mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
qtdemux: drain the adapter before pushing EOS
In a fragmented scenario, qtdemux is operating in push mode and it gets a fragmented buffer. While processing its data downstream gets unlinked (or a input-selector changes its active pad and returns not-linked). Qtdemux stops processing this fragment and returns not-linked upstream, leaving the remaining data in its adapter. When it gets an EOS it should make sure that all the data it had received is pushed before pushing EOS.
This commit is contained in:
parent
9dd6e22ba9
commit
a82f3418fd
1 changed files with 25 additions and 9 deletions
|
@ -440,6 +440,8 @@ static gboolean gst_qtdemux_handle_sink_event (GstPad * pad, GstObject * parent,
|
||||||
static gboolean gst_qtdemux_setcaps (GstQTDemux * qtdemux, GstCaps * caps);
|
static gboolean gst_qtdemux_setcaps (GstQTDemux * qtdemux, GstCaps * caps);
|
||||||
static gboolean gst_qtdemux_configure_stream (GstQTDemux * qtdemux,
|
static gboolean gst_qtdemux_configure_stream (GstQTDemux * qtdemux,
|
||||||
QtDemuxStream * stream);
|
QtDemuxStream * stream);
|
||||||
|
static GstFlowReturn gst_qtdemux_process_adapter (GstQTDemux * demux,
|
||||||
|
gboolean force);
|
||||||
|
|
||||||
static gboolean qtdemux_parse_moov (GstQTDemux * qtdemux,
|
static gboolean qtdemux_parse_moov (GstQTDemux * qtdemux,
|
||||||
const guint8 * buffer, guint length);
|
const guint8 * buffer, guint length);
|
||||||
|
@ -1887,7 +1889,7 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstObject * parent,
|
||||||
GstEvent * event)
|
GstEvent * event)
|
||||||
{
|
{
|
||||||
GstQTDemux *demux = GST_QTDEMUX (parent);
|
GstQTDemux *demux = GST_QTDEMUX (parent);
|
||||||
gboolean res;
|
gboolean res = TRUE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event));
|
GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
|
@ -2036,6 +2038,13 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstObject * parent,
|
||||||
}
|
}
|
||||||
if (!has_valid_stream)
|
if (!has_valid_stream)
|
||||||
gst_qtdemux_post_no_playable_stream_error (demux);
|
gst_qtdemux_post_no_playable_stream_error (demux);
|
||||||
|
else {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Data still available after EOS: %u",
|
||||||
|
(guint) gst_adapter_available (demux->adapter));
|
||||||
|
if (gst_qtdemux_process_adapter (demux, TRUE) != GST_FLOW_OK) {
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_CAPS:{
|
case GST_EVENT_CAPS:{
|
||||||
|
@ -2052,7 +2061,7 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstObject * parent,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = gst_pad_event_default (demux->sinkpad, parent, event);
|
res = gst_pad_event_default (demux->sinkpad, parent, event) & res;
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
return res;
|
return res;
|
||||||
|
@ -4593,22 +4602,29 @@ static GstFlowReturn
|
||||||
gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
|
gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
|
||||||
{
|
{
|
||||||
GstQTDemux *demux;
|
GstQTDemux *demux;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
|
||||||
demux = GST_QTDEMUX (parent);
|
|
||||||
|
|
||||||
|
demux = GST_QTDEMUX (parent);
|
||||||
gst_adapter_push (demux->adapter, inbuf);
|
gst_adapter_push (demux->adapter, inbuf);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"pushing in inbuf %p, neededbytes:%u, available:%" G_GSIZE_FORMAT, inbuf,
|
||||||
|
demux->neededbytes, gst_adapter_available (demux->adapter));
|
||||||
|
|
||||||
|
return gst_qtdemux_process_adapter (demux, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
|
||||||
|
{
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
/* we never really mean to buffer that much */
|
/* we never really mean to buffer that much */
|
||||||
if (demux->neededbytes == -1) {
|
if (demux->neededbytes == -1) {
|
||||||
goto eos;
|
goto eos;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
|
||||||
"pushing in inbuf %p, neededbytes:%u, available:%" G_GSIZE_FORMAT, inbuf,
|
|
||||||
demux->neededbytes, gst_adapter_available (demux->adapter));
|
|
||||||
|
|
||||||
while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) &&
|
while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) &&
|
||||||
(ret == GST_FLOW_OK)) {
|
(ret == GST_FLOW_OK || (ret == GST_FLOW_NOT_LINKED && force))) {
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"state:%d , demux->neededbytes:%d, demux->offset:%" G_GUINT64_FORMAT,
|
"state:%d , demux->neededbytes:%d, demux->offset:%" G_GUINT64_FORMAT,
|
||||||
|
|
Loading…
Reference in a new issue