mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
gst/qtdemux/qtdemux.*: Make push-based work if mdat atom is before moov atom.
Original commit message from CVS: * gst/qtdemux/qtdemux.c: (gst_qtdemux_init), (gst_qtdemux_handle_src_query), (gst_qtdemux_change_state), (next_entry_size), (gst_qtdemux_chain): * gst/qtdemux/qtdemux.h: Make push-based work if mdat atom is before moov atom. Don't answer duration query. This should be transformed into replying FALSE to seek events.
This commit is contained in:
parent
6cca025c97
commit
6e172e01f0
3 changed files with 68 additions and 17 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2006-02-14 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* gst/qtdemux/qtdemux.c: (gst_qtdemux_init),
|
||||||
|
(gst_qtdemux_handle_src_query), (gst_qtdemux_change_state),
|
||||||
|
(next_entry_size), (gst_qtdemux_chain):
|
||||||
|
* gst/qtdemux/qtdemux.h:
|
||||||
|
Make push-based work if mdat atom is before moov atom.
|
||||||
|
Don't answer duration query. This should be transformed into replying
|
||||||
|
FALSE to seek events.
|
||||||
|
|
||||||
2006-02-14 Tim-Philipp Müller <tim at centricular dot net>
|
2006-02-14 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* ext/libmms/gstmms.c: (gst_mms_class_init), (gst_mms_create),
|
* ext/libmms/gstmms.c: (gst_mms_class_init), (gst_mms_create),
|
||||||
|
|
|
@ -104,6 +104,7 @@ enum QtDemuxState
|
||||||
QTDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */
|
QTDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */
|
||||||
QTDEMUX_STATE_HEADER, /* Parsing the header */
|
QTDEMUX_STATE_HEADER, /* Parsing the header */
|
||||||
QTDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */
|
QTDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */
|
||||||
|
QTDEMUX_STATE_BUFFER_MDAT, /* Buffering the mdat atom */
|
||||||
};
|
};
|
||||||
|
|
||||||
static GNode *qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc);
|
static GNode *qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc);
|
||||||
|
@ -242,6 +243,9 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
|
||||||
qtdemux->neededbytes = 16;
|
qtdemux->neededbytes = 16;
|
||||||
qtdemux->todrop = 0;
|
qtdemux->todrop = 0;
|
||||||
qtdemux->adapter = gst_adapter_new ();
|
qtdemux->adapter = gst_adapter_new ();
|
||||||
|
qtdemux->offset = 0;
|
||||||
|
qtdemux->mdatoffset = GST_CLOCK_TIME_NONE;
|
||||||
|
qtdemux->mdatbuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -324,7 +328,8 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_QUERY_DURATION:
|
case GST_QUERY_DURATION:
|
||||||
if (qtdemux->duration != 0 && qtdemux->timescale != 0) {
|
if (qtdemux->pullbased && qtdemux->duration != 0
|
||||||
|
&& qtdemux->timescale != 0) {
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
|
|
||||||
duration = gst_util_uint64_scale_int (qtdemux->duration,
|
duration = gst_util_uint64_scale_int (qtdemux->duration,
|
||||||
|
@ -498,6 +503,10 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
|
||||||
qtdemux->todrop = 0;
|
qtdemux->todrop = 0;
|
||||||
qtdemux->pullbased = FALSE;
|
qtdemux->pullbased = FALSE;
|
||||||
qtdemux->offset = 0;
|
qtdemux->offset = 0;
|
||||||
|
qtdemux->mdatoffset = GST_CLOCK_TIME_NONE;
|
||||||
|
if (qtdemux->mdatbuffer)
|
||||||
|
gst_buffer_unref (qtdemux->mdatbuffer);
|
||||||
|
qtdemux->mdatbuffer = NULL;
|
||||||
gst_adapter_clear (qtdemux->adapter);
|
gst_adapter_clear (qtdemux->adapter);
|
||||||
for (n = 0; n < qtdemux->n_streams; n++) {
|
for (n = 0; n < qtdemux->n_streams; n++) {
|
||||||
gst_element_remove_pad (element, qtdemux->streams[n]->pad);
|
gst_element_remove_pad (element, qtdemux->streams[n]->pad);
|
||||||
|
@ -775,8 +784,9 @@ next_entry_size (GstQTDemux * demux)
|
||||||
stream->samples[stream->sample_index].size,
|
stream->samples[stream->sample_index].size,
|
||||||
stream->samples[stream->sample_index].chunk);
|
stream->samples[stream->sample_index].chunk);
|
||||||
|
|
||||||
if ((smalloffs == -1)
|
if (((smalloffs == -1)
|
||||||
|| (stream->samples[stream->sample_index].offset < smalloffs)) {
|
|| (stream->samples[stream->sample_index].offset < smalloffs))
|
||||||
|
&& (stream->samples[stream->sample_index].size)) {
|
||||||
smallidx = i;
|
smallidx = i;
|
||||||
smalloffs = stream->samples[stream->sample_index].offset;
|
smalloffs = stream->samples[stream->sample_index].offset;
|
||||||
}
|
}
|
||||||
|
@ -812,7 +822,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
inbuf, demux->neededbytes, gst_adapter_available (demux->adapter));
|
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)) {
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"state:%d , demux->neededbytes:%d, demux->offset:%lld", demux->state,
|
"state:%d , demux->neededbytes:%d, demux->offset:%lld", demux->state,
|
||||||
|
@ -832,16 +842,14 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
"Peeking found [%" GST_FOURCC_FORMAT "] size:%ld",
|
"Peeking found [%" GST_FOURCC_FORMAT "] size:%ld",
|
||||||
GST_FOURCC_ARGS (fourcc), size);
|
GST_FOURCC_ARGS (fourcc), size);
|
||||||
if ((fourcc == GST_MAKE_FOURCC ('m', 'd', 'a', 't'))) {
|
if ((fourcc == GST_MAKE_FOURCC ('m', 'd', 'a', 't'))) {
|
||||||
if (demux->n_streams <= 0) {
|
if (demux->n_streams > 0) {
|
||||||
GST_ELEMENT_ERROR (demux, STREAM, FAILED,
|
|
||||||
(NULL),
|
|
||||||
("Can't handled files with header after data in push-mode!"));
|
|
||||||
ret = GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
demux->state = QTDEMUX_STATE_MOVIE;
|
demux->state = QTDEMUX_STATE_MOVIE;
|
||||||
demux->offset += 24;
|
|
||||||
gst_adapter_flush (demux->adapter, 24);
|
|
||||||
demux->neededbytes = next_entry_size (demux);
|
demux->neededbytes = next_entry_size (demux);
|
||||||
|
} else {
|
||||||
|
demux->state = QTDEMUX_STATE_BUFFER_MDAT;
|
||||||
|
demux->neededbytes = size;
|
||||||
|
demux->mdatoffset = demux->offset;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
demux->neededbytes = size;
|
demux->neededbytes = size;
|
||||||
demux->state = QTDEMUX_STATE_HEADER;
|
demux->state = QTDEMUX_STATE_HEADER;
|
||||||
|
@ -862,7 +870,6 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
if (fourcc == GST_MAKE_FOURCC ('m', 'o', 'o', 'v')) {
|
if (fourcc == GST_MAKE_FOURCC ('m', 'o', 'o', 'v')) {
|
||||||
GST_DEBUG_OBJECT (demux, "Parsing [moov]");
|
GST_DEBUG_OBJECT (demux, "Parsing [moov]");
|
||||||
|
|
||||||
demux->offset += demux->neededbytes;
|
|
||||||
qtdemux_parse_moov (demux, data, demux->neededbytes);
|
qtdemux_parse_moov (demux, data, demux->neededbytes);
|
||||||
qtdemux_node_dump (demux, demux->moov_node);
|
qtdemux_node_dump (demux, demux->moov_node);
|
||||||
qtdemux_parse_tree (demux);
|
qtdemux_parse_tree (demux);
|
||||||
|
@ -870,14 +877,28 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
g_node_destroy (demux->moov_node);
|
g_node_destroy (demux->moov_node);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
demux->moov_node = NULL;
|
demux->moov_node = NULL;
|
||||||
|
|
||||||
demux->neededbytes = 16;
|
|
||||||
demux->state = QTDEMUX_STATE_INITIAL;
|
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (demux,
|
GST_WARNING_OBJECT (demux,
|
||||||
"Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT,
|
"Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (fourcc));
|
GST_FOURCC_ARGS (fourcc));
|
||||||
/* Let's jump that one and go back to initial state */
|
/* Let's jump that one and go back to initial state */
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "Finished parsing the header");
|
||||||
|
if (demux->mdatbuffer && demux->n_streams) {
|
||||||
|
/* the mdat was before the header */
|
||||||
|
GST_DEBUG_OBJECT (demux, "We have n_streams:%d and mdatbuffer:%p",
|
||||||
|
demux->n_streams, demux->mdatbuffer);
|
||||||
|
gst_adapter_clear (demux->adapter);
|
||||||
|
GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,
|
||||||
|
GST_FOURCC_ARGS (GST_READ_UINT32_BE (demux->mdatbuffer)));
|
||||||
|
gst_adapter_push (demux->adapter, demux->mdatbuffer);
|
||||||
|
demux->mdatbuffer = NULL;
|
||||||
|
demux->offset = demux->mdatoffset;
|
||||||
|
demux->neededbytes = next_entry_size (demux);
|
||||||
|
demux->state = QTDEMUX_STATE_MOVIE;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Carrying on normally");
|
||||||
demux->offset += demux->neededbytes;
|
demux->offset += demux->neededbytes;
|
||||||
demux->neededbytes = 16;
|
demux->neededbytes = 16;
|
||||||
demux->state = QTDEMUX_STATE_INITIAL;
|
demux->state = QTDEMUX_STATE_INITIAL;
|
||||||
|
@ -885,6 +906,23 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QTDEMUX_STATE_BUFFER_MDAT:{
|
||||||
|
GST_DEBUG_OBJECT (demux, "Got our buffer at offset %lld",
|
||||||
|
demux->mdatoffset);
|
||||||
|
if (demux->mdatbuffer)
|
||||||
|
gst_buffer_unref (demux->mdatbuffer);
|
||||||
|
demux->mdatbuffer = gst_buffer_new ();
|
||||||
|
gst_buffer_set_data (demux->mdatbuffer,
|
||||||
|
gst_adapter_take (demux->adapter, demux->neededbytes),
|
||||||
|
demux->neededbytes);
|
||||||
|
GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,
|
||||||
|
GST_FOURCC_ARGS (GST_READ_UINT32_BE (demux->mdatbuffer)));
|
||||||
|
demux->offset += demux->neededbytes;
|
||||||
|
demux->neededbytes = 16;
|
||||||
|
demux->state = QTDEMUX_STATE_INITIAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case QTDEMUX_STATE_MOVIE:{
|
case QTDEMUX_STATE_MOVIE:{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
|
@ -68,9 +68,12 @@ struct _GstQTDemux {
|
||||||
guint neededbytes;
|
guint neededbytes;
|
||||||
guint todrop;
|
guint todrop;
|
||||||
GstAdapter *adapter;
|
GstAdapter *adapter;
|
||||||
|
GstBuffer *mdatbuffer;
|
||||||
|
|
||||||
/* offset of the media data (i.e.: Size of header) */
|
/* offset of the media data (i.e.: Size of header) */
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
|
/* offset of the mdat atom */
|
||||||
|
guint64 mdatoffset;
|
||||||
|
|
||||||
GstTagList *tag_list;
|
GstTagList *tag_list;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue