diff options
author | Andy Wingo <wingo@pobox.com> | 2001-12-22 23:26:33 +0000 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2001-12-22 23:26:33 +0000 |
commit | ad6ed7da2d0d15eecc924dfe408320652481e885 (patch) | |
tree | 5adb0cfc1d7b419d6b4246f616400dca7678bac0 /gst/flx | |
parent | e5d9d6e2a512540848f5d38e01b9678a1ef5c761 (diff) | |
download | gst-plugins-bad-ad6ed7da2d0d15eecc924dfe408320652481e885.tar.gz gst-plugins-bad-ad6ed7da2d0d15eecc924dfe408320652481e885.tar.bz2 gst-plugins-bad-ad6ed7da2d0d15eecc924dfe408320652481e885.zip |
Initial revision
Original commit message from CVS:
Initial revision
Diffstat (limited to 'gst/flx')
-rw-r--r-- | gst/flx/Makefile.am | 9 | ||||
-rw-r--r-- | gst/flx/flx_color.c | 94 | ||||
-rw-r--r-- | gst/flx/flx_color.h | 43 | ||||
-rw-r--r-- | gst/flx/flx_fmt.h | 136 | ||||
-rw-r--r-- | gst/flx/gstflxdec.c | 644 | ||||
-rw-r--r-- | gst/flx/gstflxdec.h | 79 |
6 files changed, 1005 insertions, 0 deletions
diff --git a/gst/flx/Makefile.am b/gst/flx/Makefile.am new file mode 100644 index 00000000..79a6fba7 --- /dev/null +++ b/gst/flx/Makefile.am @@ -0,0 +1,9 @@ +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libgstflxdec.la + +libgstflxdec_la_SOURCES = gstflxdec.c flx_color.c +libgstflxdec_la_CFLAGS = $(GST_CFLAGS) + +noinst_HEADERS = flx_fmt.h flx_color.h gstflxdec.h + diff --git a/gst/flx/flx_color.c b/gst/flx/flx_color.c new file mode 100644 index 00000000..c61052d0 --- /dev/null +++ b/gst/flx/flx_color.c @@ -0,0 +1,94 @@ +/* Gnome-Streamer + * 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 <string.h> +#include <gst/gst.h> + + +#include "flx_color.h" + +FlxColorSpaceConverter * +flx_colorspace_converter_new(gint width, gint height) +{ + FlxColorSpaceConverter *new = g_malloc(sizeof(FlxColorSpaceConverter)); + + new->width = width; + new->height = height; + + memset(new->palvec, 0, sizeof(new->palvec)); + return new; +} + +void +flx_colorspace_converter_destroy(FlxColorSpaceConverter *flxpal) +{ + g_return_if_fail(flxpal != NULL); + + g_free(flxpal); +} + +void +flx_colorspace_convert(FlxColorSpaceConverter *flxpal, guchar *src, guchar *dest) +{ + guint size, col; + + g_return_if_fail(flxpal != NULL); + g_return_if_fail(src != dest); + + + size = flxpal->width * flxpal->height; + + while(size--) { + col = (*src++ * 3); + *dest++ = flxpal->palvec[col+2]; + *dest++ = flxpal->palvec[col+1]; + *dest++ = flxpal->palvec[col]; + *dest++ = 0; + } + +} + + +void +flx_set_palette_vector(FlxColorSpaceConverter *flxpal, guint start, guint num, guchar *newpal) +{ + guint grab; + + g_return_if_fail(flxpal != NULL); + g_return_if_fail(start < 0x100); + + grab = ((start + num) > 0x100 ? 0x100 - start : num); + + memcpy(&flxpal->palvec[start * 3], newpal, grab*3); + +} + +void +flx_set_color(FlxColorSpaceConverter *flxpal, guint colr, guint red, guint green, guint blue) +{ + + g_return_if_fail(flxpal != NULL); + g_return_if_fail(colr < 0x100); + + flxpal->palvec[(colr * 3)] = red; + flxpal->palvec[(colr * 3) + 1] = green; + flxpal->palvec[(colr * 3) + 2] = blue; +} + + diff --git a/gst/flx/flx_color.h b/gst/flx/flx_color.h new file mode 100644 index 00000000..5676c878 --- /dev/null +++ b/gst/flx/flx_color.h @@ -0,0 +1,43 @@ +/* Gnome-Streamer + * 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. + */ + +typedef enum { + FLX_COLORSPACE_RGB8, + FLX_COLORSPACE_RGB32, +} FlxColorSpaceType; + + +typedef struct _FlxColorSpaceConverter FlxColorSpaceConverter; + +struct _FlxColorSpaceConverter { + guint width; + guint height; + guchar palvec[768]; +}; + + +void flx_colorspace_converter_destroy(FlxColorSpaceConverter *flxpal); +void flx_colorspace_convert(FlxColorSpaceConverter *flxpal, guchar *src, guchar *dest); +FlxColorSpaceConverter * flx_colorspace_converter_new(gint width, gint height); + +void flx_set_palette_vector(FlxColorSpaceConverter *flxpal, guint start, guint num, + guchar *newpal); +void flx_set_color(FlxColorSpaceConverter *flxpal, guint colr, guint red, guint green, + guint blue); + diff --git a/gst/flx/flx_fmt.h b/gst/flx/flx_fmt.h new file mode 100644 index 00000000..5323de63 --- /dev/null +++ b/gst/flx/flx_fmt.h @@ -0,0 +1,136 @@ +/* Gnome-Streamer + * 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_FLX_FMT__H__ +#define __GST_FLX_FMT_H__ + +#include <gst/gst.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum Flx_TypeChunk +{ + /* frame chunks */ + FLX_PREFIX_TYPE = 0xf100, + FLX_SCRIPT_CHUNK = 0xf1e0, + FLX_FRAME_TYPE = 0xf1fa, + FLX_SEGMENT_TABLE = 0xf1fb, + FLX_HUFFMAN_TABLE = 0xf1fc, + + /* sub chunks */ + FLX_CEL_DATA = 3, + FLX_COLOR256 = 4, + FLX_SS2 = 7, + FLX_COLOR64 = 11, + FLX_LC = 12, + FLX_BLACK = 13, + FLX_BRUN = 15, + FLX_COPY = 16, + FLX_MINI = 18, + FLX_DTA_RUN = 25, + FLX_DTA_COPY = 26, + FLX_DTA_LC = 27, + FLX_LABEL = 31, + FLX_BMP_MASK = 32, + FLX_MLEV_MASK = 33, + FLX_SEGMENT = 34, + FLX_KEY_IMAGE = 35, + FLX_KEY_PAL = 36, + FLX_REGION = 37, + FLX_WAVE = 38, + FLX_USERSTRING = 39, + FLX_RGN_MASK = 40, + +}; + +enum Flx_MagicHdr +{ + FLX_MAGICHDR_FLI = 0xaf11, + FLX_MAGICHDR_FLC = 0xaf12, + FLX_MAGICHDR_FLX = 0xaf44, + FLX_MAGICHDR_HUFFBWT = 0xaf30, +}; + + + +typedef struct _FlxHeader +{ + guint32 size; + guint16 type; + guint16 frames; + guint16 width,height,depth,flags; + guint32 speed; + guint16 reserved1; + /* FLC */ + guint32 created,creator,updated,updater; + guint16 aspect_dx, aspect_dy; + /* EGI */ + guint16 ext_flags,keyframes,totalframes; + guint32 req_memory; + guint16 max_regions,transp_num; + guchar reserved2[24]; + /* FLC */ + guint32 oframe1,oframe2; + guchar reserved3[40]; +} FlxHeader; +#define FlxHeaderSize 128 + +typedef struct _FlxFrameChunk +{ + guint32 size; + guint16 id; +} FlxFrameChunk; +#define FlxFrameChunkSize 6 + +typedef struct _FlxPrefixChunk +{ + guint16 chunks; + guchar reserved[8]; +} FlxPrefixChunk; + +typedef struct _FlxSegmentTable +{ + guint16 segments; +} FlxSegmentTable; + +typedef struct _FlxHuffmanTable +{ + guint16 codelength; + guint16 numcodes; + guchar reserved[6]; +} FlxHuffmanTable; + +typedef struct _FlxFrameType +{ + guint16 chunks; + guint16 delay; + guchar reserved[6]; +} FlxFrameType; +#define FlxFrameTypeSize 10 + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_FLX_FMT_H__ */ diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c new file mode 100644 index 00000000..d6052bb6 --- /dev/null +++ b/gst/flx/gstflxdec.c @@ -0,0 +1,644 @@ +/* Gnome-Streamer + * 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 <string.h> + +#include "flx_fmt.h" +#include "gstflxdec.h" + +static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private); + +/* flx element information */ +static GstElementDetails flxdec_details = { + "FLX Decoder", + "flxdec", + "FLX decoder", + VERSION, + "Sepp Wijnands <mrrazz@garbage-coderz.net>" + "(C) 2001", +}; + +static GstTypeDefinition flxdec_definition = { + "flxdec_video/fli", + "video/fli", + ".flc .fli", + flxdec_typefind, +}; + +/* Flx signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0 +}; + +/* input */ +GST_PADTEMPLATE_FACTORY (sink_factory, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "flxdec_sink", + "video/fli", + NULL + ) +) + +/* output */ +GST_PADTEMPLATE_FACTORY (src_video_factory, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "src_video", + "video/raw", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')), + "bpp", GST_PROPS_INT (32), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN), + "red_mask", GST_PROPS_INT (0x00ff0000), + "green_mask", GST_PROPS_INT (0x0000ff00), + "blue_mask", GST_PROPS_INT (0x000000ff), + "width", GST_PROPS_INT_RANGE(320, 1280), + "height", GST_PROPS_INT_RANGE(200, 1024) + ) +) + + +static void gst_flxdec_class_init (GstFlxDecClass *klass); +static void gst_flxdec_init (GstFlxDec *flxdec); + +static void gst_flxdec_loop (GstElement *element); + +static void gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + + +static void flx_decode_color(GstFlxDec *, guchar *, guchar *); +static void flx_decode_brun(GstFlxDec *, guchar *, guchar *); +static void flx_decode_delta_fli(GstFlxDec *, guchar *, guchar *); +static void flx_decode_delta_flc(GstFlxDec *, guchar *, guchar *); + +#define rndalign(off) ((off) + ((off) % 2)) + +static GstElementClass *parent_class = NULL; + +static GstCaps* +flxdec_typefind (GstBuffer *buf, gpointer private) +{ + guchar *data = GST_BUFFER_DATA(buf); + GstCaps *new; + + // check magic + if ((data[4] == 0x11 || data[4] == 0x12 + || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) { + // check the frame type of the first frame + if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) { + g_print("GstFlxDec: found supported flx format\n"); + new = gst_caps_new("flxdec_typefind","video/fli", NULL); + return new; + } + } + + return NULL; +} + + +GType +gst_flxdec_get_type(void) +{ + static GType flxdec_type = 0; + + if (!flxdec_type) { + static const GTypeInfo flxdec_info = { + sizeof(GstFlxDecClass), NULL, + NULL, + (GClassInitFunc)gst_flxdec_class_init, + NULL, + NULL, + sizeof(GstFlxDec), + 0, + (GInstanceInitFunc)gst_flxdec_init, + }; + flxdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstFlxDec", &flxdec_info, 0); + } + return flxdec_type; +} + +static void +gst_flxdec_class_init (GstFlxDecClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + + gobject_class->set_property = NULL; + gobject_class->get_property = NULL; + +} + + + +static void +gst_flxdec_init(GstFlxDec *flxdec) +{ + flxdec->sinkpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (sink_factory), "sink"); + gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->sinkpad); + gst_element_set_loop_function(GST_ELEMENT(flxdec),gst_flxdec_loop); + + flxdec->srcpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (src_video_factory), "src"); + gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad); + + flxdec->buf = NULL; + flxdec->offset = 0; + flxdec->new_buf = TRUE; + +} + +static void +flx_decode_chunks (GstFlxDec *flxdec , gulong count, gchar *data, gchar *dest) +{ + FlxFrameChunk *hdr; + + g_return_if_fail(data != NULL); + + while (count--) { + hdr = (FlxFrameChunk *) data; + data += FlxFrameChunkSize; + + switch(hdr->id) + { + case FLX_COLOR64: + case FLX_COLOR256: + flx_decode_color(flxdec, data, dest); + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + + case FLX_BRUN: + flx_decode_brun(flxdec, data, dest); + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + + case FLX_LC: + flx_decode_delta_fli(flxdec, data, dest); + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + + case FLX_SS2: + flx_decode_delta_flc(flxdec, data, dest); + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + + case FLX_BLACK: + memset(dest, 0, flxdec->size); + break; + + case FLX_MINI: + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + + default: + g_print("GstFlxDec: Unimplented chunk type: 0x%02x size: %d\n", + hdr->id, hdr->size); + g_print("GstFlxDec: Skipping...\n"); + data += rndalign(hdr->size) - FlxFrameChunkSize; + break; + } + } +} + + +static void +flx_decode_color(GstFlxDec *flxdec, guchar *data, guchar *dest) +{ + guint packs, count, indx; + + g_return_if_fail(flxdec != NULL); + + packs = (data[0] + (data[1] << 8)); + + data += 2; + indx = 0; + + g_print("GstFlxDec: cmap packs: %d\n", packs); + while (packs--) { + /* color map index + skip count */ + indx += *data++; + + /* number of rgb triplets */ + count = *data++ & 0xff; + if (count == 0) + count = 256; + + g_print("GstFlxDec: cmap count: %d (indx: %d)\n", count, indx); + flx_set_palette_vector(flxdec->converter, indx, count, data); + + data += (count * 3); + } +} + +static void +flx_decode_brun(GstFlxDec *flxdec, guchar *data, guchar *dest) +{ + gulong count, lines, row; + guchar x; + + g_return_if_fail(flxdec != NULL); + + lines = flxdec->hdr.height; + while(lines--) { + /* packet count. + * should not be used anymore, since the flc format can + * contain more then 255 RLE packets. we use the frame + * width instead. + */ + data++; + + row = flxdec->hdr.width; + while(row) { + count = *data++; + + if (count > 0x7f) { + /* literal run */ + count = 0x100 - count; + row -= count; + + while(count--) + *dest++ = *data++; + + } else { + /* replicate run */ + row -= count; + x = *data++; + + while(count--) + *dest++ = x; + } + } + } +} + +static void +flx_decode_delta_fli(GstFlxDec *flxdec, guchar *data, guchar *dest) +{ + gulong count, packets, lines, start_line, start_l; + guchar *start_p, x; + + g_return_if_fail(flxdec != NULL); + g_return_if_fail(flxdec->delta != NULL); + + + /* use last frame for delta */ + memcpy(dest, GST_BUFFER_DATA(flxdec->delta), + GST_BUFFER_SIZE(flxdec->delta)); + + start_line = (data[0] + (data[1] << 8)); + lines = (data[2] + (data[3] << 8)); + data += 4; + + /* start position of delta */ + dest += (flxdec->hdr.width * start_line); + start_p = dest; + start_l = lines; + + while(lines--) { + /* packet count */ + packets = *data++; + + dest = start_p + (flxdec->hdr.width * (start_l - lines)); + + while(packets--) { + /* skip count */ + dest += *data++; + + /* RLE count */ + count = *data++; + + if (count > 0x7f) { + /* literal run */ + count = 0x100 - count; + x = *data++; + + while (count--) + *dest++ = x; + + } else { + /* replicate run */ + while (count--) + *dest++ = *data++; + } + } + } +} + +static void +flx_decode_delta_flc(GstFlxDec *flxdec, guchar *data, guchar *dest) +{ + gulong count, lines, start_l, opcode; + guchar *start_p; + + g_return_if_fail(flxdec != NULL); + g_return_if_fail(flxdec->delta != NULL); + + + /* use last frame for delta */ + memcpy(dest, GST_BUFFER_DATA(flxdec->delta), + GST_BUFFER_SIZE(flxdec->delta)); + + lines = (data[0] + (data[1] << 8)); + data += 2; + + start_p = dest; + start_l = lines; + + while(lines--) { + dest = start_p + (flxdec->hdr.width * (start_l - lines)); + + /* process opcode(s) */ + while ((opcode = (data[0] + (data[1] << 8))) & 0xc000) { + data += 2; + if ((opcode & 0xc000) == 0xc000) { + /* skip count */ + start_l += (0x10000 - opcode); + dest += flxdec->hdr.width * (0x10000 - opcode); + } else { + /* last pixel */ + dest += flxdec->hdr.width; + *dest++ = (opcode & 0xff); + } + } + data += 2; + + /* last opcode is the packet count */ + while(opcode--) { + /* skip count */ + dest += *data++; + + /* RLE count */ + count = *data++; + + if (count > 0x7f) { + /* replicate word run */ + count = 0x100 - count; + while (count--) { + *dest++ = data[0]; + *dest++ = data[1]; + } + data += 2; + } else { + /* literal word run */ + while (count--) { + *dest++ = *data++; + *dest++ = *data++; + } + } + } + } +} + +static GstBuffer* +flx_get_data(GstFlxDec *flxdec, gulong size) +{ + GstBuffer *retbuf; + + g_return_val_if_fail (flxdec != NULL, NULL); + + if (flxdec->new_buf) { + retbuf = gst_pad_pullregion(flxdec->sinkpad, + GST_REGION_OFFSET_LEN, 0, size); + flxdec->new_buf = FALSE; + flxdec->offset = size; + } else { + retbuf = gst_pad_pullregion(flxdec->sinkpad, GST_REGION_OFFSET_LEN, + flxdec->offset, size); + flxdec->offset += size; + } + + return retbuf; +} + + +static void +gst_flxdec_loop (GstElement *element) +{ + GstBuffer *buf; + GstBuffer *databuf; + guchar *data, *chunk; + + GstFlxDec *flxdec; + FlxHeader *flxh; + FlxFrameChunk *flxfh; + + g_return_if_fail (element != NULL); + g_return_if_fail (GST_IS_FLXDEC(element)); + + GST_DEBUG (0, "entering loop function\n"); + + flxdec = GST_FLXDEC(element); + + databuf = flx_get_data(flxdec, FlxHeaderSize); + + g_return_if_fail (databuf != NULL); + + data = GST_BUFFER_DATA(databuf); + + memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader)); + + gst_buffer_unref (databuf); + + flxh = &flxdec->hdr; + + // check header + if (flxh->type != FLX_MAGICHDR_FLI && + flxh->type != FLX_MAGICHDR_FLC && + flxh->type != FLX_MAGICHDR_FLX) + return; + + + g_print("GstFlxDec: size : %d\n", flxh->size); + g_print("GstFlxDec: frames : %d\n", flxh->frames); + g_print("GstFlxDec: width : %d\n", flxh->width); + g_print("GstFlxDec: height : %d\n", flxh->height); + g_print("GstFlxDec: depth : %d\n", flxh->depth); + g_print("GstFlxDec: speed : %d\n", flxh->speed); + + gst_pad_set_caps (flxdec->srcpad, + gst_caps_new ( + "src_video", + "video/raw", + gst_props_new ( + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')), + "bpp", GST_PROPS_INT (32), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN), + "red_mask", GST_PROPS_INT (0x00ff0000), + "green_mask", GST_PROPS_INT (0x0000ff00), + "blue_mask", GST_PROPS_INT (0x000000ff), + "width", GST_PROPS_INT (flxh->width), + "height", GST_PROPS_INT (flxh->height), + NULL))); + + if (flxh->depth <= 8) + flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height); + + if (flxh->type == FLX_MAGICHDR_FLC || + flxh->type == FLX_MAGICHDR_FLX) { + g_print("GstFlxDec: (FLC) aspect_dx : %d\n", + flxh->aspect_dx); + g_print("GstFlxDec: (FLC) aspect_dy : %d\n", + flxh->aspect_dy); + g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n", + flxh->oframe1); + g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n", + flxh->oframe2); + } + + + flxdec->size = (flxh->width * flxh->height); + + // create delta and output frame + flxdec->frame = gst_buffer_new(); + flxdec->delta = gst_buffer_new(); + GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size); + GST_BUFFER_SIZE(flxdec->frame) = flxdec->size; + GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size); + GST_BUFFER_SIZE(flxdec->delta) = flxdec->size; + + do + { + + databuf = flx_get_data(flxdec, FlxFrameChunkSize); + + flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf); + + switch(flxfh->id) + { + case FLX_FRAME_TYPE: + buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize); + + chunk = GST_BUFFER_DATA(buf); + + if (((FlxFrameType *)chunk)->chunks == 0) + break; + + // create 32 bits output frame + flxdec->out = gst_buffer_new(); + GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4); + GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4; + + + // decode chunks + flx_decode_chunks(flxdec, + ((FlxFrameType *)chunk)->chunks, + GST_BUFFER_DATA(buf) + FlxFrameTypeSize, + GST_BUFFER_DATA(flxdec->frame)); + + // destroy input buffer + gst_buffer_unref(buf); + + // save copy of the current frame for possible delta. + memcpy(GST_BUFFER_DATA(flxdec->delta), + GST_BUFFER_DATA(flxdec->frame), + GST_BUFFER_SIZE(flxdec->delta)); + + // convert current frame. + flx_colorspace_convert(flxdec->converter, + GST_BUFFER_DATA(flxdec->frame), + GST_BUFFER_DATA(flxdec->out)); + + //GST_BUFFER_FLAG_SET(flxdec->out, GST_BUFFER_FLUSH); + gst_pad_push(flxdec->srcpad, flxdec->out); + + break; + } + + // destroy header buffer + gst_buffer_unref(databuf); + + } + while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); + +} + +static void +gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstFlxDec *flxdec; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_FLXDEC(object)); + flxdec = GST_FLXDEC(object); + + switch (prop_id) { + default: + break; + } +} + +static void +gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstFlxDec *flxdec; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_FLXDEC(object)); + flxdec = GST_FLXDEC(object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + GstTypeFactory *type; + + factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory)); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_video_factory)); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + type = gst_typefactory_new (&flxdec_definition); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "flxdec", + plugin_init +}; diff --git a/gst/flx/gstflxdec.h b/gst/flx/gstflxdec.h new file mode 100644 index 00000000..cc4c94db --- /dev/null +++ b/gst/flx/gstflxdec.h @@ -0,0 +1,79 @@ +/* Gnome-Streamer + * 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_FLX_DECODER_H__ +#define __GST_FLX_DECODER_H__ + +#include <gst/gst.h> + +#include "flx_color.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Definition of structure storing data for this element. */ +typedef struct _GstFlxDec GstFlxDec; +struct _GstFlxDec { + GstElement element; + + GstPad *sinkpad,*srcpad; + + gboolean active, new_meta, new_buf; + + GstBuffer *buf, *out, *delta, *frame; + gulong offset, size; + + FlxColorSpaceConverter *converter; + + FlxHeader hdr; +}; + +/* Standard definition defining a class for this element. */ +typedef struct _GstFlxDecClass GstFlxDecClass; +struct _GstFlxDecClass { + GstElementClass parent_class; +}; + +/* Standard macros for defining types for this element. */ +#define GST_TYPE_FLXDEC \ + (gst_flxdec_get_type()) +#define GST_FLXDEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FLXDEC,GstFlxDec)) +#define GST_FLXDEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FLXDEC,GstFlxDec)) +#define GST_IS_FLXDEC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FLXDEC)) +#define GST_IS_FLXDEC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC)) + +#define FLXDEC_BUFSIZE(buf, offset) \ + ((GST_BUFFER_OFFSET(buf) + GST_BUFFER_SIZE(buf)) - offset) + +/* Standard function returning type information. */ +GType gst_flxdec_get_type(void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_FLX_DECODER_H__ */ |