summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Vermeir <thijsvermeir@gmail.com>2013-01-02 12:15:25 +0100
committerJosep Torra <n770galaxy@gmail.com>2013-03-10 12:12:37 +0100
commitb499aba1e5d849361a2a98b41e13921ed10cb39b (patch)
tree9d76d461bfea4b69e446243ce43f6f163a414080
parentbfbd34163606c50676fb1b0ac053e92fc20ff552 (diff)
downloadgstreamer-plugins-base-b499aba1e5d849361a2a98b41e13921ed10cb39b.tar.gz
videodecoder: allow parse function to not use all data on adapter
Conflicts: gst-libs/gst/video/gstvideodecoder.c
-rw-r--r--gst-libs/gst/video/gstvideodecoder.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c
index 0ce27fac0..880a52306 100644
--- a/gst-libs/gst/video/gstvideodecoder.c
+++ b/gst-libs/gst/video/gstvideodecoder.c
@@ -438,6 +438,9 @@ static GstFlowReturn gst_video_decoder_flush_parse (GstVideoDecoder * dec,
static void gst_video_decoder_clear_queues (GstVideoDecoder * dec);
+static GstFlowReturn gst_video_decoder_parse_available (GstVideoDecoder * dec,
+ gboolean at_eos);
+
GST_BOILERPLATE (GstVideoDecoder, gst_video_decoder,
GstElement, GST_TYPE_ELEMENT);
@@ -818,7 +821,33 @@ gst_video_decoder_flush (GstVideoDecoder * dec, gboolean hard)
}
static GstFlowReturn
-gst_video_decoder_handle_eos (GstVideoDecoder * dec)
+gst_video_decoder_parse_available (GstVideoDecoder * dec, gboolean at_eos)
+{
+ GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
+ GstVideoDecoderPrivate *priv = dec->priv;
+ GstFlowReturn ret = GST_FLOW_OK;
+ gsize start_size, available;
+
+ available = gst_adapter_available (priv->input_adapter);
+ start_size = 0;
+
+ while (ret == GST_FLOW_OK && available && start_size != available) {
+ /* current frame may have been parsed and handled,
+ * so we need to set up a new one when asking subclass to parse */
+ if (priv->current_frame == NULL)
+ priv->current_frame = gst_video_decoder_new_frame (dec);
+
+ start_size = available;
+ ret = decoder_class->parse (dec, priv->current_frame,
+ priv->input_adapter, at_eos);
+ available = gst_adapter_available (priv->input_adapter);
+ }
+
+ return ret;
+}
+
+static GstFlowReturn
+gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
{
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
GstVideoDecoderPrivate *priv = dec->priv;
@@ -830,23 +859,17 @@ gst_video_decoder_handle_eos (GstVideoDecoder * dec)
/* Forward mode, if unpacketized, give the child class
* a final chance to flush out packets */
if (!priv->packetized) {
- while (ret == GST_FLOW_OK && gst_adapter_available (priv->input_adapter)) {
- if (priv->current_frame == NULL)
- priv->current_frame = gst_video_decoder_new_frame (dec);
-
- ret = decoder_class->parse (dec, priv->current_frame,
- priv->input_adapter, TRUE);
- }
+ ret = gst_video_decoder_parse_available (dec, TRUE);
}
} else {
/* Reverse playback mode */
ret = gst_video_decoder_flush_parse (dec, TRUE);
}
- ret = GST_FLOW_OK;
-
- if (decoder_class->finish)
- ret = decoder_class->finish (dec);
+ if (at_eos) {
+ if (decoder_class->finish)
+ ret = decoder_class->finish (dec);
+ }
GST_VIDEO_DECODER_STREAM_UNLOCK (dec);
@@ -866,7 +889,7 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
{
GstFlowReturn flow_ret = GST_FLOW_OK;
- flow_ret = gst_video_decoder_handle_eos (decoder);
+ flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
handled = (flow_ret == GST_VIDEO_DECODER_FLOW_DROPPED);
break;
@@ -1631,24 +1654,11 @@ gst_video_decoder_chain_forward (GstVideoDecoder * decoder,
}
priv->current_frame = NULL;
} else {
-
gst_adapter_push (priv->input_adapter, buf);
- if (G_UNLIKELY (!gst_adapter_available (priv->input_adapter)))
- goto beach;
-
- do {
- /* current frame may have been parsed and handled,
- * so we need to set up a new one when asking subclass to parse */
- if (priv->current_frame == NULL)
- priv->current_frame = gst_video_decoder_new_frame (decoder);
-
- ret = klass->parse (decoder, priv->current_frame,
- priv->input_adapter, at_eos);
- } while (ret == GST_FLOW_OK && gst_adapter_available (priv->input_adapter));
+ ret = gst_video_decoder_parse_available (decoder, at_eos);
}
-beach:
if (ret == GST_VIDEO_DECODER_FLOW_NEED_DATA)
return GST_FLOW_OK;