From 53b9cea328c7b16b66fe469c56939803caa311f3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 22 Mar 2000 21:18:15 +0000 Subject: [PATCH] Added jpeg decoder. the avi decoder now configures the jpeg codec if an MJPG encoded avi is found. Fixed riff parsing... Original commit message from CVS: Added jpeg decoder. the avi decoder now configures the jpeg codec if an MJPG encoded avi is found. Fixed riff parsing. readded rgb_draw functions to the videosink. jpeglib is used to decode the jpeg image. --- configure.in | 1 + gst/gstpad.c | 3 +++ gst/types/gsttypes.c | 3 ++- libs/riff/Makefile.am | 2 +- libs/riff/gstriff.c | 53 +++++++++++++++++++++++++++++++++++-------- libs/riff/gstriff.h | 3 +++ 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/configure.in b/configure.in index 66f845b6e2..9c64d9926d 100644 --- a/configure.in +++ b/configure.in @@ -304,6 +304,7 @@ plugins/Makefile plugins/au/Makefile plugins/wav/Makefile plugins/avi/Makefile +plugins/jpeg/Makefile plugins/mp3decode/Makefile plugins/mp3decode/xa/Makefile plugins/mp3decode/xing/Makefile diff --git a/gst/gstpad.c b/gst/gstpad.c index 7b14ab8d69..ac41477716 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -148,6 +148,7 @@ void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) { void gst_pad_push(GstPad *pad,GstBuffer *buffer) { g_return_if_fail(pad != NULL); g_return_if_fail(GST_IS_PAD(pad)); + g_return_if_fail(GST_PAD_CONNECTED(pad)); g_return_if_fail(buffer != NULL); gst_trace_add_entry(NULL,0,buffer,"push buffer"); @@ -251,6 +252,8 @@ void gst_pad_set_parent(GstPad *pad,GstObject *parent) { g_return_if_fail(GTK_IS_OBJECT(parent)); g_return_if_fail((gpointer)pad != (gpointer)parent); + //g_print("set parent %s\n", gst_element_get_name(parent)); + pad->parent = parent; } diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index c88f08df14..990a17126a 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -30,7 +30,8 @@ GstTypeFactory _factories[] = { { "audio/mpeg audio/mp3", ".mp2 .mp3 .mpa .mpega", mp3_typefind }, { "audio/wav", ".wav", wav_typefind }, { "audio/ac3", ".ac3", NULL }, - { "video/raw", ".raw", NULL }, + { "image/jpeg", ".jpg .jpeg", NULL }, + { "video/raw image/raw", ".raw", NULL }, { "video/mpeg video/mpeg1 video/mpeg-system", ".mpg", NULL }, { "video/x-msvideo video/msvideo video/avi", ".avi", NULL }, { NULL, NULL, NULL }, diff --git a/libs/riff/Makefile.am b/libs/riff/Makefile.am index 70f3bef82f..80e254f16a 100644 --- a/libs/riff/Makefile.am +++ b/libs/riff/Makefile.am @@ -6,7 +6,7 @@ libgstriff_la_SOURCES = gstriff.c noinst_HEADERS = gstriff.h -CFLAGS += -O2 -Wall +CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la diff --git a/libs/riff/gstriff.c b/libs/riff/gstriff.c index 5e0dda95d4..eedfcc7223 100644 --- a/libs/riff/gstriff.c +++ b/libs/riff/gstriff.c @@ -20,6 +20,9 @@ #include +//#define debug(format,args...) g_print(format,##args) +#define debug(format,args...) + GstRiff *gst_riff_new(GstRiffCallback function, gpointer data) { GstRiff *riff; @@ -35,6 +38,7 @@ GstRiff *gst_riff_new(GstRiffCallback function, gpointer data) { riff->new_tag_found = function; riff->callback_data = data; riff->incomplete_chunk = NULL; + riff->dataleft = NULL; return riff; } @@ -50,7 +54,24 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { size = GST_BUFFER_SIZE(buf); last = off + size; - //g_print("offset new buffer 0x%08lx size 0x%08x\n", off, GST_BUFFER_SIZE(buf)); + debug("offset new buffer 0x%08lx size 0x%08x\n", off, GST_BUFFER_SIZE(buf)); + + if (riff->dataleft) { + gulong newsize; + + debug("recovering left data\n"); + newsize = riff->dataleft_size + size; + riff->dataleft = g_realloc(riff->dataleft, newsize); + memcpy(riff->dataleft+riff->dataleft_size, GST_BUFFER_DATA(buf), size); + gst_buffer_unref(buf); + + buf = gst_buffer_new(); + GST_BUFFER_DATA(buf) = riff->dataleft; + GST_BUFFER_SIZE(buf) = newsize; + off -= riff->dataleft_size; + //last -= riff->dataleft_size; + riff->dataleft = NULL; + } if (off == 0) { gulong *words = (gulong *)GST_BUFFER_DATA(buf); @@ -77,10 +98,10 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { // if we have an incomplete chunk from the previous buffer if (riff->incomplete_chunk) { guint leftover; - //g_print("have incomplete chunk %08x filled\n", riff->incomplete_chunk_size); + debug("have incomplete chunk %08x filled\n", riff->incomplete_chunk_size); leftover = riff->incomplete_chunk->size - riff->incomplete_chunk_size; if (leftover <= size) { - //g_print("we can fill it from %08x with %08x bytes = %08x\n", riff->incomplete_chunk_size, leftover, riff->incomplete_chunk_size+leftover); + debug("we can fill it from %08x with %08x bytes = %08x\n", riff->incomplete_chunk_size, leftover, riff->incomplete_chunk_size+leftover); memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), leftover); if (riff->new_tag_found) { @@ -91,22 +112,34 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { riff->incomplete_chunk = NULL; } else { - //g_print("we cannot fill it %08x >= %08lx\n", leftover, size); + debug("we cannot fill it %08x >= %08lx\n", leftover, size); memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), size); riff->incomplete_chunk_size += size; return 0; } } + if ((riff->nextlikely+12) > last) { + guint left = last - riff->nextlikely; + debug("not enough data next 0x%08x last 0x%08lx %08x %08x\n",riff->nextlikely, last, left, off); + + riff->dataleft = g_malloc(left); + riff->dataleft_size = left; + memcpy(riff->dataleft, GST_BUFFER_DATA(buf)+size-left, left); + + return 0; + } + + debug("next 0x%08x last 0x%08lx offset %08x\n",riff->nextlikely, last, off); /* loop while the next likely chunk header is in this buffer */ - while ((riff->nextlikely+12) < last) { + while ((riff->nextlikely+12) <= last) { gulong *words = (gulong *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely - off ); // loop over all of the chunks to check which one is finished while (riff->chunks) { chunk = g_list_nth_data(riff->chunks, 0); - //g_print("next 0x%08x offset 0x%08lx size 0x%08x\n",riff->nextlikely, chunk->offset, chunk->size); + debug("next 0x%08x offset 0x%08lx size 0x%08x\n",riff->nextlikely, chunk->offset, chunk->size); if (riff->nextlikely >= chunk->offset+chunk->size) { //g_print("found END LIST\n"); // we have the end of the chunk on the stack, remove it @@ -115,7 +148,7 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { else break; } - //g_print("next likely chunk is at offset 0x%08x\n",riff->nextlikely); + debug("next likely chunk is at offset 0x%08x\n",riff->nextlikely); chunk = (GstRiffChunk *)g_malloc(sizeof(GstRiffChunk)); g_return_val_if_fail(chunk != NULL, GST_RIFF_ENOMEM); @@ -141,13 +174,13 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { } else { - //g_print("chunk id offset %08x is 0x%08lx '%s' and is 0x%08lx long\n",riff->nextlikely, words[0], - // gst_riff_id_to_fourcc(words[0]),words[1]); + debug("chunk id offset %08x is 0x%08lx '%s' and is 0x%08lx long\n",riff->nextlikely, words[0], + gst_riff_id_to_fourcc(words[0]),words[1]); riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */ // if this buffer is incomplete if (riff->nextlikely > last) { - guint left = size - (riff->nextlikely - 0 - chunk->size - off); + guint left = size - (riff->nextlikely - chunk->size - off); //g_print("make incomplete buffer %08x\n", left); chunk->data = g_malloc(chunk->size); diff --git a/libs/riff/gstriff.h b/libs/riff/gstriff.h index 82afb3760f..a5f1aa073e 100644 --- a/libs/riff/gstriff.h +++ b/libs/riff/gstriff.h @@ -293,6 +293,9 @@ struct _GstRiff { gint state; guint32 curoffset; guint32 nextlikely; + /* leftover data */ + guchar *dataleft; + guint32 dataleft_size; /* callback function and data pointer */ GstRiffCallback new_tag_found;