mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 17:51:16 +00:00
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:
parent
7cf6883096
commit
53b9cea328
6 changed files with 53 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue