From d189beda4d130515d88920de4f1d240c3aca0435 Mon Sep 17 00:00:00 2001 From: Thijs Vermeir Date: Wed, 2 Jan 2013 12:15:25 +0100 Subject: [PATCH] videodecoder: allow parse function to not use all data on adapter --- gst-libs/gst/video/gstvideodecoder.c | 51 +++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index 0383682..a9be47e 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -453,6 +453,8 @@ static gboolean gst_video_decoder_decide_allocation_default (GstVideoDecoder * static gboolean gst_video_decoder_propose_allocation_default (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_video_decoder_negotiate_default (GstVideoDecoder * decoder); +static GstFlowReturn gst_video_decoder_parse_available (GstVideoDecoder * dec, + gboolean at_eos); /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init * method to get to the padtemplates */ @@ -899,6 +901,32 @@ gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event) } static GstFlowReturn +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); @@ -911,13 +939,7 @@ gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos) /* 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 */ @@ -1699,24 +1721,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; -- 2.7.4