diff options
Diffstat (limited to 'gst')
-rw-r--r-- | gst/avi/Makefile.am | 15 | ||||
-rw-r--r-- | gst/avi/gstavidemux.c | 527 | ||||
-rw-r--r-- | gst/avi/gstavidemux.h | 14 | ||||
-rw-r--r-- | gst/avi/gstaviparse.c | 43 | ||||
-rw-r--r-- | gst/avi/riff.c | 115 | ||||
-rw-r--r-- | gst/avi/riff.h | 356 |
6 files changed, 269 insertions, 801 deletions
diff --git a/gst/avi/Makefile.am b/gst/avi/Makefile.am index da983d0d..1db049bd 100644 --- a/gst/avi/Makefile.am +++ b/gst/avi/Makefile.am @@ -2,19 +2,18 @@ plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ plugin_LTLIBRARIES = \ libgstavimux.la \ - libgstavidemux.la \ - libgstaviparse.la + libgstavidemux.la +# libgstaviparse.la # libgstaviaudiodecoder.la -libgstavidemux_la_SOURCES = gstavidemux.c +libgstavidemux_la_SOURCES = gstavidemux.c libgstavimux_la_SOURCES = gstavimux.c -libgstaviparse_la_SOURCES = gstaviparse.c riff.c +#libgstaviparse_la_SOURCES = gstaviparse.c # libgstaviaudiodecoder_la_SOURCES = gstaviaudiodecoder.c noinst_HEADERS = \ gstavimux.h \ gstavidemux.h \ - riff.h \ gstaviaudiodecoder.h #CFLAGS += -Wall -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math -DNDEBUG @@ -27,9 +26,9 @@ libgstavimux_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) libgstavimux_la_LIBADD = libgstavimux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstaviparse_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) -libgstaviparse_la_LIBADD = -libgstaviparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +#libgstaviparse_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) +#libgstaviparse_la_LIBADD = +#libgstaviparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # libgstaviaudiodecoder_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) # libgstaviaudiodecoder_la_LIBADD = diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 10fcef29..35925614 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -23,7 +23,6 @@ #include "gstavidemux.h" - /* elementfactory information */ static GstElementDetails gst_avi_demux_details = { "Avi demuxer", @@ -32,7 +31,7 @@ static GstElementDetails gst_avi_demux_details = { "Demultiplex an avi file into audio and video", VERSION, "Erik Walthinsen <omega@cse.ogi.edu>\n" - "Wim Taymans <wim.taymans@tvd.be>", + "Wim Taymans <wim.taymans@chello.be>", "(C) 1999", }; @@ -164,10 +163,6 @@ static void gst_avi_demux_init (GstAviDemux *avi_demux); 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 const GstEventMask* @@ -244,15 +239,6 @@ gst_avi_demux_init (GstAviDemux *avi_demux) gst_element_add_pad (GST_ELEMENT (avi_demux), avi_demux->sinkpad); gst_element_set_loop_function (GST_ELEMENT (avi_demux), gst_avi_demux_loop); - - avi_demux->num_streams = 0; - avi_demux->num_v_streams = 0; - avi_demux->num_a_streams = 0; - avi_demux->index_entries = NULL; - avi_demux->index_size = 0; - avi_demux->seek_pending = 0; - avi_demux->restart = FALSE; - } static GstCaps* @@ -279,10 +265,11 @@ static gboolean gst_avi_demux_avih (GstAviDemux *avi_demux) { gst_riff_avih *avih; - guint32 got_bytes; - GstByteStream *bs = avi_demux->bs; + GstByteStream *bs = avi_demux->bs; + guint32 got_bytes; + + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&avih, sizeof (gst_riff_avih)); - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&avih, sizeof (gst_riff_avih)); if (got_bytes == sizeof (gst_riff_avih)) { avi_demux->avih.us_frame = GUINT32_FROM_LE (avih->us_frame); avi_demux->avih.max_bps = GUINT32_FROM_LE (avih->max_bps); @@ -324,10 +311,11 @@ static gboolean gst_avi_demux_strh (GstAviDemux *avi_demux) { gst_riff_strh *strh; - GstByteStream *bs = avi_demux->bs; - guint32 got_bytes; + GstByteStream *bs = avi_demux->bs; + guint32 got_bytes; + + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&strh, sizeof (gst_riff_strh)); - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&strh, sizeof (gst_riff_strh)); if (got_bytes == sizeof (gst_riff_strh)) { avi_stream_context *target; @@ -375,7 +363,9 @@ gst_avi_demux_strh (GstAviDemux *avi_demux) target->total_bytes = 0LL; target->total_frames = 0; target->end_pos = -1; - + target->current_frame = 0; + target->current_byte = 0; + target->need_flush = FALSE; target->skip = 0; avi_demux->avih.bufsize = MAX (avi_demux->avih.bufsize, target->strh.bufsize); @@ -389,11 +379,10 @@ static void gst_avi_demux_dmlh (GstAviDemux *avi_demux) { gst_riff_dmlh *dmlh; + GstByteStream *bs = avi_demux->bs; guint32 got_bytes; - got_bytes = gst_bytestream_peek_bytes (avi_demux->bs, (guint8**) &dmlh, sizeof (gst_riff_dmlh)); - -/* g_print ("Found total frame: %u\n", dmlh->totalframes); */ + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&dmlh, sizeof (gst_riff_dmlh)); } static void @@ -401,12 +390,14 @@ gst_avi_demux_strf_vids (GstAviDemux *avi_demux) { gst_riff_strf_vids *strf; GstPad *srcpad; - GstByteStream *bs = avi_demux->bs; GstCaps *newcaps = NULL, *capslist = NULL; avi_stream_context *stream; - guint32 got_bytes; + GstByteStream *bs = avi_demux->bs; + guint32 got_bytes; - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&strf, sizeof (gst_riff_strf_vids)); + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&strf, sizeof (gst_riff_strf_vids)); + if (got_bytes != sizeof (gst_riff_strf_vids)) + return; GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: strf tag found in context vids"); GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: size %d", GUINT32_FROM_LE (strf->size)); @@ -499,12 +490,14 @@ gst_avi_demux_strf_auds (GstAviDemux *avi_demux) { gst_riff_strf_auds *strf; GstPad *srcpad; - GstByteStream *bs = avi_demux->bs; GstCaps *newcaps = NULL, *capslist = NULL; avi_stream_context *stream; - guint32 got_bytes; + GstByteStream *bs = avi_demux->bs; + guint32 got_bytes; - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&strf, sizeof (gst_riff_strf_auds)); + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&strf, sizeof (gst_riff_strf_auds)); + if (got_bytes != sizeof (gst_riff_strf_auds)) + return; GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: strf tag found in context auds"); GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: format %d", GUINT16_FROM_LE (strf->format)); @@ -600,12 +593,14 @@ gst_avi_demux_strf_iavs (GstAviDemux *avi_demux) { gst_riff_strf_iavs *strf; GstPad *srcpad; - GstByteStream *bs = avi_demux->bs; GstCaps *newcaps = NULL, *capslist = NULL; avi_stream_context *stream; - guint32 got_bytes; + GstByteStream *bs = avi_demux->bs; + guint32 got_bytes; - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&strf, sizeof (gst_riff_strf_iavs)); + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **)&strf, sizeof (gst_riff_strf_iavs)); + if (got_bytes != sizeof (gst_riff_strf_iavs)) + return; GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: strf tag found in context iavs"); GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux: DVAAuxSrc %08x", GUINT32_FROM_LE (strf->DVAAuxSrc)); @@ -682,17 +677,18 @@ gst_avi_demux_parse_index (GstAviDemux *avi_demux, GST_INFO (GST_CAT_PLUGIN_INFO, "avidemux: could not seek to index"); return; } - got_bytes = gst_bytestream_read (avi_demux->bs, &buf, 8); - while (got_bytes < 8) { + do { guint32 remaining; GstEvent *event; + got_bytes = gst_bytestream_read (avi_demux->bs, &buf, 8); + if (got_bytes == 8) + break; + gst_bytestream_get_status (avi_demux->bs, &remaining, &event); gst_event_unref (event); + } while (TRUE); - got_bytes = gst_bytestream_read (avi_demux->bs, &buf, 8); - } - if (GST_BUFFER_OFFSET (buf) != filepos + offset || GST_BUFFER_SIZE (buf) != 8) { GST_INFO (GST_CAT_PLUGIN_INFO, "avidemux: could not get index, got %lld %d, expected %ld", GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf), filepos + offset); @@ -745,7 +741,7 @@ gst_avi_demux_parse_index (GstAviDemux *avi_demux, /* 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; + avi_demux->index_offset = filepos - 4; else avi_demux->index_offset = 0; } @@ -778,7 +774,8 @@ gst_avi_demux_parse_index (GstAviDemux *avi_demux, avi_stream_context *stream; stream = &avi_demux->stream[i]; - GST_DEBUG (GST_CAT_PLUGIN_INFO, "stream %i: %d frames, %lld bytes", i, stream->total_frames, stream->total_bytes); + GST_DEBUG (GST_CAT_PLUGIN_INFO, "stream %i: %d frames, %lld bytes", + i, stream->total_frames, stream->total_bytes); } gst_buffer_unref (buf); @@ -1139,6 +1136,7 @@ gst_avi_demux_handle_sink_event (GstAviDemux *avi_demux) guint32 remaining; GstEvent *event; GstEventType type; + gboolean res = TRUE; gst_bytestream_get_status (avi_demux->bs, &remaining, &event); @@ -1148,7 +1146,8 @@ gst_avi_demux_handle_sink_event (GstAviDemux *avi_demux) case GST_EVENT_EOS: gst_bytestream_flush (avi_demux->bs, remaining); gst_pad_event_default (avi_demux->sinkpad, event); - break; + res = FALSE; + goto done; case GST_EVENT_FLUSH: g_warning ("flush event"); break; @@ -1163,7 +1162,7 @@ gst_avi_demux_handle_sink_event (GstAviDemux *avi_demux) if (GST_PAD_IS_USABLE (stream->pad)) { GST_DEBUG (GST_CAT_EVENT, "sending discont on %d %lld + %lld = %lld", i, avi_demux->last_seek, stream->delay, avi_demux->last_seek + stream->delay); - discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, + discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, avi_demux->last_seek + stream->delay , NULL); gst_pad_push (stream->pad, GST_BUFFER (discont)); } @@ -1177,293 +1176,226 @@ gst_avi_demux_handle_sink_event (GstAviDemux *avi_demux) gst_event_unref (event); - return TRUE; -} - -static inline gboolean -gst_avi_demux_read_chunk (GstAviDemux *avi_demux, guint32 *id, guint32 *size) -{ - gst_riff_chunk *chunk; - GstByteStream *bs = avi_demux->bs; - guint32 got_bytes; - - do { - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&chunk, sizeof (gst_riff_chunk)); - if (got_bytes == sizeof (gst_riff_chunk)) { - *id = GUINT32_FROM_LE (chunk->id); - *size = GUINT32_FROM_LE (chunk->size); - - gst_bytestream_flush (bs, sizeof (gst_riff_chunk)); - - return TRUE; - } - - } while (gst_avi_demux_handle_sink_event (avi_demux)); +done: - return TRUE; + return res; } -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 -gst_avi_demux_process_chunk (GstAviDemux *avi_demux, guint64 *filepos, - guint32 desired_tag, - gint rec_depth, guint32 *chunksize) +static void +gst_avi_demux_loop (GstElement *element) { - guint32 chunkid; - GstByteStream *bs = avi_demux->bs; + GstAviDemux *avi_demux; + gst_riff_riff chunk; + guint32 flush = 0; + guint32 got_bytes; + GstByteStream *bs; + guint64 pos; - if (!gst_avi_demux_read_chunk (avi_demux, &chunkid, chunksize)) { - g_print (" ***** Error reading chunk at filepos 0x%08llx\n", *filepos); - return FALSE; - } - if (desired_tag) { /* do we have to test identity? */ - if (desired_tag != chunkid) { - g_print ("\n\n *** Error: Expected chunk '%s', found '%s'\n", - gst_riff_id_to_fourcc (desired_tag), - gst_riff_id_to_fourcc (chunkid)); - return FALSE; - } - } + avi_demux = GST_AVI_DEMUX (element); - GST_INFO (GST_CAT_PLUGIN_INFO, "chunkid %s, size %08x, filepos %08llx", - gst_riff_id_to_fourcc (chunkid), *chunksize, *filepos); + bs = avi_demux->bs; - *filepos += (sizeof (guint32) + sizeof (guint32)); + if (avi_demux->seek_pending) { + GST_DEBUG (0, "avidemux: seek pending to %lld %08llx", + avi_demux->seek_offset, avi_demux->seek_offset); - switch (chunkid) { - case GST_RIFF_TAG_RIFF: - case GST_RIFF_TAG_LIST: + if (!gst_bytestream_seek (avi_demux->bs, + avi_demux->seek_offset, + GST_SEEK_METHOD_SET)) { - guint32 datashowed; - guint32 subchunksize = 0; /* size of a read subchunk */ - gchar *formtype; - guint32 got_bytes; - - got_bytes = gst_bytestream_peek_bytes (bs, (guint8**)&formtype, sizeof (guint32)); - if (got_bytes < sizeof(guint32)) - return FALSE; - - switch (GUINT32_FROM_LE (*((guint32*)formtype))) { - case GST_RIFF_LIST_movi: - gst_avi_demux_parse_index (avi_demux, *filepos, *chunksize); - while (!gst_bytestream_flush (bs, sizeof (guint32))) { - guint32 remaining; - GstEvent *event; - - gst_bytestream_get_status (avi_demux->bs, &remaining, &event); - gst_event_unref (event); - } - if (avi_demux->avih.bufsize) { - gst_bytestream_size_hint (avi_demux->bs, avi_demux->avih.bufsize); - } + GST_INFO (GST_CAT_PLUGIN_INFO, "avidemux: could not seek"); + } + avi_demux->seek_pending = FALSE; + } - gst_avi_demux_process_movi (avi_demux, rec_depth, filepos); - goto done; - default: - /* flush the form type */ - gst_bytestream_flush_fast (bs, sizeof (guint32)); - break; + pos = gst_bytestream_tell (bs); + do { + gst_riff_riff *temp_chunk; + guint32 skipsize; + + /* read first two dwords to get chunktype and size */ + while (TRUE) { + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **) &temp_chunk, sizeof (gst_riff_chunk)); + if (got_bytes < sizeof (gst_riff_chunk)) { + if (!gst_avi_demux_handle_sink_event (avi_demux)) + return; } + else break; + } - datashowed = sizeof (guint32); /* we showed the form type */ - *filepos += datashowed; /* for the rest of the routine */ - - while (datashowed < *chunksize) { /* while not showed all: */ - - 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)) { - - g_print (" ***** Error processing chunk at filepos 0x%08llxi %u %u\n", - *filepos, *chunksize, datashowed); - return FALSE; - } - if (avi_demux->restart) - goto done; - - subchunksize = ((subchunksize + 1) & ~1); - - datashowed += (sizeof (guint32) + sizeof (guint32) + subchunksize); - GST_INFO (GST_CAT_PLUGIN_INFO, "process chunk done filepos %08llx, subchunksize %08x", - *filepos, subchunksize); - } - if (datashowed != *chunksize) { - g_warning ("error parsing AVI %u %u", datashowed, *chunksize); - } - goto done; + chunk.id = temp_chunk->id; + chunk.size = temp_chunk->size; + + switch (chunk.id) { + case GST_RIFF_TAG_RIFF: + case GST_RIFF_TAG_LIST: + /* read complete list chunk */ + while (TRUE) { + got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **) &temp_chunk, sizeof (gst_riff_list)); + if (got_bytes < sizeof (gst_riff_list)) { + if (!gst_avi_demux_handle_sink_event (avi_demux)) + return; + } + else break; + } + chunk.type = temp_chunk->type; + skipsize = sizeof (gst_riff_list); + break; + default: + skipsize = sizeof (gst_riff_chunk); + break; } - case GST_RIFF_TAG_avih: - gst_avi_demux_avih (avi_demux); - break; - case GST_RIFF_TAG_strh: - { - gst_avi_demux_strh (avi_demux); + gst_bytestream_flush_fast (bs, skipsize); + } + while (FALSE); + + /* need to flush an even number of bytes at the end */ + flush = (chunk.size + 1) & ~1; + + switch (avi_demux->state) { + case GST_AVI_DEMUX_START: + if (chunk.id != GST_RIFF_TAG_RIFF && + chunk.id != GST_RIFF_RIFF_AVI) { + gst_element_error (element, "This doesn't appear to be an AVI file"); + return; + } + avi_demux->state = GST_AVI_DEMUX_HEADER; + /* we are not going to flush lists */ + flush = 0; break; - } - case GST_RIFF_TAG_strf: - switch (avi_demux->fcc_type) { - case GST_RIFF_FCC_vids: - gst_avi_demux_strf_vids (avi_demux); - break; - case GST_RIFF_FCC_auds: - gst_avi_demux_strf_auds (avi_demux); - break; - case GST_RIFF_FCC_iavs: - gst_avi_demux_strf_iavs (avi_demux); + case GST_AVI_DEMUX_HEADER: + GST_DEBUG (0, "riff tag: %4.4s %08x", (gchar *)&chunk.id, chunk.size); + switch (chunk.id) { + case GST_RIFF_TAG_LIST: + GST_DEBUG (0, "list type: %4.4s", (gchar *)&chunk.type); + switch (chunk.type) { + case GST_RIFF_LIST_movi: + { + guint64 filepos; + + filepos = gst_bytestream_tell (bs); + + gst_avi_demux_parse_index (avi_demux, filepos , chunk.size - 4); + + if (avi_demux->avih.bufsize) { + gst_bytestream_size_hint (avi_demux->bs, avi_demux->avih.bufsize); + } + + avi_demux->state = GST_AVI_DEMUX_MOVI; + break; + } + default: + break; + } + flush = 0; break; - case GST_RIFF_FCC_pads: - case GST_RIFF_FCC_txts: - default: - GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux_chain: strh type %s not supported", + case GST_RIFF_TAG_avih: + gst_avi_demux_avih (avi_demux); + break; + case GST_RIFF_TAG_strh: + gst_avi_demux_strh (avi_demux); + break; + case GST_RIFF_TAG_strf: + switch (avi_demux->fcc_type) { + case GST_RIFF_FCC_vids: + gst_avi_demux_strf_vids (avi_demux); + break; + case GST_RIFF_FCC_auds: + gst_avi_demux_strf_auds (avi_demux); + break; + case GST_RIFF_FCC_iavs: + gst_avi_demux_strf_iavs (avi_demux); + break; + case GST_RIFF_FCC_pads: + case GST_RIFF_FCC_txts: + default: + GST_INFO (GST_CAT_PLUGIN_INFO, "gst_avi_demux_chain: strh type %s not supported", gst_riff_id_to_fourcc (avi_demux->fcc_type)); + break; + } + break; + case GST_RIFF_TAG_dmlh: + gst_avi_demux_dmlh (avi_demux); + break; + case GST_RIFF_TAG_JUNK: + case GST_RIFF_ISFT: + break; + default: + GST_DEBUG (0, " ***** unknown chunkid %08x", chunk.id); break; } break; - case GST_RIFF_00dc: - case GST_RIFF_00db: - case GST_RIFF_00__: - case GST_RIFF_01wb: - { - gint stream_id; - avi_stream_context *stream; - gint64 next_ts; - GstFormat format; + case GST_AVI_DEMUX_MOVI: + switch (chunk.id) { + case GST_RIFF_00dc: + case GST_RIFF_00db: + case GST_RIFF_00__: + case GST_RIFF_01wb: + { + gint stream_id; + avi_stream_context *stream; + gint64 next_ts; + GstFormat format; - stream_id = CHUNKID_TO_STREAMNR (chunkid); + stream_id = CHUNKID_TO_STREAMNR (chunk.id); - stream = &avi_demux->stream[stream_id]; + stream = &avi_demux->stream[stream_id]; - GST_DEBUG (0,"gst_avi_demux_chain: tag found %08x size %08x stream_id %d", - chunkid, *chunksize, stream_id); + GST_DEBUG (0,"gst_avi_demux_chain: tag found %08x size %08x stream_id %d", + chunk.id, chunk.size, stream_id); - format = GST_FORMAT_TIME; - gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &next_ts); + format = GST_FORMAT_TIME; + gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &next_ts); - if (stream->strh.init_frames == stream->current_frame && stream->delay==0) - stream->delay = next_ts; + if (stream->strh.init_frames == stream->current_frame && stream->delay==0) + stream->delay = next_ts; - stream->current_frame++; - stream->current_byte += *chunksize; + stream->current_frame++; + stream->current_byte += chunk.size; - if (stream->skip) { - stream->skip--; - } - else { - if (GST_PAD_IS_USABLE (stream->pad)) { - if (next_ts >= stream->end_pos) { - gst_pad_push (stream->pad, GST_BUFFER (gst_event_new (GST_EVENT_EOS))); - GST_DEBUG (0, "end stream %d: %lld %d %lld", stream_id, next_ts, stream->current_frame - 1, + if (stream->skip) { + stream->skip--; + } + else { + if (GST_PAD_IS_USABLE (stream->pad)) { + if (next_ts >= stream->end_pos) { + gst_pad_push (stream->pad, GST_BUFFER (gst_event_new (GST_EVENT_EOS))); + GST_DEBUG (0, "end stream %d: %lld %d %lld", stream_id, next_ts, stream->current_frame - 1, stream->end_pos); - } - else { - GstBuffer *buf; - guint32 got_bytes; + } + else { + GstBuffer *buf; + guint32 got_bytes; - if (*chunksize) { - got_bytes = gst_bytestream_peek (bs, &buf, *chunksize); + if (chunk.size) { + got_bytes = gst_bytestream_peek (avi_demux->bs, &buf, chunk.size); - GST_BUFFER_TIMESTAMP (buf) = next_ts; + GST_BUFFER_TIMESTAMP (buf) = next_ts; - if (stream->need_flush) { - /* FIXME, do some flush event here */ - stream->need_flush = FALSE; - } - GST_DEBUG (0, "send stream %d: %lld %d %lld %08x", stream_id, next_ts, stream->current_frame - 1, - stream->delay, *chunksize); + if (stream->need_flush) { + /* FIXME, do some flush event here */ + stream->need_flush = FALSE; + } + GST_DEBUG (0, "send stream %d: %lld %d %lld %08x", stream_id, next_ts, stream->current_frame - 1, + stream->delay, chunk.size); - gst_pad_push(stream->pad, buf); - } + gst_pad_push(stream->pad, buf); + } + } + } } - } + break; + } + default: + GST_DEBUG (0, " ***** unknown chunkid %08x", chunk.id); + break; } - - *chunksize = (*chunksize + 1) & ~1; break; - } - case GST_RIFF_TAG_dmlh: - gst_avi_demux_dmlh (avi_demux); - break; - - case GST_RIFF_TAG_JUNK: - case GST_RIFF_ISFT: - *chunksize = (*chunksize + 1) & ~1; - break; - - default: - GST_DEBUG (0, " ***** unknown chunkid %08x", chunkid); - *chunksize = 1; -/* *chunksize = (*chunksize + 1) & ~1; */ - } - GST_INFO (GST_CAT_PLUGIN_INFO, "chunkid %s, flush %08x, filepos %08llx", - gst_riff_id_to_fourcc (chunkid), *chunksize, *filepos); - - *filepos += *chunksize; - { - gboolean ret; - - ret = gst_bytestream_flush (bs, *chunksize); - if (!ret) { - return gst_avi_demux_handle_sink_event (avi_demux); - } } -done: - - return TRUE; -} - -static void -gst_avi_demux_loop (GstElement *element) -{ - GstAviDemux *avi_demux; - guint32 chunksize; - guint64 filepos = 0; - - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_AVI_DEMUX (element)); - - avi_demux = GST_AVI_DEMUX (element); - - avi_demux->restart = FALSE; - - /* this is basically an infinite loop */ - 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"); - return; - } - if (!avi_demux->restart) - /* if we exit the loop we are EOS */ - gst_pad_event_default (avi_demux->sinkpad, gst_event_new (GST_EVENT_EOS)); + if (flush) + gst_bytestream_flush (avi_demux->bs, flush); } static GstElementStateReturn @@ -1477,6 +1409,13 @@ gst_avi_demux_change_state (GstElement *element) case GST_STATE_READY_TO_PAUSED: avi_demux->bs = gst_bytestream_new (avi_demux->sinkpad); avi_demux->last_seek = 0; + avi_demux->state = GST_AVI_DEMUX_START; + avi_demux->num_streams = 0; + avi_demux->num_v_streams = 0; + avi_demux->num_a_streams = 0; + avi_demux->index_entries = NULL; + avi_demux->index_size = 0; + avi_demux->seek_pending = 0; break; case GST_STATE_PAUSED_TO_PLAYING: break; @@ -1484,7 +1423,6 @@ gst_avi_demux_change_state (GstElement *element) break; case GST_STATE_PAUSED_TO_READY: gst_bytestream_destroy (avi_demux->bs); - avi_demux->restart = TRUE; break; case GST_STATE_READY_TO_NULL: break; @@ -1524,6 +1462,7 @@ plugin_init (GModule *module, GstPlugin *plugin) /* this filter needs the riff parser */ if (!gst_library_load ("gstbytestream")) return FALSE; + if (!gst_library_load ("gstriff")) return FALSE; diff --git a/gst/avi/gstavidemux.h b/gst/avi/gstavidemux.h index 3c32cd07..ed41c7cf 100644 --- a/gst/avi/gstavidemux.h +++ b/gst/avi/gstavidemux.h @@ -24,8 +24,8 @@ #include <config.h> #include <gst/gst.h> -#include <gst/riff/riff.h> #include <gst/bytestream/bytestream.h> +#include <gst/riff/riff.h> #ifdef __cplusplus extern "C" { @@ -73,7 +73,6 @@ typedef struct guint32 current_byte; guint64 delay; gboolean need_flush; - guint32 av_bps; guint64 end_pos; guint64 total_bytes; @@ -83,6 +82,13 @@ typedef struct } avi_stream_context; +typedef enum +{ + GST_AVI_DEMUX_START, + GST_AVI_DEMUX_HEADER, + GST_AVI_DEMUX_MOVI, +} GstAviDemuxState; + struct _GstAviDemux { GstElement element; @@ -91,8 +97,9 @@ struct _GstAviDemux { /* AVI decoding state */ guint32 fcc_type; + GstAviDemuxState state; - GstByteStream *bs; + GstByteStream *bs; gst_avi_index_entry *index_entries; gulong index_size; @@ -109,7 +116,6 @@ struct _GstAviDemux { gboolean seek_pending; gint64 seek_offset; guint64 last_seek; - gboolean restart; }; struct _GstAviDemuxClass { diff --git a/gst/avi/gstaviparse.c b/gst/avi/gstaviparse.c index f4c35f72..d5a2fb06 100644 --- a/gst/avi/gstaviparse.c +++ b/gst/avi/gstaviparse.c @@ -23,8 +23,7 @@ #include <config.h> #include <gst/gst.h> #include <gst/bytestream/bytestream.h> - -#include "riff.h" +#include <gst/riff/riff.h> #define GST_TYPE_AVI_PARSE \ (gst_avi_parse_get_type()) @@ -207,9 +206,10 @@ gst_avi_parse_loop (GstElement *element) { GstAviParse *avi_parse; GstRiffParse *rp; - GstBuffer *buf; - guint32 id; GstRiffReturn res; + gst_riff_chunk chunk; + guint32 data_size; + guint64 pos; g_return_if_fail (element != NULL); g_return_if_fail (GST_IS_AVI_PARSE (element)); @@ -218,40 +218,35 @@ gst_avi_parse_loop (GstElement *element) rp = avi_parse->rp; - res = gst_riff_parse_next_chunk (rp, &id, &buf); + pos = gst_bytestream_tell (rp->bs); + + res = gst_riff_parse_next_chunk (rp, &chunk); if (res == GST_RIFF_EOS) { gst_element_set_eos (element); return; } - switch (id) { + switch (chunk.id) { case GST_RIFF_TAG_RIFF: case GST_RIFF_TAG_LIST: - { - gst_riff_list *list; - - list = (gst_riff_list *) GST_BUFFER_DATA (buf); - - g_print ("%4.4s %08x %4.4s\n", (gchar *)&list->id, list->size, (gchar *)&list->type); + g_print ("%08llx: %4.4s %08x %4.4s\n", pos, (gchar *)&chunk.id, chunk.size, (gchar *)&chunk.type); + data_size = 0; break; - } default: - { - gst_riff_chunk *chunk; - - chunk = (gst_riff_chunk *) GST_BUFFER_DATA (buf); - - g_print ("%4.4s %08x\n", (gchar *)&chunk->id, chunk->size); + g_print ("%08llx: %4.4s %08x\n", pos, (gchar *)&chunk.id, chunk.size); + data_size = chunk.size; break; - } } - if (GST_PAD_IS_USABLE (avi_parse->srcpad)) { + if (GST_PAD_IS_USABLE (avi_parse->srcpad) && data_size) { + GstBuffer *buf; + + gst_riff_parse_peek (rp, &buf, data_size); gst_pad_push (avi_parse->srcpad, buf); } - else { - gst_buffer_unref (buf); - } + data_size = (data_size + 1) & ~1; + + gst_riff_parse_flush (rp, data_size); } static GstElementStateReturn diff --git a/gst/avi/riff.c b/gst/avi/riff.c deleted file mode 100644 index 5138b8dc..00000000 --- a/gst/avi/riff.c +++ /dev/null @@ -1,115 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "riff.h" - -GstRiffParse* -gst_riff_parse_new (GstPad *pad) -{ - GstRiffParse *parse; - - parse = g_new0 (GstRiffParse, 1); - parse->pad = pad; - parse->bs = gst_bytestream_new (pad); - - return parse; -} - -void -gst_riff_parse_free (GstRiffParse *parse) -{ - gst_bytestream_destroy (parse->bs); - g_free (parse); -} - - -static GstRiffReturn -gst_riff_parse_handle_sink_event (GstRiffParse *parse) -{ - guint32 remaining; - GstEvent *event; - GstEventType type; - GstRiffReturn ret = GST_RIFF_OK; - - gst_bytestream_get_status (parse->bs, &remaining, &event); - - type = event? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN; - - switch (type) { - case GST_EVENT_EOS: - ret = GST_RIFF_EOS; - break; - default: - g_warning ("unhandled event %d", type); - break; - } - - gst_event_unref (event); - - return ret; -} - -GstRiffReturn -gst_riff_parse_next_chunk (GstRiffParse *parse, guint32 *id, GstBuffer **buf) -{ - GstByteStream *bs; - guint32 got_bytes; - gint skipsize; - gst_riff_chunk *chunk; - - bs = parse->bs; - - do { - got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **) &chunk, sizeof (gst_riff_chunk)); - if (got_bytes < sizeof (gst_riff_chunk)) { - GstRiffReturn ret; - - ret = gst_riff_parse_handle_sink_event (parse); - - if (ret == GST_RIFF_EOS) - return ret; - } - } while (got_bytes != sizeof (gst_riff_chunk)); - - *id = chunk->id; - - switch (chunk->id) { - case GST_RIFF_TAG_RIFF: - case GST_RIFF_TAG_LIST: - skipsize = sizeof (gst_riff_list); - break; - default: - skipsize = (chunk->size + 8 + 1) & ~1; - break; - } - - do { - got_bytes = gst_bytestream_read (bs, buf, skipsize); - if (got_bytes < skipsize) { - GstRiffReturn ret; - - ret = gst_riff_parse_handle_sink_event (parse); - - if (ret == GST_RIFF_EOS) - return ret; - } - } while (got_bytes != skipsize); - - return GST_RIFF_OK; -} diff --git a/gst/avi/riff.h b/gst/avi/riff.h deleted file mode 100644 index f78e72c4..00000000 --- a/gst/avi/riff.h +++ /dev/null @@ -1,356 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_RIFF_PARSE_H__ -#define __GST_RIFF_PARSE_H__ - -#include <gst/gst.h> -#include <gst/bytestream/bytestream.h> - -typedef enum { - GST_RIFF_OK = 0, - GST_RIFF_EOS = -1, - GST_RIFF_ERROR = -2, - GST_RIFF_EINVAL = -3, -} GstRiffReturn; - -#define MAKE_FOUR_CC(a,b,c,d) ( ((guint32)a) | (((guint32)b)<< 8) | \ - ((guint32)c)<<16 | (((guint32)d)<<24) ) - -/* RIFF types */ -#define GST_RIFF_RIFF_WAVE MAKE_FOUR_CC('W','A','V','E') -#define GST_RIFF_RIFF_AVI MAKE_FOUR_CC('A','V','I',' ') - -/* tags */ -#define GST_RIFF_TAG_RIFF MAKE_FOUR_CC('R','I','F','F') -#define GST_RIFF_TAG_RIFX MAKE_FOUR_CC('R','I','F','X') -#define GST_RIFF_TAG_LIST MAKE_FOUR_CC('L','I','S','T') -#define GST_RIFF_TAG_avih MAKE_FOUR_CC('a','v','i','h') -#define GST_RIFF_TAG_strd MAKE_FOUR_CC('s','t','r','d') -#define GST_RIFF_TAG_strh MAKE_FOUR_CC('s','t','r','h') -#define GST_RIFF_TAG_strf MAKE_FOUR_CC('s','t','r','f') -#define GST_RIFF_TAG_vedt MAKE_FOUR_CC('v','e','d','t') -#define GST_RIFF_TAG_JUNK MAKE_FOUR_CC('J','U','N','K') -#define GST_RIFF_TAG_idx1 MAKE_FOUR_CC('i','d','x','1') -/* WAV stuff */ -#define GST_RIFF_TAG_fmt MAKE_FOUR_CC('f','m','t',' ') -#define GST_RIFF_TAG_data MAKE_FOUR_CC('d','a','t','a') - -/* LIST types */ -#define GST_RIFF_LIST_movi MAKE_FOUR_CC('m','o','v','i') -#define GST_RIFF_LIST_hdrl MAKE_FOUR_CC('h','d','r','l') -#define GST_RIFF_LIST_strl MAKE_FOUR_CC('s','t','r','l') - -/* fcc types */ -#define GST_RIFF_FCC_vids MAKE_FOUR_CC('v','i','d','s') -#define GST_RIFF_FCC_auds MAKE_FOUR_CC('a','u','d','s') -#define GST_RIFF_FCC_pads MAKE_FOUR_CC('p','a','d','s') -#define GST_RIFF_FCC_txts MAKE_FOUR_CC('t','x','t','s') -#define GST_RIFF_FCC_vidc MAKE_FOUR_CC('v','i','d','c') -#define GST_RIFF_FCC_iavs MAKE_FOUR_CC('i','a','v','s') -/* fcc handlers */ -#define GST_RIFF_FCCH_RLE MAKE_FOUR_CC('R','L','E',' ') -#define GST_RIFF_FCCH_msvc MAKE_FOUR_CC('m','s','v','c') -#define GST_RIFF_FCCH_MSVC MAKE_FOUR_CC('M','S','V','C') - -/*********Chunk Names***************/ -#define GST_RIFF_FF00 MAKE_FOUR_CC(0xFF,0xFF,0x00,0x00) -#define GST_RIFF_00 MAKE_FOUR_CC( '0', '0',0x00,0x00) -#define GST_RIFF_01 MAKE_FOUR_CC( '0', '1',0x00,0x00) -#define GST_RIFF_02 MAKE_FOUR_CC( '0', '2',0x00,0x00) -#define GST_RIFF_03 MAKE_FOUR_CC( '0', '3',0x00,0x00) -#define GST_RIFF_04 MAKE_FOUR_CC( '0', '4',0x00,0x00) -#define GST_RIFF_05 MAKE_FOUR_CC( '0', '5',0x00,0x00) -#define GST_RIFF_06 MAKE_FOUR_CC( '0', '6',0x00,0x00) -#define GST_RIFF_07 MAKE_FOUR_CC( '0', '7',0x00,0x00) -#define GST_RIFF_00pc MAKE_FOUR_CC( '0', '0', 'p', 'c') -#define GST_RIFF_01pc MAKE_FOUR_CC( '0', '1', 'p', 'c') -#define GST_RIFF_00dc MAKE_FOUR_CC( '0', '0', 'd', 'c') -#define GST_RIFF_00dx MAKE_FOUR_CC( '0', '0', 'd', 'x') -#define GST_RIFF_00db MAKE_FOUR_CC( '0', '0', 'd', 'b') -#define GST_RIFF_00xx MAKE_FOUR_CC( '0', '0', 'x', 'x') -#define GST_RIFF_00id MAKE_FOUR_CC( '0', '0', 'i', 'd') -#define GST_RIFF_00rt MAKE_FOUR_CC( '0', '0', 'r', 't') -#define GST_RIFF_0021 MAKE_FOUR_CC( '0', '0', '2', '1') -#define GST_RIFF_00iv MAKE_FOUR_CC( '0', '0', 'i', 'v') -#define GST_RIFF_0031 MAKE_FOUR_CC( '0', '0', '3', '1') -#define GST_RIFF_0032 MAKE_FOUR_CC( '0', '0', '3', '2') -#define GST_RIFF_00vc MAKE_FOUR_CC( '0', '0', 'v', 'c') -#define GST_RIFF_00xm MAKE_FOUR_CC( '0', '0', 'x', 'm') -#define GST_RIFF_01wb MAKE_FOUR_CC( '0', '1', 'w', 'b') -#define GST_RIFF_01dc MAKE_FOUR_CC( '0', '1', 'd', 'c') -#define GST_RIFF_00__ MAKE_FOUR_CC( '0', '0', '_', '_') - -/*********VIDEO CODECS**************/ -#define GST_RIFF_cram MAKE_FOUR_CC( 'c', 'r', 'a', 'm') -#define GST_RIFF_CRAM MAKE_FOUR_CC( 'C', 'R', 'A', 'M') -#define GST_RIFF_wham MAKE_FOUR_CC( 'w', 'h', 'a', 'm') -#define GST_RIFF_WHAM MAKE_FOUR_CC( 'W', 'H', 'A', 'M') -#define GST_RIFF_rgb MAKE_FOUR_CC(0x00,0x00,0x00,0x00) -#define GST_RIFF_RGB MAKE_FOUR_CC( 'R', 'G', 'B', ' ') -#define GST_RIFF_rle8 MAKE_FOUR_CC(0x01,0x00,0x00,0x00) -#define GST_RIFF_RLE8 MAKE_FOUR_CC( 'R', 'L', 'E', '8') -#define GST_RIFF_rle4 MAKE_FOUR_CC(0x02,0x00,0x00,0x00) -#define GST_RIFF_RLE4 MAKE_FOUR_CC( 'R', 'L', 'E', '4') -#define GST_RIFF_none MAKE_FOUR_CC(0x00,0x00,0xFF,0xFF) -#define GST_RIFF_NONE MAKE_FOUR_CC( 'N', 'O', 'N', 'E') -#define GST_RIFF_pack MAKE_FOUR_CC(0x01,0x00,0xFF,0xFF) -#define GST_RIFF_PACK MAKE_FOUR_CC( 'P', 'A', 'C', 'K') -#define GST_RIFF_tran MAKE_FOUR_CC(0x02,0x00,0xFF,0xFF) -#define GST_RIFF_TRAN MAKE_FOUR_CC( 'T', 'R', 'A', 'N') -#define GST_RIFF_ccc MAKE_FOUR_CC(0x03,0x00,0xFF,0xFF) -#define GST_RIFF_CCC MAKE_FOUR_CC( 'C', 'C', 'C', ' ') -#define GST_RIFF_cyuv MAKE_FOUR_CC( 'c', 'y', 'u', 'v') -#define GST_RIFF_CYUV MAKE_FOUR_CC( 'C', 'Y', 'U', 'V') -#define GST_RIFF_jpeg MAKE_FOUR_CC(0x04,0x00,0xFF,0xFF) -#define GST_RIFF_JPEG MAKE_FOUR_CC( 'J', 'P', 'E', 'G') -#define GST_RIFF_MJPG MAKE_FOUR_CC( 'M', 'J', 'P', 'G') -#define GST_RIFF_mJPG MAKE_FOUR_CC( 'm', 'J', 'P', 'G') -#define GST_RIFF_IJPG MAKE_FOUR_CC( 'I', 'J', 'P', 'G') -#define GST_RIFF_rt21 MAKE_FOUR_CC( 'r', 't', '2', '1') -#define GST_RIFF_RT21 MAKE_FOUR_CC( 'R', 'T', '2', '1') -#define GST_RIFF_iv31 MAKE_FOUR_CC( 'i', 'v', '3', '1') -#define GST_RIFF_IV31 MAKE_FOUR_CC( 'I', 'V', '3', '1') -#define GST_RIFF_iv32 MAKE_FOUR_CC( 'i', 'v', '3', '2') -#define GST_RIFF_IV32 MAKE_FOUR_CC( 'I', 'V', '3', '2') -#define GST_RIFF_iv41 MAKE_FOUR_CC( 'i', 'v', '4', '1') -#define GST_RIFF_IV41 MAKE_FOUR_CC( 'I', 'V', '4', '1') -#define GST_RIFF_iv50 MAKE_FOUR_CC( 'i', 'v', '5', '0') -#define GST_RIFF_IV50 MAKE_FOUR_CC( 'I', 'V', '5', '0') -#define GST_RIFF_cvid MAKE_FOUR_CC( 'c', 'v', 'i', 'd') -#define GST_RIFF_CVID MAKE_FOUR_CC( 'C', 'V', 'I', 'D') -#define GST_RIFF_ULTI MAKE_FOUR_CC( 'U', 'L', 'T', 'I') -#define GST_RIFF_ulti MAKE_FOUR_CC( 'u', 'l', 't', 'i') -#define GST_RIFF_YUV9 MAKE_FOUR_CC( 'Y', 'V', 'U', '9') -#define GST_RIFF_YVU9 MAKE_FOUR_CC( 'Y', 'U', 'V', '9') -#define GST_RIFF_XMPG MAKE_FOUR_CC( 'X', 'M', 'P', 'G') -#define GST_RIFF_xmpg MAKE_FOUR_CC( 'x', 'm', 'p', 'g') -#define GST_RIFF_VDOW MAKE_FOUR_CC( 'V', 'D', 'O', 'W') -#define GST_RIFF_MVI1 MAKE_FOUR_CC( 'M', 'V', 'I', '1') -#define GST_RIFF_v422 MAKE_FOUR_CC( 'v', '4', '2', '2') -#define GST_RIFF_V422 MAKE_FOUR_CC( 'V', '4', '2', '2') -#define GST_RIFF_mvi1 MAKE_FOUR_CC( 'm', 'v', 'i', '1') -#define GST_RIFF_MPIX MAKE_FOUR_CC(0x04,0x00, 'i', '1') /* MotionPixels munged their id */ -#define GST_RIFF_AURA MAKE_FOUR_CC( 'A', 'U', 'R', 'A') -#define GST_RIFF_DMB1 MAKE_FOUR_CC( 'D', 'M', 'B', '1') -#define GST_RIFF_dmb1 MAKE_FOUR_CC( 'd', 'm', 'b', '1') - -#define GST_RIFF_BW10 MAKE_FOUR_CC( 'B', 'W', '1', '0') -#define GST_RIFF_bw10 MAKE_FOUR_CC( 'b', 'w', '1', '0') - -#define GST_RIFF_yuy2 MAKE_FOUR_CC( 'y', 'u', 'y', '2') -#define GST_RIFF_YUY2 MAKE_FOUR_CC( 'Y', 'U', 'Y', '2') -#define GST_RIFF_YUV8 MAKE_FOUR_CC( 'Y', 'U', 'V', '8') -#define GST_RIFF_WINX MAKE_FOUR_CC( 'W', 'I', 'N', 'X') -#define GST_RIFF_WPY2 MAKE_FOUR_CC( 'W', 'P', 'Y', '2') -#define GST_RIFF_m263 MAKE_FOUR_CC( 'm', '2', '6', '3') -#define GST_RIFF_M263 MAKE_FOUR_CC( 'M', '2', '6', '3') - -#define GST_RIFF_Q1_0 MAKE_FOUR_CC( 'Q', '1',0x2e, '0') -#define GST_RIFF_SFMC MAKE_FOUR_CC( 'S', 'F', 'M', 'C') - -#define GST_RIFF_y41p MAKE_FOUR_CC( 'y', '4', '1', 'p') -#define GST_RIFF_Y41P MAKE_FOUR_CC( 'Y', '4', '1', 'P') -#define GST_RIFF_yv12 MAKE_FOUR_CC( 'y', 'v', '1', '2') -#define GST_RIFF_YV12 MAKE_FOUR_CC( 'Y', 'V', '1', '2') -#define GST_RIFF_vixl MAKE_FOUR_CC( 'v', 'i', 'x', 'l') -#define GST_RIFF_VIXL MAKE_FOUR_CC( 'V', 'I', 'X', 'L') -#define GST_RIFF_iyuv MAKE_FOUR_CC( 'i', 'y', 'u', 'v') -#define GST_RIFF_IYUV MAKE_FOUR_CC( 'I', 'Y', 'U', 'V') -#define GST_RIFF_i420 MAKE_FOUR_CC( 'i', '4', '2', '0') -#define GST_RIFF_I420 MAKE_FOUR_CC( 'I', '4', '2', '0') -#define GST_RIFF_vyuy MAKE_FOUR_CC( 'v', 'y', 'u', 'y') -#define GST_RIFF_VYUY MAKE_FOUR_CC( 'V', 'Y', 'U', 'Y') - -#define GST_RIFF_DIV3 MAKE_FOUR_CC( 'D', 'I', 'V', '3') - -#define GST_RIFF_rpza MAKE_FOUR_CC( 'r', 'p', 'z', 'a') -/* And this here's the mistakes that need to be supported */ -#define GST_RIFF_azpr MAKE_FOUR_CC( 'a', 'z', 'p', 'r') /* recognize Apple's rpza mangled? */ - -/*********** FND in MJPG **********/ -#define GST_RIFF_ISFT MAKE_FOUR_CC( 'I', 'S', 'F', 'T') -#define GST_RIFF_IDIT MAKE_FOUR_CC( 'I', 'D', 'I', 'T') - -#define GST_RIFF_00AM MAKE_FOUR_CC( '0', '0', 'A', 'M') -#define GST_RIFF_DISP MAKE_FOUR_CC( 'D', 'I', 'S', 'P') -#define GST_RIFF_ISBJ MAKE_FOUR_CC( 'I', 'S', 'B', 'J') - -#define GST_RIFF_rec MAKE_FOUR_CC( 'r', 'e', 'c', ' ') - -/* common data structures */ -struct _gst_riff_avih { - guint32 us_frame; /* microsec per frame */ - guint32 max_bps; /* byte/s overall */ - guint32 pad_gran; /* pad_gran (???) */ - guint32 flags; -/* flags values */ -#define GST_RIFF_AVIH_HASINDEX 0x00000010 /* has idx1 chunk */ -#define GST_RIFF_AVIH_MUSTUSEINDEX 0x00000020 /* must use idx1 chunk to determine order */ -#define GST_RIFF_AVIH_ISINTERLEAVED 0x00000100 /* AVI file is interleaved */ -#define GST_RIFF_AVIH_WASCAPTUREFILE 0x00010000 /* specially allocated used for capturing real time video */ -#define GST_RIFF_AVIH_COPYRIGHTED 0x00020000 /* contains copyrighted data */ - guint32 tot_frames; /* # of frames (all) */ - guint32 init_frames; /* initial frames (???) */ - guint32 streams; - guint32 bufsize; /* suggested buffer size */ - guint32 width; - guint32 height; - guint32 scale; - guint32 rate; - guint32 start; - guint32 length; -}; - -struct _gst_riff_strh { - guint32 type; /* stream type */ - guint32 fcc_handler; /* fcc_handler */ - guint32 flags; -/* flags values */ -#define GST_RIFF_STRH_DISABLED 0x000000001 -#define GST_RIFF_STRH_VIDEOPALCHANGES 0x000010000 - guint32 priority; - guint32 init_frames; /* initial frames (???) */ - guint32 scale; - guint32 rate; - guint32 start; - guint32 length; - guint32 bufsize; /* suggested buffer size */ - guint32 quality; - guint32 samplesize; - /* XXX 16 bytes ? */ -}; - -struct _gst_riff_strf_vids { /* == BitMapInfoHeader */ - guint32 size; - guint32 width; - guint32 height; - guint16 planes; - guint16 bit_cnt; - guint32 compression; - guint32 image_size; - guint32 xpels_meter; - guint32 ypels_meter; - guint32 num_colors; /* used colors */ - guint32 imp_colors; /* important colors */ - /* may be more for some codecs */ -}; - - -struct _gst_riff_strf_auds { /* == WaveHeader (?) */ - guint16 format; -/**** from public Microsoft RIFF docs ******/ -#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000) -#define GST_RIFF_WAVE_FORMAT_PCM (0x0001) -#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002) -#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005) -#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006) -#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007) -#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010) -#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011) -#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015) -#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016) -#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020) -#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022) -#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031) -#define GST_RIFF_WAVE_FORMAT_MSN (0x0032) -#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050) -#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055) -#define GST_RIFF_IBM_FORMAT_MULAW (0x0101) -#define GST_RIFF_IBM_FORMAT_ALAW (0x0102) -#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103) -#define GST_RIFF_WAVE_FORMAT_DIVX (0x0160) -#define GST_RIFF_WAVE_FORMAT_divx (0x0161) -#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f) -#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750) -#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751) -#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f) -#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770) -#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771) - guint16 channels; - guint32 rate; - guint32 av_bps; - guint16 blockalign; - guint16 size; -}; - -struct _gst_riff_strf_iavs { - guint32 DVAAuxSrc; - guint32 DVAAuxCtl; - guint32 DVAAuxSrc1; - guint32 DVAAuxCtl1; - guint32 DVVAuxSrc; - guint32 DVVAuxCtl; - guint32 DVReserved1; - guint32 DVReserved2; -}; - -struct _gst_riff_riff { - guint32 id; - guint32 size; - guint32 type; -}; - -struct _gst_riff_list { - guint32 id; - guint32 size; - guint32 type; -}; - -struct _gst_riff_chunk { - guint32 id; - guint32 size; -}; - -struct _gst_riff_index_entry { - guint32 id; - guint32 flags; -#define GST_RIFF_IF_LIST (0x00000001L) -#define GST_RIFF_IF_KEYFRAME (0x00000010L) -#define GST_RIFF_IF_NO_TIME (0x00000100L) -#define GST_RIFF_IF_COMPUSE (0x0FFF0000L) - guint32 offset; - guint32 size; -}; - -typedef struct _gst_riff_riff gst_riff_riff; -typedef struct _gst_riff_list gst_riff_list; -typedef struct _gst_riff_chunk gst_riff_chunk; -typedef struct _gst_riff_index_entry gst_riff_index_entry; - -typedef struct _gst_riff_avih gst_riff_avih; -typedef struct _gst_riff_strh gst_riff_strh; -typedef struct _gst_riff_strf_vids gst_riff_strf_vids; -typedef struct _gst_riff_strf_auds gst_riff_strf_auds; -typedef struct _gst_riff_strf_iavs gst_riff_strf_iavs; - - -typedef struct _GstRiffParse GstRiffParse; - -struct _GstRiffParse { - GstPad *pad; - - GstByteStream *bs; -}; - -GstRiffParse* gst_riff_parse_new (GstPad *pad); -GstRiffReturn gst_riff_parse_next_chunk (GstRiffParse *parse, guint32 *id, GstBuffer **buf); -void gst_riff_parse_free (GstRiffParse *parse); - -#endif /* __GST_RIFF_PARSE_H__ */ |