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.
This commit is contained in:
Wim Taymans 2000-03-22 21:18:15 +00:00
parent 7cf6883096
commit 53b9cea328
6 changed files with 53 additions and 12 deletions

View file

@ -304,6 +304,7 @@ plugins/Makefile
plugins/au/Makefile plugins/au/Makefile
plugins/wav/Makefile plugins/wav/Makefile
plugins/avi/Makefile plugins/avi/Makefile
plugins/jpeg/Makefile
plugins/mp3decode/Makefile plugins/mp3decode/Makefile
plugins/mp3decode/xa/Makefile plugins/mp3decode/xa/Makefile
plugins/mp3decode/xing/Makefile plugins/mp3decode/xing/Makefile

View file

@ -148,6 +148,7 @@ void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) {
void gst_pad_push(GstPad *pad,GstBuffer *buffer) { void gst_pad_push(GstPad *pad,GstBuffer *buffer) {
g_return_if_fail(pad != NULL); g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(GST_PAD_CONNECTED(pad));
g_return_if_fail(buffer != NULL); g_return_if_fail(buffer != NULL);
gst_trace_add_entry(NULL,0,buffer,"push buffer"); 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(GTK_IS_OBJECT(parent));
g_return_if_fail((gpointer)pad != (gpointer)parent); g_return_if_fail((gpointer)pad != (gpointer)parent);
//g_print("set parent %s\n", gst_element_get_name(parent));
pad->parent = parent; pad->parent = parent;
} }

View file

@ -30,7 +30,8 @@ GstTypeFactory _factories[] = {
{ "audio/mpeg audio/mp3", ".mp2 .mp3 .mpa .mpega", mp3_typefind }, { "audio/mpeg audio/mp3", ".mp2 .mp3 .mpa .mpega", mp3_typefind },
{ "audio/wav", ".wav", wav_typefind }, { "audio/wav", ".wav", wav_typefind },
{ "audio/ac3", ".ac3", NULL }, { "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/mpeg video/mpeg1 video/mpeg-system", ".mpg", NULL },
{ "video/x-msvideo video/msvideo video/avi", ".avi", NULL }, { "video/x-msvideo video/msvideo video/avi", ".avi", NULL },
{ NULL, NULL, NULL }, { NULL, NULL, NULL },

View file

@ -6,7 +6,7 @@ libgstriff_la_SOURCES = gstriff.c
noinst_HEADERS = gstriff.h 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) INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir)
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la

View file

@ -20,6 +20,9 @@
#include <gstriff.h> #include <gstriff.h>
//#define debug(format,args...) g_print(format,##args)
#define debug(format,args...)
GstRiff *gst_riff_new(GstRiffCallback function, gpointer data) { GstRiff *gst_riff_new(GstRiffCallback function, gpointer data) {
GstRiff *riff; GstRiff *riff;
@ -35,6 +38,7 @@ GstRiff *gst_riff_new(GstRiffCallback function, gpointer data) {
riff->new_tag_found = function; riff->new_tag_found = function;
riff->callback_data = data; riff->callback_data = data;
riff->incomplete_chunk = NULL; riff->incomplete_chunk = NULL;
riff->dataleft = NULL;
return riff; return riff;
} }
@ -50,7 +54,24 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
size = GST_BUFFER_SIZE(buf); size = GST_BUFFER_SIZE(buf);
last = off + size; 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) { if (off == 0) {
gulong *words = (gulong *)GST_BUFFER_DATA(buf); 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 we have an incomplete chunk from the previous buffer
if (riff->incomplete_chunk) { if (riff->incomplete_chunk) {
guint leftover; 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; leftover = riff->incomplete_chunk->size - riff->incomplete_chunk_size;
if (leftover <= 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); memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), leftover);
if (riff->new_tag_found) { if (riff->new_tag_found) {
@ -91,22 +112,34 @@ gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
riff->incomplete_chunk = NULL; riff->incomplete_chunk = NULL;
} }
else { 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); memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), size);
riff->incomplete_chunk_size += size; riff->incomplete_chunk_size += size;
return 0; 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 */ /* 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 ); gulong *words = (gulong *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely - off );
// loop over all of the chunks to check which one is finished // loop over all of the chunks to check which one is finished
while (riff->chunks) { while (riff->chunks) {
chunk = g_list_nth_data(riff->chunks, 0); 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) { if (riff->nextlikely >= chunk->offset+chunk->size) {
//g_print("found END LIST\n"); //g_print("found END LIST\n");
// we have the end of the chunk on the stack, remove it // 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; 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)); chunk = (GstRiffChunk *)g_malloc(sizeof(GstRiffChunk));
g_return_val_if_fail(chunk != NULL, GST_RIFF_ENOMEM); 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 { else {
//g_print("chunk id offset %08x is 0x%08lx '%s' and is 0x%08lx long\n",riff->nextlikely, words[0], 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]); gst_riff_id_to_fourcc(words[0]),words[1]);
riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */ riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */
// if this buffer is incomplete // if this buffer is incomplete
if (riff->nextlikely > last) { 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); //g_print("make incomplete buffer %08x\n", left);
chunk->data = g_malloc(chunk->size); chunk->data = g_malloc(chunk->size);

View file

@ -293,6 +293,9 @@ struct _GstRiff {
gint state; gint state;
guint32 curoffset; guint32 curoffset;
guint32 nextlikely; guint32 nextlikely;
/* leftover data */
guchar *dataleft;
guint32 dataleft_size;
/* callback function and data pointer */ /* callback function and data pointer */
GstRiffCallback new_tag_found; GstRiffCallback new_tag_found;