mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
Separate the movi processing loop from the index/entry parsing loop
Original commit message from CVS: Separate the movi processing loop from the index/entry parsing loop Detect when the index starts from 0 or from the movi chunck offset
This commit is contained in:
parent
8b72069ccb
commit
d9b0cf77a2
2 changed files with 56 additions and 15 deletions
|
@ -153,6 +153,10 @@ static void gst_avi_demux_init (GstAviDemux *avi_demux);
|
||||||
|
|
||||||
static void gst_avi_demux_loop (GstElement *element);
|
static void gst_avi_demux_loop (GstElement *element);
|
||||||
|
|
||||||
|
static gboolean gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
||||||
|
guint32 desired_tag,
|
||||||
|
gint rec_depth, guint32 *chunksize);
|
||||||
|
|
||||||
static gboolean gst_avi_demux_send_event (GstElement *element, GstEvent *event);
|
static gboolean gst_avi_demux_send_event (GstElement *element, GstEvent *event);
|
||||||
|
|
||||||
static gboolean gst_avi_demux_handle_src_event (GstPad *pad, GstEvent *event);
|
static gboolean gst_avi_demux_handle_src_event (GstPad *pad, GstEvent *event);
|
||||||
|
@ -231,6 +235,7 @@ gst_avi_demux_init (GstAviDemux *avi_demux)
|
||||||
avi_demux->index_entries = NULL;
|
avi_demux->index_entries = NULL;
|
||||||
avi_demux->index_size = 0;
|
avi_demux->index_size = 0;
|
||||||
avi_demux->seek_pending = 0;
|
avi_demux->seek_pending = 0;
|
||||||
|
avi_demux->restart = FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,6 +686,14 @@ gst_avi_demux_parse_index (GstAviDemux *avi_demux,
|
||||||
target->size = entry[i].size;
|
target->size = entry[i].size;
|
||||||
target->offset = entry[i].offset;
|
target->offset = entry[i].offset;
|
||||||
|
|
||||||
|
/* figure out if the index is 0 based or relative to the MOVI start */
|
||||||
|
if (i == 0) {
|
||||||
|
if (target->offset < filepos)
|
||||||
|
avi_demux->index_offset = filepos;
|
||||||
|
else
|
||||||
|
avi_demux->index_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
target->bytes_before = stream->total_bytes;
|
target->bytes_before = stream->total_bytes;
|
||||||
target->frames_before = stream->total_frames;
|
target->frames_before = stream->total_frames;
|
||||||
|
|
||||||
|
@ -714,7 +727,6 @@ gst_avi_demux_parse_index (GstAviDemux *avi_demux,
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
avi_demux->index_offset = filepos;
|
|
||||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "index offset at %08lx", filepos);
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "index offset at %08lx", filepos);
|
||||||
|
|
||||||
if (!gst_bytestream_seek (avi_demux->bs, filepos, GST_SEEK_METHOD_SET)) {
|
if (!gst_bytestream_seek (avi_demux->bs, filepos, GST_SEEK_METHOD_SET)) {
|
||||||
|
@ -1060,14 +1072,6 @@ gst_avi_demux_read_chunk (GstAviDemux *avi_demux, guint32 *id, guint32 *size)
|
||||||
GstByteStream *bs = avi_demux->bs;
|
GstByteStream *bs = avi_demux->bs;
|
||||||
guint32 got_bytes;
|
guint32 got_bytes;
|
||||||
|
|
||||||
if (avi_demux->seek_pending) {
|
|
||||||
GST_DEBUG (0, "avidemux: seek pending to %lld %08llx", avi_demux->seek_offset, avi_demux->seek_offset);
|
|
||||||
if (!gst_bytestream_seek (avi_demux->bs, avi_demux->seek_offset, GST_SEEK_METHOD_SET)) {
|
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "avidemux: could not seek");
|
|
||||||
}
|
|
||||||
avi_demux->seek_pending = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&chunk, sizeof (gst_riff_chunk));
|
got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&chunk, sizeof (gst_riff_chunk));
|
||||||
if (got_bytes == sizeof (gst_riff_chunk)) {
|
if (got_bytes == sizeof (gst_riff_chunk)) {
|
||||||
|
@ -1083,6 +1087,36 @@ gst_avi_demux_read_chunk (GstAviDemux *avi_demux, guint32 *id, guint32 *size)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_avi_demux_process_movi (GstAviDemux *avi_demux, gint rec_depth, guint64 *filepos)
|
||||||
|
{
|
||||||
|
guint32 subchunksize = 0;
|
||||||
|
|
||||||
|
while (!avi_demux->restart) { /* while not showed all: */
|
||||||
|
if (avi_demux->seek_pending) {
|
||||||
|
GST_DEBUG (0, "avidemux: seek pending to %lld %08llx", avi_demux->seek_offset, avi_demux->seek_offset);
|
||||||
|
if (!gst_bytestream_seek (avi_demux->bs, avi_demux->seek_offset, GST_SEEK_METHOD_SET)) {
|
||||||
|
GST_INFO (GST_CAT_PLUGIN_INFO, "avidemux: could not seek");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*filepos = avi_demux->seek_offset;
|
||||||
|
}
|
||||||
|
avi_demux->seek_pending = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO (GST_CAT_PLUGIN_INFO, "process chunk filepos %08llx", *filepos);
|
||||||
|
/* recurse for subchunks of RIFF and LIST chunks: */
|
||||||
|
if (!gst_avi_demux_process_chunk (avi_demux, filepos, 0,
|
||||||
|
rec_depth + 1, &subchunksize)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* we are running in an infinite loop, we need to _yield
|
||||||
|
* from time to time */
|
||||||
|
gst_element_yield (GST_ELEMENT (avi_demux));
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
||||||
guint32 desired_tag,
|
guint32 desired_tag,
|
||||||
|
@ -1133,7 +1167,9 @@ gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
||||||
}
|
}
|
||||||
if (avi_demux->avih.bufsize)
|
if (avi_demux->avih.bufsize)
|
||||||
gst_bytestream_size_hint (avi_demux->bs, avi_demux->avih.bufsize);
|
gst_bytestream_size_hint (avi_demux->bs, avi_demux->avih.bufsize);
|
||||||
break;
|
|
||||||
|
gst_avi_demux_process_movi (avi_demux, rec_depth, filepos);
|
||||||
|
goto done;
|
||||||
default:
|
default:
|
||||||
/* flush the form type */
|
/* flush the form type */
|
||||||
gst_bytestream_flush_fast (bs, sizeof (guint32));
|
gst_bytestream_flush_fast (bs, sizeof (guint32));
|
||||||
|
@ -1154,6 +1190,8 @@ gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
||||||
%u %u\n", *filepos, *chunksize, datashowed);
|
%u %u\n", *filepos, *chunksize, datashowed);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (avi_demux->restart)
|
||||||
|
goto done;
|
||||||
|
|
||||||
subchunksize = ((subchunksize + 1) & ~1);
|
subchunksize = ((subchunksize + 1) & ~1);
|
||||||
|
|
||||||
|
@ -1261,9 +1299,6 @@ gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* we are running in an infinite loop, we need to _yield
|
|
||||||
* from time to time */
|
|
||||||
gst_element_yield (GST_ELEMENT (avi_demux));
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1280,11 +1315,14 @@ gst_avi_demux_loop (GstElement *element)
|
||||||
|
|
||||||
avi_demux = GST_AVI_DEMUX (element);
|
avi_demux = GST_AVI_DEMUX (element);
|
||||||
|
|
||||||
|
avi_demux->restart = FALSE;
|
||||||
|
|
||||||
/* this is basically an infinite loop */
|
/* this is basically an infinite loop */
|
||||||
if (!gst_avi_demux_process_chunk (avi_demux, &filepos, GST_RIFF_TAG_RIFF, 0, &chunksize)) {
|
if (!gst_avi_demux_process_chunk (avi_demux, &filepos, GST_RIFF_TAG_RIFF, 0, &chunksize)) {
|
||||||
gst_element_error (element, "This doesn't appear to be an AVI file");
|
gst_element_error (element, "This doesn't appear to be an AVI file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!avi_demux->restart)
|
||||||
/* if we exit the loop we are EOS */
|
/* if we exit the loop we are EOS */
|
||||||
gst_pad_event_default (avi_demux->sinkpad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_event_default (avi_demux->sinkpad, gst_event_new (GST_EVENT_EOS));
|
||||||
}
|
}
|
||||||
|
@ -1299,6 +1337,7 @@ gst_avi_demux_change_state (GstElement *element)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_PAUSED:
|
case GST_STATE_READY_TO_PAUSED:
|
||||||
avi_demux->bs = gst_bytestream_new (avi_demux->sinkpad);
|
avi_demux->bs = gst_bytestream_new (avi_demux->sinkpad);
|
||||||
|
avi_demux->last_seek = 0;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_PLAYING:
|
case GST_STATE_PAUSED_TO_PLAYING:
|
||||||
break;
|
break;
|
||||||
|
@ -1306,6 +1345,7 @@ gst_avi_demux_change_state (GstElement *element)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_READY:
|
case GST_STATE_PAUSED_TO_READY:
|
||||||
gst_bytestream_destroy (avi_demux->bs);
|
gst_bytestream_destroy (avi_demux->bs);
|
||||||
|
avi_demux->restart = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -108,6 +108,7 @@ struct _GstAviDemux {
|
||||||
gboolean seek_pending;
|
gboolean seek_pending;
|
||||||
gint64 seek_offset;
|
gint64 seek_offset;
|
||||||
guint64 last_seek;
|
guint64 last_seek;
|
||||||
|
gboolean restart;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstAviDemuxClass {
|
struct _GstAviDemuxClass {
|
||||||
|
|
Loading…
Reference in a new issue