summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-02-16 12:19:20 +0100
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-02-16 12:35:53 +0100
commit439884d628fa80e710698e9bb36f063c503b9e79 (patch)
tree8e6660214f4acba923dc5af14f1c970c7a1a9349
parent5b4dc0252323a5f77470531a814d0d2cceac0056 (diff)
audiodecoder: add some properties to tweak baseclass behaviour
... so subclass can also rely upon never being bothered with some NULL buffer it can't do any interesting with, or with any data before it received any format configuration (and setup properly).
-rw-r--r--gst-libs/gst/audio/gstaudiodecoder.c124
-rw-r--r--gst-libs/gst/audio/gstaudiodecoder.h10
2 files changed, 134 insertions, 0 deletions
diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c
index 1a812788f..705197cc6 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.c
+++ b/gst-libs/gst/audio/gstaudiodecoder.c
@@ -181,6 +181,8 @@ enum
181#define DEFAULT_LATENCY 0 181#define DEFAULT_LATENCY 0
182#define DEFAULT_TOLERANCE 0 182#define DEFAULT_TOLERANCE 0
183#define DEFAULT_PLC FALSE 183#define DEFAULT_PLC FALSE
184#define DEFAULT_DRAINABLE TRUE
185#define DEFAULT_NEEDS_FORMAT FALSE
184 186
185typedef struct _GstAudioDecoderContext 187typedef struct _GstAudioDecoderContext
186{ 188{
@@ -262,6 +264,8 @@ struct _GstAudioDecoderPrivate
262 GstClockTime latency; 264 GstClockTime latency;
263 GstClockTime tolerance; 265 GstClockTime tolerance;
264 gboolean plc; 266 gboolean plc;
267 gboolean drainable;
268 gboolean needs_format;
265 269
266 /* pending serialized sink events, will be sent from finish_frame() */ 270 /* pending serialized sink events, will be sent from finish_frame() */
267 GList *pending_events; 271 GList *pending_events;
@@ -395,6 +399,8 @@ gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass)
395 dec->priv->latency = DEFAULT_LATENCY; 399 dec->priv->latency = DEFAULT_LATENCY;
396 dec->priv->tolerance = DEFAULT_TOLERANCE; 400 dec->priv->tolerance = DEFAULT_TOLERANCE;
397 dec->priv->plc = DEFAULT_PLC; 401 dec->priv->plc = DEFAULT_PLC;
402 dec->priv->drainable = DEFAULT_DRAINABLE;
403 dec->priv->needs_format = DEFAULT_NEEDS_FORMAT;
398 404
399 /* init state */ 405 /* init state */
400 gst_audio_decoder_reset (dec, TRUE); 406 gst_audio_decoder_reset (dec, TRUE);
@@ -1024,6 +1030,10 @@ gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
1024 } else { 1030 } else {
1025 if (!force) 1031 if (!force)
1026 break; 1032 break;
1033 if (!priv->drainable) {
1034 priv->drained = TRUE;
1035 break;
1036 }
1027 buffer = NULL; 1037 buffer = NULL;
1028 } 1038 }
1029 1039
@@ -1344,6 +1354,9 @@ gst_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
1344 1354
1345 dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad)); 1355 dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
1346 1356
1357 if (G_UNLIKELY (!GST_PAD_CAPS (pad) && dec->priv->needs_format))
1358 goto not_negotiated;
1359
1347 GST_LOG_OBJECT (dec, 1360 GST_LOG_OBJECT (dec,
1348 "received buffer of size %d with ts %" GST_TIME_FORMAT 1361 "received buffer of size %d with ts %" GST_TIME_FORMAT
1349 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), 1362 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
@@ -1381,6 +1394,15 @@ gst_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
1381 GST_AUDIO_DECODER_STREAM_UNLOCK (dec); 1394 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1382 1395
1383 return ret; 1396 return ret;
1397
1398 /* ERRORS */
1399not_negotiated:
1400 {
1401 GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
1402 ("decoder not initialized"));
1403 gst_buffer_unref (buffer);
1404 return GST_FLOW_NOT_NEGOTIATED;
1405 }
1384} 1406}
1385 1407
1386/* perform upstream byte <-> time conversion (duration, seeking) 1408/* perform upstream byte <-> time conversion (duration, seeking)
@@ -2461,3 +2483,105 @@ gst_audio_decoder_get_tolerance (GstAudioDecoder * dec)
2461 2483
2462 return result; 2484 return result;
2463} 2485}
2486
2487/**
2488 * gst_audio_decoder_set_drainable:
2489 * @enc: a #GstAudioDecoder
2490 * @enabled: new state
2491 *
2492 * Configures decoder drain handling. If drainable, subclass might
2493 * be handed a NULL buffer to have it return any leftover decoded data.
2494 * Otherwise, it is not considered so capable and will only ever be passed
2495 * real data.
2496 *
2497 * MT safe.
2498 *
2499 * Since: 0.10.36
2500 */
2501void
2502gst_audio_decoder_set_drainable (GstAudioDecoder * dec, gboolean enabled)
2503{
2504 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2505
2506 GST_OBJECT_LOCK (dec);
2507 dec->priv->drainable = enabled;
2508 GST_OBJECT_UNLOCK (dec);
2509}
2510
2511/**
2512 * gst_audio_decoder_get_drainable:
2513 * @enc: a #GstAudioDecoder
2514 *
2515 * Queries decoder drain handling.
2516 *
2517 * Returns: TRUE if drainable handling is enabled.
2518 *
2519 * MT safe.
2520 *
2521 * Since: 0.10.36
2522 */
2523gboolean
2524gst_audio_decoder_get_drainable (GstAudioDecoder * dec)
2525{
2526 gboolean result;
2527
2528 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2529
2530 GST_OBJECT_LOCK (dec);
2531 result = dec->priv->drainable;
2532 GST_OBJECT_UNLOCK (dec);
2533
2534 return result;
2535}
2536
2537/**
2538 * gst_audio_decoder_set_needs_format:
2539 * @enc: a #GstAudioDecoder
2540 * @enabled: new state
2541 *
2542 * Configures decoder format needs. If enabled, subclass needs to be
2543 * negotiated with format caps before it can process any data. It will then
2544 * never be handed any data before it has been configured.
2545 * Otherwise, it might be handed data without having been configured and
2546 * is then expected being able to do so either by default
2547 * or based on the input data.
2548 *
2549 * MT safe.
2550 *
2551 * Since: 0.10.36
2552 */
2553void
2554gst_audio_decoder_set_needs_format (GstAudioDecoder * dec, gboolean enabled)
2555{
2556 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2557
2558 GST_OBJECT_LOCK (dec);
2559 dec->priv->needs_format = enabled;
2560 GST_OBJECT_UNLOCK (dec);
2561}
2562
2563/**
2564 * gst_audio_decoder_get_needs_format:
2565 * @enc: a #GstAudioDecoder
2566 *
2567 * Queries decoder required format handling.
2568 *
2569 * Returns: TRUE if required format handling is enabled.
2570 *
2571 * MT safe.
2572 *
2573 * Since: 0.10.36
2574 */
2575gboolean
2576gst_audio_decoder_get_needs_format (GstAudioDecoder * dec)
2577{
2578 gboolean result;
2579
2580 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2581
2582 GST_OBJECT_LOCK (dec);
2583 result = dec->priv->needs_format;
2584 GST_OBJECT_UNLOCK (dec);
2585
2586 return result;
2587}
diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h
index a6ae61803..ba4fff348 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.h
+++ b/gst-libs/gst/audio/gstaudiodecoder.h
@@ -293,6 +293,16 @@ void gst_audio_decoder_set_tolerance (GstAudioDecoder * dec,
293 293
294gint64 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec); 294gint64 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec);
295 295
296void gst_audio_decoder_set_drainable (GstAudioDecoder * dec,
297 gboolean enabled);
298
299gboolean gst_audio_decoder_get_drainable (GstAudioDecoder * dec);
300
301void gst_audio_decoder_set_needs_format (GstAudioDecoder * dec,
302 gboolean enabled);
303
304gboolean gst_audio_decoder_get_needs_format (GstAudioDecoder * dec);
305
296G_END_DECLS 306G_END_DECLS
297 307
298#endif /* _GST_AUDIO_DECODER_H_ */ 308#endif /* _GST_AUDIO_DECODER_H_ */