gst/qtdemux/qtdemux.c: In push mode, error out if we get EOS before we've created any srcpads.

Original commit message from CVS:
* gst/qtdemux/qtdemux.c:
In push mode, error out if we get EOS before we've created any srcpads.
Handle (in pull mode) some files that have a truncated moov atom where
the final sub-atom is a 'free' atom and the contents of that are not
present in the file.
This commit is contained in:
Michael Smith 2009-01-08 18:17:13 +00:00
parent 7958cf82ab
commit 1d32ad886e
2 changed files with 47 additions and 2 deletions

View file

@ -1,3 +1,11 @@
2009-01-08 Michael Smith <msmith@songbirdnest.com>
* gst/qtdemux/qtdemux.c:
In push mode, error out if we get EOS before we've created any srcpads.
Handle (in pull mode) some files that have a truncated moov atom where
the final sub-atom is a 'free' atom and the contents of that are not
present in the file.
2009-01-08 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
* gst/matroska/matroska-demux.c: (gst_matroska_demux_video_caps):

View file

@ -985,6 +985,15 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
gst_event_unref (event);
res = TRUE;
break;
case GST_EVENT_EOS:
/* If we are in push mode, and get an EOS before we've seen any streams,
* then error out - we have nowhere to send the EOS */
if (!demux->pullbased && demux->n_streams == 0) {
GST_ELEMENT_ERROR (demux, STREAM, DECODE,
(_("This file contains no playable streams.")),
("no known streams found"));
}
/* Fall through */
default:
res = gst_pad_event_default (demux->sinkpad, event);
break;
@ -1127,11 +1136,39 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &moov);
if (ret != GST_FLOW_OK)
goto beach;
if (length != GST_BUFFER_SIZE (moov)) {
/* Some files have a 'moov' atom at the end of the file which contains
* a terminal 'free' atom where the body of the atom is missing.
* Check for, and permit, this special case.
*/
if (GST_BUFFER_SIZE (moov) >= 8) {
guint8 *final_data = GST_BUFFER_DATA (moov) +
(GST_BUFFER_SIZE (moov) - 8);
guint32 final_length = QT_UINT32 (final_data);
guint32 final_fourcc = QT_FOURCC (final_data + 4);
if (final_fourcc == FOURCC_free &&
GST_BUFFER_SIZE (moov) + final_length - 8 == length) {
/* Ok, we've found that special case. Allocate a new buffer with
* that free atom actually present. */
GstBuffer *newmoov = gst_buffer_new_and_alloc (length);
gst_buffer_copy_metadata (newmoov, moov,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
GST_BUFFER_COPY_CAPS);
memcpy (GST_BUFFER_DATA (newmoov), GST_BUFFER_DATA (moov),
GST_BUFFER_SIZE (moov));
memset (GST_BUFFER_DATA (newmoov) + GST_BUFFER_SIZE (moov), 0,
final_length - 8);
gst_buffer_unref (moov);
moov = newmoov;
}
}
}
if (length != GST_BUFFER_SIZE (moov)) {
GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
(_("This file is incomplete and cannot be played.")),
("We got less than expected (received %u, wanted %u)",
GST_BUFFER_SIZE (moov), (guint) length));
("We got less than expected (received %u, wanted %u, offset %u)",
GST_BUFFER_SIZE (moov), (guint) length, cur_offset));
ret = GST_FLOW_ERROR;
goto beach;
}