mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 23:48:53 +00:00
videodecoder: allow parse function to not use all data on adapter
This commit is contained in:
parent
e7caef6b29
commit
d189beda4d
1 changed files with 30 additions and 21 deletions
|
@ -453,6 +453,8 @@ static gboolean gst_video_decoder_decide_allocation_default (GstVideoDecoder *
|
||||||
static gboolean gst_video_decoder_propose_allocation_default (GstVideoDecoder *
|
static gboolean gst_video_decoder_propose_allocation_default (GstVideoDecoder *
|
||||||
decoder, GstQuery * query);
|
decoder, GstQuery * query);
|
||||||
static gboolean gst_video_decoder_negotiate_default (GstVideoDecoder * decoder);
|
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
|
/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
|
||||||
* method to get to the padtemplates */
|
* method to get to the padtemplates */
|
||||||
|
@ -898,6 +900,32 @@ gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event)
|
||||||
return gst_pad_push_event (decoder->srcpad, event);
|
return gst_pad_push_event (decoder->srcpad, 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
|
static GstFlowReturn
|
||||||
gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
|
gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
|
||||||
{
|
{
|
||||||
|
@ -911,13 +939,7 @@ gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
|
||||||
/* Forward mode, if unpacketized, give the child class
|
/* Forward mode, if unpacketized, give the child class
|
||||||
* a final chance to flush out packets */
|
* a final chance to flush out packets */
|
||||||
if (!priv->packetized) {
|
if (!priv->packetized) {
|
||||||
while (ret == GST_FLOW_OK && gst_adapter_available (priv->input_adapter)) {
|
ret = gst_video_decoder_parse_available (dec, TRUE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Reverse playback mode */
|
/* Reverse playback mode */
|
||||||
|
@ -1699,24 +1721,11 @@ gst_video_decoder_chain_forward (GstVideoDecoder * decoder,
|
||||||
}
|
}
|
||||||
priv->current_frame = NULL;
|
priv->current_frame = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
gst_adapter_push (priv->input_adapter, buf);
|
gst_adapter_push (priv->input_adapter, buf);
|
||||||
|
|
||||||
if (G_UNLIKELY (!gst_adapter_available (priv->input_adapter)))
|
ret = gst_video_decoder_parse_available (decoder, at_eos);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
|
||||||
if (ret == GST_VIDEO_DECODER_FLOW_NEED_DATA)
|
if (ret == GST_VIDEO_DECODER_FLOW_NEED_DATA)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue