diff --git a/configure.ac b/configure.ac index 9c98bfb7d3..8c37a81449 100644 --- a/configure.ac +++ b/configure.ac @@ -1443,17 +1443,6 @@ AG_GST_CHECK_FEATURE(SWFDEC, [swfdec plug-in], swfdec, [ AC_SUBST(SWFDEC_LIBS) ]) -dnl *** theora *** -translit(dnm, m, l) AM_CONDITIONAL(USE_THEORADEC, true) -AG_GST_CHECK_FEATURE(THEORADEC, [ogg theora codec], theoraexpdec, [ - PKG_CHECK_MODULES(THEORADEC, theoradec, HAVE_THEORADEC="yes", [ - HAVE_THEORADEC="no" - AC_MSG_RESULT(no) - ]) - AC_SUBST(THEORADEC_LIBS) - AC_SUBST(THEORADEC_CFLAGS) -]) - dnl *** XVID *** translit(dnm, m, l) AM_CONDITIONAL(USE_XVID, true) AG_GST_CHECK_FEATURE(XVID, [xvid plugins], xvid, [ @@ -1898,7 +1887,6 @@ ext/gsettings/Makefile ext/gsettings/org.freedesktop.gstreamer.default-elements.gschema.xml ext/spc/Makefile ext/swfdec/Makefile -ext/theora/Makefile ext/timidity/Makefile ext/vp8/Makefile ext/xvid/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index 142ce1d3a1..552926f06d 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -324,18 +324,6 @@ else SWFDEC_DIR= endif -if USE_THEORADEC -#THEORA_DIR = theora -else -THEORA_DIR = -endif - -# if USE_TARKIN -# TARKIN_DIR=tarkin -# else -TARKIN_DIR= -# endif - if USE_VP8 VP8_DIR=vp8 else @@ -480,7 +468,6 @@ DIST_SUBDIRS = \ spc \ gme \ swfdec \ - theora \ timidity \ vp8 \ xvid \ diff --git a/ext/tarkin/Makefile.am b/ext/tarkin/Makefile.am deleted file mode 100644 index 7bc190908a..0000000000 --- a/ext/tarkin/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ - -plugin_LTLIBRARIES = libgsttarkin.la - -libgsttarkin_la_SOURCES = tarkin.c \ - mem.c wavelet.c wavelet_xform.c \ - wavelet_coeff.c yuv.c info.c \ - gsttarkin.c gsttarkinenc.c gsttarkindec.c - -libgsttarkin_la_CFLAGS = $(GST_CFLAGS) $(VORBIS_CFLAGS) -DTYPE_BITS=10 -DTYPE=int16_t -DRLECODER -## AM_PATH_VORBIS also sets VORBISENC_LIBS -libgsttarkin_la_LIBADD = $(VORBIS_LIBS) $(VORBISENC_LIBS) -libgsttarkin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgsttarkin_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = gsttarkinenc.h mem.h tarkin.h yuv.h wavelet.h diff --git a/ext/tarkin/README b/ext/tarkin/README deleted file mode 100644 index ee91356d1a..0000000000 --- a/ext/tarkin/README +++ /dev/null @@ -1,8 +0,0 @@ -This is a video codec based on an integer wavelet in 3 dimensions (x, -y, and time/frame). What documentation exists so far is on the -vorbis-dev and (now) tarkin-dev mailing lists at xiph.org. Some brief -documentation can be found in the w3d/docs directory. - -For sample / test streams, see http://media.xiph.org/ -(and feel free to submit more streams if you have them). - diff --git a/ext/tarkin/TODO b/ext/tarkin/TODO deleted file mode 100644 index 909d377168..0000000000 --- a/ext/tarkin/TODO +++ /dev/null @@ -1,42 +0,0 @@ - - -Most important things: - - - the entropy coder, replace static huffman - - clean up the pnsr tools - - write docs and do some performance analysis, compare to other codecs - - think about a multiresolution multidimensional motion flow detection scheme, - Marco posted a good paper comparing different algorithms to do this - - -Open bugs and stuff required to fix them: - - - wavelet xform bug at short rows, see workaround in wavelet_xform.c - - (4,x) and (x,4) wavelet implementations have a bug which causes round-off - errors in the two least significand bits - - -Wavelet-related TODO's: - - - remove unecessairy copying in inverse xform - - improve truncation table setup - - try other approaches to encode coefficients, jack was talking about VQ - and reuse vorbis code - - write avitotarkin/quicktimetotarkin/mpegtotarkin/player/recorder - (a libsndfile/libaudiofile/libao alike video library would be great !) - - profile - - add special transform functions for large strides to prevent cache misses - - mmx/3dnow/sse/altivec - - -Other: - - - u and v buffers could get quarter size already at color conversion - this would speed up the whole algorithm; perhaps this should get - configurable - - fast internal 16bitY/U/V->15/16bitRGB for display could make sense - - the wavelet codec could be used for still image compression too - (we just have to define a file format with all goodies you can imagine;) - - to make it perfect someone has to write a good bilevel compressor and - mask seperation algorithm - diff --git a/ext/tarkin/WHAT_THE_HECK_IS_THIS_CODE_DOING b/ext/tarkin/WHAT_THE_HECK_IS_THIS_CODE_DOING deleted file mode 100644 index 4660260582..0000000000 --- a/ext/tarkin/WHAT_THE_HECK_IS_THIS_CODE_DOING +++ /dev/null @@ -1,61 +0,0 @@ - -This is deprecated. Take a look in the w3d/docs directory. - -The command line semantics are changed. You have to call the test program -now like this: - -./tarkin_enc ../clips/venuscubes-ppm/AnimSpace00%03d.ppm 5000 4 4 -./tarkin_dec - ------------------------------------------------------------------------------- - -Hi, - -this is a experimental 3d-integer-wavelet-video compression codec. Since the -integer wavelet transform is reversible and a reversible rgb-yuv conversion -is used (you can understand it as (1,2) integer wavelet transform, too), this -codec should be lossless if you transmit the whole bitstream. -The Y/U/V-bitstreams are embedded, thus you can simply get lossy compression -and shape the used bandwith by cutting bitstreams, when a user defined limit -is reached. - - -Here is how the current code works: - -First we grab a block of N_FRAMES frames (defined in main.c) of .ppm files. -Then each pixel becomes transformed into a YUV-alike colorspace. Take a look in -yuv.c to see how it is done. Each component is then transformed into frequency -space by applying the wavelet transform in x, y and frame direction. -The frame-direction transform is our high-order 'motion compensation'. -At boundaries we use (1,1)-Wavelets (== HAAR transform), inside the image -(2,2)-Wavelets. (4,4)-Wavelets should be easy to add. See wavelet.c for details. - -The resulting coefficients are scanned bitplane by bitplane and -runlength-encoded. Runlengths are Huffman-compressed and written into the -bitstreams. The bitplanes of higher-frequency scales are offset'ed to ensure a -fast transmission of high-energy-low-frequency coefficients. (coder.c) -The huffman coder is quite simple and uses a hardcoded table, this can be done -much better, but I wanted to get it working fast. - -Decompression works exactly like compression but in reversed direction. - -The test program writes for each frame the grabbed original image, the y/u/v -component (may look strange, since u/v can be negative and are not clamped to -the [0:255] range), the coefficients (look much more like usual wavelet -coefficients if you add 128 to each pixel), the coefficients after they are -runlength/huffman encoded and decoded, the y/u/v components when inverse wavelet -transform is done and the output image in .ppm format. - -You can call the test program like this: - - $ ./main 20000 5000 5000 ../clips/%i.ppm - -which means: images are grabbed from directory ../clips/0.ppm, ../clips/1.ppm, -etc. The Y component bitstream is limited to 20000 Bytes, the U and V bitstreams -to 5000 Bytes. If the last argument is omitted, frames are taken from current -directory. - -Good Luck, - -- Holger - diff --git a/ext/tarkin/bitcoder.h b/ext/tarkin/bitcoder.h deleted file mode 100644 index 312cd8871b..0000000000 --- a/ext/tarkin/bitcoder.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef __BITCODER_H -#define __BITCODER_H - -#include "mem.h" - -#if defined(BITCODER) - -#define OUTPUT_BIT(coder,bit) bitcoder_write_bit(coder,bit) -#define INPUT_BIT(coder) bitcoder_read_bit(coder) -#define OUTPUT_BIT_DIRECT(coder,bit) bitcoder_write_bit(coder,bit) -#define INPUT_BIT_DIRECT(coder) bitcoder_read_bit(coder) -#define ENTROPY_CODER BitCoderState -#define ENTROPY_ENCODER_init(coder,limit) bitcoder_coder_init(coder,limit) -#define ENTROPY_ENCODER_DONE(coder) bitcoder_encoder_done(coder) -#define ENTROPY_ENCODER_FLUSH(coder) bitcoder_flush(coder) -#define ENTROPY_DECODER_INIT(coder,bitstream,limit) \ - bitcoder_decoder_init(coder,bitstream,limit) -#define ENTROPY_DECODER_DONE(coder) /* nothing to do ... */ -#define ENTROPY_CODER_BITSTREAM(coder) (coder)->bitstream - -#define ENTROPY_CODER_SYMBOL(coder) 1 -#define ENTROPY_CODER_RUNLENGTH(coder) 0 -#define ENTROPY_CODER_SKIP(coder,skip) - -#endif - - -typedef struct { - int32_t bit_count; /* number of valid bits in byte */ - uint8_t byte; /* buffer to save bits */ - uint32_t byte_count; /* number of bytes written */ - uint8_t *bitstream; - uint32_t limit; /* don't write more bytes to bitstream ... */ - int eos; /* end of stream reached */ -} BitCoderState; - - - -static inline -void bitcoder_encoder_init (BitCoderState *s, uint32_t limit) -{ - s->bit_count = 0; - s->byte = 0; - s->byte_count = 0; - s->bitstream = (uint8_t*) MALLOC (limit); - s->limit = limit; - s->eos = 0; -} - - -static inline -void bitcoder_encoder_done (BitCoderState *s) -{ - FREE (s->bitstream); -} - - -static inline -void bitcoder_decoder_init (BitCoderState *s, uint8_t *bitstream, uint32_t limit) -{ - s->bit_count = -1; - s->byte = 0; - s->byte_count = 0; - s->bitstream = bitstream; - s->limit = limit; - s->eos = 0; -} - - -static inline -uint32_t bitcoder_flush (BitCoderState *s) -{ - if (s->bit_count > 0 && s->byte_count < s->limit) - s->bitstream [s->byte_count++] = s->byte << (8 - s->bit_count); - -/*printf ("%s: %i bytes written.\n", __FUNCTION__, s->byte_count); */ -/*printf ("%s: last bit %i\n", __FUNCTION__, s->bit_count); */ - return s->byte_count; -} - - - -static inline -void bitcoder_write_bit (BitCoderState *s, int bit) -{ - s->byte <<= 1; - s->byte |= bit & 1; - - s->bit_count++; - - if (s->bit_count == 8) { - if (s->byte_count < s->limit) { - s->bitstream [s->byte_count++] = s->byte; - s->bit_count = 0; - } else { - s->eos = 1; - } - } -} - - -static inline -int bitcoder_read_bit (BitCoderState *s) -{ - int ret; - - if (s->bit_count <= 0) { - if (!s->bitstream) { - s->eos = 1; - return 0; - } - - if (s->byte_count < s->limit) { - s->byte = s->bitstream [s->byte_count++]; - } else { - s->eos = 1; - s->byte = 0; - } - - s->bit_count = 8; - } - - ret = s->byte >> 7; - s->byte <<= 1; - s->bit_count--; - - return ret & 1; -} - - - - - - -static inline -void bit_print (TYPE byte) -{ - int bit = 8*sizeof(TYPE); - - do { - bit--; - printf ((byte & (1 << bit)) ? "1" : "0"); - } while (bit); - printf ("\n"); -} - -#endif - diff --git a/ext/tarkin/golomb.h b/ext/tarkin/golomb.h deleted file mode 100644 index 95e63c304f..0000000000 --- a/ext/tarkin/golomb.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef __GOLOMB_H -#define __GOLOMB_H - - -#include "bitcoder.h" - - -static inline -unsigned int required_bits (unsigned int x) -{ - int bits = 31; - - while ((x & (1 << bits)) == 0 && bits) - bits--; - - return bits; -} - - -static inline -void write_number_binary (BitCoderState *b, unsigned int x, int bits, int u) -{ -/*printf ("wrote %i with %i bits (%i+%i)\n", x, u+bits, u, bits); */ - while (bits) { - bits--; - bitcoder_write_bit (b, (x >> bits) & 1); - } -} - - -static inline -unsigned int read_number_binary (BitCoderState *b, int bits) -{ - unsigned int x = 0; - - while (bits) { - bits--; - x |= bitcoder_read_bit (b) << bits; - } - - return x; -} - - -static inline -void golomb_write_number (BitCoderState *b, unsigned int x, int bits) -{ - unsigned int q, r; -int i = 0; - - assert (x > 0); - - while ((q = (x - 1) >> bits) > 0) { - bitcoder_write_bit (b, 1); /* fast temporary adaption, write */ - bits++; /* unary representation of q */ -i++; - }; - - bitcoder_write_bit (b, 0); - - r = x - 1 - (q << bits); - - write_number_binary (b, r, bits, i+1); -} - - -static inline -unsigned int golomb_read_number (BitCoderState *b, int bits) -{ - unsigned int q = 0, r, x; - - while (bitcoder_read_bit (b) != 0) { - bits++; - } - - r = read_number_binary (b, bits); - x = (q << bits) + r + 1; - - return x; -} - - -typedef struct { - uint8_t count; - uint8_t bits; /* a 5.3 fixed point integer */ -} GolombAdaptiveCoderState; - -#define GOLOMB_ADAPTIVE_CODER_STATE_INITIALIZER { 8<<3, 0 } - - -static const int golomb_w_tab [] = { 256, 128, 64 }; - - - - -static inline -void golombcoder_encode_number (GolombAdaptiveCoderState *g, - BitCoderState *b, - unsigned int x) -{ - golomb_write_number (b, x, g->bits >> 3); - - g->bits = ((256 - golomb_w_tab[g->count]) * (int) g->bits + - golomb_w_tab[g->count] * (required_bits(x)<<3)) / 256; - g->count++; - - if (g->count > 2) - g->count = 2; -} - - -static inline -unsigned int golombcoder_decode_number (GolombAdaptiveCoderState *g, - BitCoderState *b) -{ - unsigned int x; - - x = golomb_read_number (b, g->bits >> 3); - - g->bits = ((256 - golomb_w_tab[g->count]) * g->bits + - golomb_w_tab[g->count] * (required_bits(x)<<3)) / 256; - g->count++; - - if (g->count > 2) - g->count = 2; - - return x; -} - - -#endif - diff --git a/ext/tarkin/gsttarkin.c b/ext/tarkin/gsttarkin.c deleted file mode 100644 index cfda4088d5..0000000000 --- a/ext/tarkin/gsttarkin.c +++ /dev/null @@ -1,45 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gsttarkinenc.h" -#include "gsttarkindec.h" - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "tarkinenc", GST_RANK_NONE, - GST_TYPE_TARKINENC)) - return FALSE; - - if (!gst_element_register (plugin, "tarkindec", GST_RANK_PRIMARY, - GST_TYPE_TARKINDEC)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "tarkin", - "Tarkin plugin library", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/tarkin/gsttarkindec.c b/ext/tarkin/gsttarkindec.c deleted file mode 100644 index f6b1e834c0..0000000000 --- a/ext/tarkin/gsttarkindec.c +++ /dev/null @@ -1,334 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include - -#include "gsttarkindec.h" - -static GstPadTemplate *dec_src_template, *dec_sink_template; - -/* TarkinDec signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_BITRATE -}; - -static void gst_tarkindec_base_init (gpointer g_class); -static void gst_tarkindec_class_init (TarkinDecClass * klass); -static void gst_tarkindec_init (TarkinDec * arkindec); - -static void gst_tarkindec_chain (GstPad * pad, GstData * _data); -static void gst_tarkindec_setup (TarkinDec * tarkindec); -static GstStateChangeReturn gst_tarkindec_change_state (GstElement * element, - GstStateChange transition); - -static void gst_tarkindec_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void gst_tarkindec_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static GstElementClass *parent_class = NULL; - -/*static guint gst_tarkindec_signals[LAST_SIGNAL] = { 0 }; */ - -GType -tarkindec_get_type (void) -{ - static GType tarkindec_type = 0; - - if (!tarkindec_type) { - static const GTypeInfo tarkindec_info = { - sizeof (TarkinDecClass), - gst_tarkindec_base_init, - NULL, - (GClassInitFunc) gst_tarkindec_class_init, - NULL, - NULL, - sizeof (TarkinDec), - 0, - (GInstanceInitFunc) gst_tarkindec_init, - }; - - tarkindec_type = - g_type_register_static (GST_TYPE_ELEMENT, "TarkinDec", &tarkindec_info, - 0); - } - return tarkindec_type; -} - -static GstCaps * -tarkin_caps_factory (void) -{ - return gst_caps_new ("tarkin_tarkin", "application/ogg", NULL); -} - -static GstCaps * -raw_caps_factory (void) -{ - return - GST_CAPS_NEW ("tarkin_raw", - "video/x-raw-rgb", - "bpp", GST_PROPS_INT (24), - "depth", GST_PROPS_INT (24), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "red_mask", GST_PROPS_INT (0xff0000), - "green_mask", GST_PROPS_INT (0xff00), - "blue_mask", GST_PROPS_INT (0xff), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT), - "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) - ); -} - -static void -gst_tarkindec_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstCaps *raw_caps, *tarkin_caps; - - raw_caps = raw_caps_factory (); - tarkin_caps = tarkin_caps_factory (); - - dec_sink_template = gst_pad_template_new ("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, tarkin_caps, NULL); - dec_src_template = gst_pad_template_new ("src", - GST_PAD_SRC, GST_PAD_ALWAYS, raw_caps, NULL); - gst_element_class_add_pad_template (element_class, dec_sink_template); - gst_element_class_add_pad_template (element_class, dec_src_template); - - gst_element_class_set_details_simple (element_class, "Tarkin video decoder", - "Codec/Decoder/Video", - "Decodes video in OGG Tarkin format", - "Monty , " "Wim Taymans "); -} - -static void -gst_tarkindec_class_init (TarkinDecClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, - g_param_spec_int ("bitrate", "bitrate", "bitrate", - G_MININT, G_MAXINT, 3000, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_tarkindec_set_property; - gobject_class->get_property = gst_tarkindec_get_property; - - gstelement_class->change_state = gst_tarkindec_change_state; -} - -static void -gst_tarkindec_init (TarkinDec * tarkindec) -{ - tarkindec->sinkpad = gst_pad_new_from_template (dec_sink_template, "sink"); - gst_element_add_pad (GST_ELEMENT (tarkindec), tarkindec->sinkpad); - gst_pad_set_chain_function (tarkindec->sinkpad, gst_tarkindec_chain); - - tarkindec->srcpad = gst_pad_new_from_template (dec_src_template, "src"); - gst_element_add_pad (GST_ELEMENT (tarkindec), tarkindec->srcpad); - - tarkindec->bitrate = 3000; - tarkindec->setup = FALSE; - tarkindec->nheader = 0; - - /* we're chained and we can deal with events */ - GST_OBJECT_FLAG_SET (tarkindec, GST_ELEMENT_EVENT_AWARE); -} - -static void -gst_tarkindec_setup (TarkinDec * tarkindec) -{ - tarkindec->tarkin_stream = tarkin_stream_new (); - - ogg_sync_init (&tarkindec->oy); - ogg_stream_init (&tarkindec->os, 1); - tarkin_info_init (&tarkindec->ti); - tarkin_comment_init (&tarkindec->tc); - - tarkindec->setup = TRUE; -} - -static void -gst_tarkindec_chain (GstPad * pad, GstData * _data) -{ - GstBuffer *buf = GST_BUFFER (_data); - TarkinDec *tarkindec; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - tarkindec = GST_TARKINDEC (gst_pad_get_parent (pad)); - - if (!tarkindec->setup) { - GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), - ("decoder not initialized (input is not tarkin?)")); - if (GST_IS_BUFFER (buf)) - gst_buffer_unref (buf); - else - gst_pad_event_default (pad, GST_EVENT (buf)); - return; - } - - if (GST_IS_EVENT (buf)) { - switch (GST_EVENT_TYPE (buf)) { - case GST_EVENT_EOS: - default: - gst_pad_event_default (pad, GST_EVENT (buf)); - break; - } - } else { - gchar *data; - gulong size; - gchar *buffer; - guchar *rgb; - TarkinTime date; - TarkinVideoLayerDesc *layer; - - /* data to decode */ - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); - - buffer = ogg_sync_buffer (&tarkindec->oy, size); - memcpy (buffer, data, size); - ogg_sync_wrote (&tarkindec->oy, size); - - if (ogg_sync_pageout (&tarkindec->oy, &tarkindec->og)) { - ogg_stream_pagein (&tarkindec->os, &tarkindec->og); - - while (ogg_stream_packetout (&tarkindec->os, &tarkindec->op)) { - if (tarkindec->op.e_o_s) - break; - if (tarkindec->nheader < 3) { /* 3 first packets to headerin */ - tarkin_synthesis_headerin (&tarkindec->ti, &tarkindec->tc, - &tarkindec->op); - - if (tarkindec->nheader == 2) { - tarkin_synthesis_init (tarkindec->tarkin_stream, &tarkindec->ti); - } - tarkindec->nheader++; - } else { - tarkin_synthesis_packetin (tarkindec->tarkin_stream, &tarkindec->op); - - while (tarkin_synthesis_frameout (tarkindec->tarkin_stream, &rgb, 0, - &date) == 0) { - GstBuffer *outbuf; - - layer = &tarkindec->tarkin_stream->layer->desc; - - if (!GST_PAD_CAPS (tarkindec->srcpad)) { - if (gst_pad_try_set_caps (tarkindec->srcpad, GST_CAPS_NEW ("tarkin_raw", "video/x-raw-rgb", "bpp", GST_PROPS_INT (24), "depth", GST_PROPS_INT (24), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "red_mask", GST_PROPS_INT (0xff0000), "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT (layer->width), "height", GST_PROPS_INT (layer->height), "framerate", GST_PROPS_FLOAT (0.) /* FIXME!!! */ - )) <= 0) { - GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), - ("could not output format")); - gst_buffer_unref (buf); - return; - } - } - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = rgb; - GST_BUFFER_SIZE (outbuf) = layer->width * layer->height * 3; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (tarkindec->srcpad, GST_DATA (outbuf)); - - tarkin_synthesis_freeframe (tarkindec->tarkin_stream, rgb); - } - } - } - } - gst_buffer_unref (buf); - } -} - -static GstStateChangeReturn -gst_tarkindec_change_state (GstElement * element, GstStateChange transition) -{ - TarkinDec *tarkindec; - - tarkindec = GST_TARKINDEC (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_tarkindec_setup (tarkindec); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - default: - break; - } - - return parent_class->change_state (element, transition); -} - -static void -gst_tarkindec_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - TarkinDec *tarkindec; - - g_return_if_fail (GST_IS_TARKINDEC (object)); - - tarkindec = GST_TARKINDEC (object); - - switch (prop_id) { - case ARG_BITRATE: - g_value_set_int (value, tarkindec->bitrate); - break; - default: - break; - } -} - -static void -gst_tarkindec_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - TarkinDec *tarkindec; - - g_return_if_fail (GST_IS_TARKINDEC (object)); - - tarkindec = GST_TARKINDEC (object); - - switch (prop_id) { - case ARG_BITRATE: - tarkindec->bitrate = g_value_get_int (value); - break; - default: - break; - } -} diff --git a/ext/tarkin/gsttarkindec.h b/ext/tarkin/gsttarkindec.h deleted file mode 100644 index 41e55a1bcc..0000000000 --- a/ext/tarkin/gsttarkindec.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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 __TARKINDEC_H__ -#define __TARKINDEC_H__ - - -#include - -#include "tarkin.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define GST_TYPE_TARKINDEC \ - (tarkindec_get_type()) -#define GST_TARKINDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TARKINDEC,TarkinDec)) -#define GST_TARKINDEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TARKINDEC,TarkinDecClass)) -#define GST_IS_TARKINDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TARKINDEC)) -#define GST_IS_TARKINDEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TARKINDEC)) - -typedef struct _TarkinDec TarkinDec; -typedef struct _TarkinDecClass TarkinDecClass; - -struct _TarkinDec { - GstElement element; - - GstPad *sinkpad,*srcpad; - - ogg_sync_state oy; - ogg_stream_state os; - ogg_page og; - ogg_packet op; - - TarkinStream *tarkin_stream; - TarkinComment tc; - TarkinInfo ti; - TarkinVideoLayerDesc layer[1]; - - gint frame_num; - gint nheader; - - gboolean eos; - gint bitrate; - gboolean setup; -}; - -struct _TarkinDecClass { - GstElementClass parent_class; -}; - -GType tarkindec_get_type(void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __TARKINDEC_H__ */ diff --git a/ext/tarkin/gsttarkinenc.c b/ext/tarkin/gsttarkinenc.c deleted file mode 100644 index 7390da3b8d..0000000000 --- a/ext/tarkin/gsttarkinenc.c +++ /dev/null @@ -1,414 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include - -#include "gsttarkinenc.h" - -static GstPadTemplate *enc_src_template, *enc_sink_template; - -/* TarkinEnc signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_BITRATE, - ARG_S_MOMENTS, - ARG_A_MOMENTS -}; - -static void gst_tarkinenc_base_init (gpointer g_class); -static void gst_tarkinenc_class_init (TarkinEncClass * klass); -static void gst_tarkinenc_init (TarkinEnc * arkinenc); - -static void gst_tarkinenc_chain (GstPad * pad, GstData * _data); -static void gst_tarkinenc_setup (TarkinEnc * tarkinenc); - -static void gst_tarkinenc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void gst_tarkinenc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static GstElementClass *parent_class = NULL; - -/*static guint gst_tarkinenc_signals[LAST_SIGNAL] = { 0 }; */ - -GType -tarkinenc_get_type (void) -{ - static GType tarkinenc_type = 0; - - if (!tarkinenc_type) { - static const GTypeInfo tarkinenc_info = { - sizeof (TarkinEncClass), - gst_tarkinenc_base_init, - NULL, - (GClassInitFunc) gst_tarkinenc_class_init, - NULL, - NULL, - sizeof (TarkinEnc), - 0, - (GInstanceInitFunc) gst_tarkinenc_init, - }; - - tarkinenc_type = - g_type_register_static (GST_TYPE_ELEMENT, "TarkinEnc", &tarkinenc_info, - 0); - } - return tarkinenc_type; -} - -static GstCaps * -tarkin_caps_factory (void) -{ - return gst_caps_new ("tarkin_tarkin", "application/ogg", NULL); -} - -static GstCaps * -raw_caps_factory (void) -{ - return - GST_CAPS_NEW ("tarkin_raw", - "video/x-raw-rgb", - "bpp", GST_PROPS_INT (24), - "depth", GST_PROPS_INT (24), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "red_mask", GST_PROPS_INT (0xff0000), - "green_mask", GST_PROPS_INT (0xff00), - "blue_mask", GST_PROPS_INT (0xff), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT), - "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) - ); -} - -static void -gst_tarkinenc_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstCaps *raw_caps, *tarkin_caps; - - raw_caps = raw_caps_factory (); - tarkin_caps = tarkin_caps_factory (); - - enc_sink_template = gst_pad_template_new ("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, raw_caps, NULL); - enc_src_template = gst_pad_template_new ("src", - GST_PAD_SRC, GST_PAD_ALWAYS, tarkin_caps, NULL); - gst_element_class_add_pad_template (element_class, enc_sink_template); - gst_element_class_add_pad_template (element_class, enc_src_template); - - gst_element_class_set_details_simple (element_class, "Tarkin video encoder", - "Codec/Encoder/Video", - "Encodes video in OGG Tarkin format", - "Monty , " "Wim Taymans "); -} - -static void -gst_tarkinenc_class_init (TarkinEncClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, - g_param_spec_int ("bitrate", "bitrate", "bitrate", - G_MININT, G_MAXINT, 3000, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_S_MOMENTS, - g_param_spec_int ("s-moments", "Synthesis Moments", - "Number of vanishing moments for the synthesis filter", - 1, 4, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_A_MOMENTS, - g_param_spec_int ("a-moments", "Analysis Moments", - "Number of vanishing moments for the analysis filter", - 1, 4, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_tarkinenc_set_property; - gobject_class->get_property = gst_tarkinenc_get_property; -} - -static GstPadLinkReturn -gst_tarkinenc_sinkconnect (GstPad * pad, GstCaps * caps) -{ - TarkinEnc *tarkinenc; - - tarkinenc = GST_TARKINENC (gst_pad_get_parent (pad)); - - if (!GST_CAPS_IS_FIXED (caps)) - return GST_PAD_LINK_DELAYED; - - gst_caps_debug (caps, "caps to be set on tarkin sink pad"); - - tarkinenc->layer[0].bitstream_len = tarkinenc->bitrate; - tarkinenc->layer[0].a_moments = tarkinenc->a_moments; - tarkinenc->layer[0].s_moments = tarkinenc->s_moments; - gst_caps_get_int (caps, "width", &tarkinenc->layer[0].width); - gst_caps_get_int (caps, "height", &tarkinenc->layer[0].height); - tarkinenc->layer[0].format = TARKIN_RGB24; - tarkinenc->layer[0].frames_per_buf = TARKIN_RGB24; - - gst_tarkinenc_setup (tarkinenc); - - if (tarkinenc->setup) - return GST_PAD_LINK_OK; - - return GST_PAD_LINK_REFUSED; -} - -static void -gst_tarkinenc_init (TarkinEnc * tarkinenc) -{ - tarkinenc->sinkpad = gst_pad_new_from_template (enc_sink_template, "sink"); - gst_element_add_pad (GST_ELEMENT (tarkinenc), tarkinenc->sinkpad); - gst_pad_set_chain_function (tarkinenc->sinkpad, gst_tarkinenc_chain); - gst_pad_set_link_function (tarkinenc->sinkpad, gst_tarkinenc_sinkconnect); - - tarkinenc->srcpad = gst_pad_new_from_template (enc_src_template, "src"); - gst_element_add_pad (GST_ELEMENT (tarkinenc), tarkinenc->srcpad); - - tarkinenc->bitrate = 3000; - tarkinenc->s_moments = 2; - tarkinenc->a_moments = 2; - tarkinenc->setup = FALSE; -} - -TarkinError -free_frame (void *s, void *ptr) -{ - return (TARKIN_OK); -} - -TarkinError -packet_out (void *stream, ogg_packet * op) -{ - ogg_page og; - TarkinStream *s = stream; - TarkinEnc *te = s->user_ptr; - GstBuffer *outbuf; - - ogg_stream_packetin (&te->os, op); - - if (op->e_o_s) { - ogg_stream_flush (&te->os, &og); - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = og.header; - GST_BUFFER_SIZE (outbuf) = og.header_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (te->srcpad, GST_DATA (outbuf)); - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = og.body; - GST_BUFFER_SIZE (outbuf) = og.body_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (te->srcpad, GST_DATA (outbuf)); - } else { - while (ogg_stream_pageout (&te->os, &og)) { - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = og.header; - GST_BUFFER_SIZE (outbuf) = og.header_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (te->srcpad, GST_DATA (outbuf)); - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = og.body; - GST_BUFFER_SIZE (outbuf) = og.body_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (te->srcpad, GST_DATA (outbuf)); - } - } - return (TARKIN_OK); -} - - -static void -gst_tarkinenc_setup (TarkinEnc * tarkinenc) -{ - gint i; - GstBuffer *outbuf; - - ogg_stream_init (&tarkinenc->os, 1); - tarkin_info_init (&tarkinenc->ti); - - tarkinenc->ti.inter.numerator = 1; - tarkinenc->ti.inter.denominator = 1; - - tarkin_comment_init (&tarkinenc->tc); - tarkin_comment_add_tag (&tarkinenc->tc, "TITLE", "GStreamer produced file"); - tarkin_comment_add_tag (&tarkinenc->tc, "ARTIST", "C coders ;)"); - - tarkinenc->tarkin_stream = tarkin_stream_new (); - tarkin_analysis_init (tarkinenc->tarkin_stream, - &tarkinenc->ti, free_frame, packet_out, (void *) tarkinenc); - tarkin_analysis_add_layer (tarkinenc->tarkin_stream, &tarkinenc->layer[0]); - - tarkin_analysis_headerout (tarkinenc->tarkin_stream, &tarkinenc->tc, - tarkinenc->op, &tarkinenc->op[1], &tarkinenc->op[2]); - for (i = 0; i < 3; i++) { - ogg_stream_packetin (&tarkinenc->os, &tarkinenc->op[i]); - } - - ogg_stream_flush (&tarkinenc->os, &tarkinenc->og); - - tarkinenc->frame_num = 0; - - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = tarkinenc->og.header; - GST_BUFFER_SIZE (outbuf) = tarkinenc->og.header_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (tarkinenc->srcpad, GST_DATA (outbuf)); - - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = tarkinenc->og.body; - GST_BUFFER_SIZE (outbuf) = tarkinenc->og.body_len; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); - gst_pad_push (tarkinenc->srcpad, GST_DATA (outbuf)); - - tarkinenc->setup = TRUE; -} - -static void -gst_tarkinenc_chain (GstPad * pad, GstData * _data) -{ - GstBuffer *buf = GST_BUFFER (_data); - TarkinEnc *tarkinenc; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - tarkinenc = GST_TARKINENC (gst_pad_get_parent (pad)); - - if (!tarkinenc->setup) { - GST_ELEMENT_ERROR (tarkinenc, CORE, NEGOTIATION, (NULL), - ("encoder not initialized (input is not tarkin?)")); - if (GST_IS_BUFFER (buf)) - gst_buffer_unref (buf); - else - gst_pad_event_default (pad, GST_EVENT (buf)); - return; - } - - if (GST_IS_EVENT (buf)) { - switch (GST_EVENT_TYPE (buf)) { - case GST_EVENT_EOS: - tarkin_analysis_framein (tarkinenc->tarkin_stream, NULL, 0, NULL); /* EOS */ - tarkin_comment_clear (&tarkinenc->tc); - tarkin_stream_destroy (tarkinenc->tarkin_stream); - default: - gst_pad_event_default (pad, GST_EVENT (buf)); - break; - } - } else { - gchar *data; - gulong size; - TarkinTime date; - - /* data to encode */ - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); - - date.numerator = tarkinenc->frame_num; - date.denominator = 1; - tarkin_analysis_framein (tarkinenc->tarkin_stream, data, 0, &date); - tarkinenc->frame_num++; - - gst_buffer_unref (buf); - } -} - -static void -gst_tarkinenc_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - TarkinEnc *tarkinenc; - - g_return_if_fail (GST_IS_TARKINENC (object)); - - tarkinenc = GST_TARKINENC (object); - - switch (prop_id) { - case ARG_BITRATE: - g_value_set_int (value, tarkinenc->bitrate); - break; - case ARG_S_MOMENTS: - g_value_set_int (value, tarkinenc->s_moments); - break; - case ARG_A_MOMENTS: - g_value_set_int (value, tarkinenc->a_moments); - break; - default: - break; - } -} - -static void -gst_tarkinenc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - TarkinEnc *tarkinenc; - - g_return_if_fail (GST_IS_TARKINENC (object)); - - tarkinenc = GST_TARKINENC (object); - - switch (prop_id) { - case ARG_BITRATE: - tarkinenc->bitrate = g_value_get_int (value); - break; - case ARG_S_MOMENTS: - { - gint s_moments; - - s_moments = g_value_get_int (value); - if (s_moments != 1 || s_moments != 2 || s_moments != 4) { - g_warning ("tarkinenc: s_moments must be 1, 2 or 4"); - } else { - tarkinenc->s_moments = s_moments; - } - break; - } - case ARG_A_MOMENTS: - { - gint a_moments; - - a_moments = g_value_get_int (value); - if (a_moments != 1 || a_moments != 2 || a_moments != 4) { - g_warning ("tarkinenc: a_moments must be 1, 2 or 4"); - } else { - tarkinenc->a_moments = a_moments; - } - break; - } - default: - break; - } -} diff --git a/ext/tarkin/gsttarkinenc.h b/ext/tarkin/gsttarkinenc.h deleted file mode 100644 index 3c733b0e4a..0000000000 --- a/ext/tarkin/gsttarkinenc.h +++ /dev/null @@ -1,83 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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 __TARKINENC_H__ -#define __TARKINENC_H__ - - -#include - -#include "tarkin.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define GST_TYPE_TARKINENC \ - (tarkinenc_get_type()) -#define GST_TARKINENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TARKINENC,TarkinEnc)) -#define GST_TARKINENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TARKINENC,TarkinEncClass)) -#define GST_IS_TARKINENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TARKINENC)) -#define GST_IS_TARKINENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TARKINENC)) - -typedef struct _TarkinEnc TarkinEnc; -typedef struct _TarkinEncClass TarkinEncClass; - -struct _TarkinEnc { - GstElement element; - - GstPad *sinkpad,*srcpad; - - ogg_stream_state os; /* take physical pages, weld into a logical - stream of packets */ - ogg_page og; /* one Ogg bitstream page. Tarkin packets are inside */ - ogg_packet op[3]; /* one raw packet of data for decode */ - - TarkinStream *tarkin_stream; - TarkinComment tc; - TarkinInfo ti; - TarkinVideoLayerDesc layer[1]; - - gint frame_num; - - gboolean eos; - gint bitrate; - gint s_moments; - gint a_moments; - gboolean setup; -}; - -struct _TarkinEncClass { - GstElementClass parent_class; -}; - -GType tarkinenc_get_type(void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __TARKINENC_H__ */ diff --git a/ext/tarkin/info.c b/ext/tarkin/info.c deleted file mode 100644 index 83fe1bae60..0000000000 --- a/ext/tarkin/info.c +++ /dev/null @@ -1,621 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - - ******************************************************************** - - function: maintain the info structure, info <-> header packets - last mod: $Id$ - - ********************************************************************/ - -/* general handling of the header and the TarkinInfo structure (and - substructures) */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include "tarkin.h" -#include "yuv.h" -#include "mem.h" - -/* helpers */ -static void -_v_writestring (oggpack_buffer * o, char *s, int bytes) -{ - while (bytes--) { - oggpack_write (o, *s++, 8); - } -} - -static void -_v_readstring (oggpack_buffer * o, char *buf, int bytes) -{ - while (bytes--) { - *buf++ = oggpack_read (o, 8); - } -} - -void -tarkin_comment_init (TarkinComment * vc) -{ - memset (vc, 0, sizeof (*vc)); -} - -void -tarkin_comment_add (TarkinComment * vc, char *comment) -{ - vc->user_comments = REALLOC (vc->user_comments, - (vc->comments + 2) * sizeof (*vc->user_comments)); - vc->comment_lengths = REALLOC (vc->comment_lengths, - (vc->comments + 2) * sizeof (*vc->comment_lengths)); - vc->comment_lengths[vc->comments] = strlen (comment); - vc->user_comments[vc->comments] = - MALLOC (vc->comment_lengths[vc->comments] + 1); - strcpy (vc->user_comments[vc->comments], comment); - vc->comments++; - vc->user_comments[vc->comments] = NULL; -} - -void -tarkin_comment_add_tag (TarkinComment * vc, char *tag, char *contents) -{ - char *comment = alloca (strlen (tag) + strlen (contents) + 2); /* +2 for = and \0 */ - - strcpy (comment, tag); - strcat (comment, "="); - strcat (comment, contents); - tarkin_comment_add (vc, comment); -} - -/* This is more or less the same as strncasecmp - but that doesn't exist - * everywhere, and this is a fairly trivial function, so we include it */ -static int -tagcompare (const char *s1, const char *s2, int n) -{ - int c = 0; - - while (c < n) { - if (toupper (s1[c]) != toupper (s2[c])) - return !0; - c++; - } - return 0; -} - -char * -tarkin_comment_query (TarkinComment * vc, char *tag, int count) -{ - long i; - int found = 0; - int taglen = strlen (tag) + 1; /* +1 for the = we append */ - char *fulltag = alloca (taglen + 1); - - strcpy (fulltag, tag); - strcat (fulltag, "="); - - for (i = 0; i < vc->comments; i++) { - if (!tagcompare (vc->user_comments[i], fulltag, taglen)) { - if (count == found) - /* We return a pointer to the data, not a copy */ - return vc->user_comments[i] + taglen; - else - found++; - } - } - return NULL; /* didn't find anything */ -} - -int -tarkin_comment_query_count (TarkinComment * vc, char *tag) -{ - int i, count = 0; - int taglen = strlen (tag) + 1; /* +1 for the = we append */ - char *fulltag = alloca (taglen + 1); - - strcpy (fulltag, tag); - strcat (fulltag, "="); - - for (i = 0; i < vc->comments; i++) { - if (!tagcompare (vc->user_comments[i], fulltag, taglen)) - count++; - } - - return count; -} - -void -tarkin_comment_clear (TarkinComment * vc) -{ - if (vc) { - long i; - - for (i = 0; i < vc->comments; i++) - if (vc->user_comments[i]) - FREE (vc->user_comments[i]); - if (vc->user_comments) - FREE (vc->user_comments); - if (vc->comment_lengths) - FREE (vc->comment_lengths); - if (vc->vendor) - FREE (vc->vendor); - } - memset (vc, 0, sizeof (*vc)); -} - -/* used by synthesis, which has a full, alloced vi */ -void -tarkin_info_init (TarkinInfo * vi) -{ - memset (vi, 0, sizeof (*vi)); -} - -void -tarkin_info_clear (TarkinInfo * vi) -{ - memset (vi, 0, sizeof (*vi)); -} - -/* Header packing/unpacking ********************************************/ - -static int -_tarkin_unpack_info (TarkinInfo * vi, oggpack_buffer * opb) -{ -#ifdef DBG_OGG - printf ("dbg_ogg: Decoding Info: "); -#endif - vi->version = oggpack_read (opb, 32); - if (vi->version != 0) - return (-TARKIN_VERSION); - - vi->n_layers = oggpack_read (opb, 8); - vi->inter.numerator = oggpack_read (opb, 32); - vi->inter.denominator = oggpack_read (opb, 32); - - vi->bitrate_upper = oggpack_read (opb, 32); - vi->bitrate_nominal = oggpack_read (opb, 32); - vi->bitrate_lower = oggpack_read (opb, 32); - -#ifdef DBG_OGG - printf (" n_layers %d, interleave: %d/%d, ", - vi->n_layers, vi->inter.numerator, vi->inter.denominator); -#endif - - if (vi->inter.numerator < 1) - goto err_out; - if (vi->inter.denominator < 1) - goto err_out; - if (vi->n_layers < 1) - goto err_out; - - if (oggpack_read (opb, 1) != 1) - goto err_out; /* EOP check */ - -#ifdef DBG_OGG - printf ("Success\n"); -#endif - return (0); -err_out: -#ifdef DBG_OGG - printf ("Failed\n"); -#endif - tarkin_info_clear (vi); - return (-TARKIN_BAD_HEADER); -} - -static int -_tarkin_unpack_comment (TarkinComment * vc, oggpack_buffer * opb) -{ - int i; - int vendorlen = oggpack_read (opb, 32); - -#ifdef DBG_OGG - printf ("dbg_ogg: Decoding comment: "); -#endif - if (vendorlen < 0) - goto err_out; - vc->vendor = _ogg_calloc (vendorlen + 1, 1); - _v_readstring (opb, vc->vendor, vendorlen); - vc->comments = oggpack_read (opb, 32); - if (vc->comments < 0) - goto err_out; - vc->user_comments = - _ogg_calloc (vc->comments + 1, sizeof (*vc->user_comments)); - vc->comment_lengths = - _ogg_calloc (vc->comments + 1, sizeof (*vc->comment_lengths)); - - for (i = 0; i < vc->comments; i++) { - int len = oggpack_read (opb, 32); - - if (len < 0) - goto err_out; - vc->comment_lengths[i] = len; - vc->user_comments[i] = _ogg_calloc (len + 1, 1); - _v_readstring (opb, vc->user_comments[i], len); - } - if (oggpack_read (opb, 1) != 1) - goto err_out; /* EOP check */ - -#ifdef DBG_OGG - printf ("Success, read %d comments\n", vc->comments); -#endif - return (0); -err_out: -#ifdef DBG_OGG - printf ("Failed\n"); -#endif - tarkin_comment_clear (vc); - return (-TARKIN_BAD_HEADER); -} - -/* the real encoding details are here, currently TarkinVideoLayerDesc. */ -static int -_tarkin_unpack_layer_desc (TarkinInfo * vi, oggpack_buffer * opb) -{ - int i, j; - - vi->layer = CALLOC (vi->n_layers, (sizeof (*vi->layer))); - memset (vi->layer, 0, vi->n_layers * sizeof (*vi->layer)); - -#ifdef DBG_OGG - printf ("ogg: Decoding layers description: "); -#endif - for (i = 0; i < vi->n_layers; i++) { - TarkinVideoLayer *layer = vi->layer + i; - - layer->desc.width = oggpack_read (opb, 32); - layer->desc.height = oggpack_read (opb, 32); - layer->desc.a_moments = oggpack_read (opb, 32); - layer->desc.s_moments = oggpack_read (opb, 32); - layer->desc.frames_per_buf = oggpack_read (opb, 32); - layer->desc.bitstream_len = oggpack_read (opb, 32); - layer->desc.format = oggpack_read (opb, 32); - - switch (layer->desc.format) { - case TARKIN_GRAYSCALE: - layer->n_comp = 1; - layer->color_fwd_xform = grayscale_to_y; - layer->color_inv_xform = y_to_grayscale; - break; - case TARKIN_RGB24: - layer->n_comp = 3; - layer->color_fwd_xform = rgb24_to_yuv; - layer->color_inv_xform = yuv_to_rgb24; - break; - case TARKIN_RGB32: - layer->n_comp = 3; - layer->color_fwd_xform = rgb32_to_yuv; - layer->color_inv_xform = yuv_to_rgb32; - break; - case TARKIN_RGBA: - layer->n_comp = 4; - layer->color_fwd_xform = rgba_to_yuv; - layer->color_inv_xform = yuv_to_rgba; - break; - default: - return -TARKIN_INVALID_COLOR_FORMAT; - }; - - layer->waveletbuf = (Wavelet3DBuf **) CALLOC (layer->n_comp, - sizeof (Wavelet3DBuf *)); - - layer->packet = MALLOC (layer->n_comp * sizeof (*layer->packet)); - memset (layer->packet, 0, layer->n_comp * sizeof (*layer->packet)); - - for (j = 0; j < layer->n_comp; j++) { - layer->waveletbuf[j] = wavelet_3d_buf_new (layer->desc.width, - layer->desc.height, layer->desc.frames_per_buf); - layer->packet[j].data = MALLOC (layer->desc.bitstream_len); - layer->packet[j].storage = layer->desc.bitstream_len; - } - - vi->max_bitstream_len += layer->desc.bitstream_len + 2 * 10 * sizeof (uint32_t) * layer->n_comp; /* truncation tables */ - -#ifdef DBG_OGG - printf - ("\n layer%d: size %dx%dx%d, format %d, a_m %d, s_m %d, %d fpb\n", - i, layer->desc.width, layer->desc.height, layer->n_comp, - layer->desc.format, layer->desc.a_moments, layer->desc.s_moments, - layer->desc.frames_per_buf); -#endif - } /* for each layer */ - - if (oggpack_read (opb, 1) != 1) - goto err_out; /* EOP check */ - -#ifdef DBG_OGG - printf ("Success\n"); -#endif - - return (0); -err_out: -#ifdef DBG_OGG - printf ("Failed\n"); -#endif - tarkin_info_clear (vi); - return (-TARKIN_BAD_HEADER); -} - -/* The Tarkin header is in three packets; the initial small packet in - the first page that identifies basic parameters, a second packet - with bitstream comments and a third packet that holds the - layer description structures. */ - -TarkinError -tarkin_synthesis_headerin (TarkinInfo * vi, TarkinComment * vc, ogg_packet * op) -{ - oggpack_buffer opb; - - if (op) { - oggpack_readinit (&opb, op->packet, op->bytes); - - /* Which of the three types of header is this? */ - /* Also verify header-ness, tarkin */ - { - char buffer[6]; - int packtype = oggpack_read (&opb, 8); - - memset (buffer, 0, 6); - _v_readstring (&opb, buffer, 6); - if (memcmp (buffer, "tarkin", 6)) { - /* not a tarkin header */ - return (-TARKIN_NOT_TARKIN); - } - switch (packtype) { - case 0x01: /* least significant *bit* is read first */ - if (!op->b_o_s) { - /* Not the initial packet */ - return (-TARKIN_BAD_HEADER); - } - if (vi->inter.numerator != 0) { - /* previously initialized info header */ - return (-TARKIN_BAD_HEADER); - } - - return (_tarkin_unpack_info (vi, &opb)); - - case 0x03: /* least significant *bit* is read first */ - if (vi->inter.denominator == 0) { - /* um... we didn't get the initial header */ - return (-TARKIN_BAD_HEADER); - } - - return (_tarkin_unpack_comment (vc, &opb)); - - case 0x05: /* least significant *bit* is read first */ - if (vi->inter.numerator == 0 || vc->vendor == NULL) { - /* um... we didn;t get the initial header or comments yet */ - return (-TARKIN_BAD_HEADER); - } - - return (_tarkin_unpack_layer_desc (vi, &opb)); - - default: - /* Not a valid tarkin header type */ - return (-TARKIN_BAD_HEADER); - break; - } - } - } - return (-TARKIN_BAD_HEADER); -} - -/* pack side **********************************************************/ - -static int -_tarkin_pack_info (oggpack_buffer * opb, TarkinInfo * vi) -{ - - /* preamble */ - oggpack_write (opb, 0x01, 8); - _v_writestring (opb, "tarkin", 6); - - /* basic information about the stream */ - oggpack_write (opb, 0x00, 32); - oggpack_write (opb, vi->n_layers, 8); - oggpack_write (opb, vi->inter.numerator, 32); - oggpack_write (opb, vi->inter.denominator, 32); - - oggpack_write (opb, vi->bitrate_upper, 32); - oggpack_write (opb, vi->bitrate_nominal, 32); - oggpack_write (opb, vi->bitrate_lower, 32); - - oggpack_write (opb, 1, 1); - -#ifdef DBG_OGG - printf ("dbg_ogg: Putting out info, inter %d/%d, n_layers %d\n", - vi->inter.numerator, vi->inter.denominator, vi->n_layers); -#endif - return (0); -} - -static int -_tarkin_pack_comment (oggpack_buffer * opb, TarkinComment * vc) -{ - char temp[] = "libTarkin debugging edition 20011104"; - int bytes = strlen (temp); - - /* preamble */ - oggpack_write (opb, 0x03, 8); - _v_writestring (opb, "tarkin", 6); - - /* vendor */ - oggpack_write (opb, bytes, 32); - _v_writestring (opb, temp, bytes); - - /* comments */ - - oggpack_write (opb, vc->comments, 32); - if (vc->comments) { - int i; - - for (i = 0; i < vc->comments; i++) { - if (vc->user_comments[i]) { - oggpack_write (opb, vc->comment_lengths[i], 32); - _v_writestring (opb, vc->user_comments[i], vc->comment_lengths[i]); - } else { - oggpack_write (opb, 0, 32); - } - } - } - oggpack_write (opb, 1, 1); - -#ifdef DBG_OGG - printf ("dbg_ogg: Putting out %d comments\n", vc->comments); -#endif - - return (0); -} - -static int -_tarkin_pack_layer_desc (oggpack_buffer * opb, TarkinInfo * vi) -{ - int i; - TarkinVideoLayer *layer; - -#ifdef DBG_OGG - printf ("dbg_ogg: Putting out layers description:\n"); -#endif - - oggpack_write (opb, 0x05, 8); - _v_writestring (opb, "tarkin", 6); - - for (i = 0; i < vi->n_layers; i++) { - layer = vi->layer + i; - oggpack_write (opb, layer->desc.width, 32); - oggpack_write (opb, layer->desc.height, 32); - oggpack_write (opb, layer->desc.a_moments, 32); - oggpack_write (opb, layer->desc.s_moments, 32); - oggpack_write (opb, layer->desc.frames_per_buf, 32); - oggpack_write (opb, layer->desc.bitstream_len, 32); - oggpack_write (opb, layer->desc.format, 32); - -#ifdef DBG_OGG - printf (" res. %dx%d, format %d, a_m %d, s_m %d, fpb %d\n", - layer->desc.width, layer->desc.height, layer->desc.format, - layer->desc.a_moments, layer->desc.s_moments, - layer->desc.frames_per_buf); -#endif - - } - oggpack_write (opb, 1, 1); - -#ifdef DBG_OGG - printf (" wrote %ld bytes.\n", oggpack_bytes (opb)); -#endif - - return (0); -} - -int -tarkin_comment_header_out (TarkinComment * vc, ogg_packet * op) -{ - - oggpack_buffer opb; - - oggpack_writeinit (&opb); - if (_tarkin_pack_comment (&opb, vc)) - return -TARKIN_NOT_IMPLEMENTED; - - op->packet = MALLOC (oggpack_bytes (&opb)); - memcpy (op->packet, opb.buffer, oggpack_bytes (&opb)); - - op->bytes = oggpack_bytes (&opb); - op->b_o_s = 0; - op->e_o_s = 0; - op->granulepos = 0; - - return 0; -} - -TarkinError -tarkin_analysis_headerout (TarkinStream * v, - TarkinComment * vc, - ogg_packet * op, ogg_packet * op_comm, ogg_packet * op_code) -{ - int ret = -TARKIN_NOT_IMPLEMENTED; - TarkinInfo *vi; - oggpack_buffer opb; - tarkin_header_store *b = &v->headers; - - vi = v->ti; - - /* first header packet ********************************************* */ - - oggpack_writeinit (&opb); - if (_tarkin_pack_info (&opb, vi)) - goto err_out; - - /* build the packet */ - if (b->header) - FREE (b->header); - b->header = MALLOC (oggpack_bytes (&opb)); - memcpy (b->header, opb.buffer, oggpack_bytes (&opb)); - op->packet = b->header; - op->bytes = oggpack_bytes (&opb); - op->b_o_s = 1; - op->e_o_s = 0; - op->granulepos = 0; - - /* second header packet (comments) ********************************* */ - - oggpack_reset (&opb); - if (_tarkin_pack_comment (&opb, vc)) - goto err_out; - - if (b->header1) - FREE (b->header1); - b->header1 = MALLOC (oggpack_bytes (&opb)); - memcpy (b->header1, opb.buffer, oggpack_bytes (&opb)); - op_comm->packet = b->header1; - op_comm->bytes = oggpack_bytes (&opb); - op_comm->b_o_s = 0; - op_comm->e_o_s = 0; - op_comm->granulepos = 0; - - /* third header packet (modes/codebooks) *************************** */ - - oggpack_reset (&opb); - if (_tarkin_pack_layer_desc (&opb, vi)) - goto err_out; - - if (b->header2) - FREE (b->header2); - b->header2 = MALLOC (oggpack_bytes (&opb)); - memcpy (b->header2, opb.buffer, oggpack_bytes (&opb)); - op_code->packet = b->header2; - op_code->bytes = oggpack_bytes (&opb); - op_code->b_o_s = 0; - op_code->e_o_s = 0; - op_code->granulepos = 0; - - oggpack_writeclear (&opb); - return (0); -err_out: - oggpack_writeclear (&opb); - memset (op, 0, sizeof (*op)); - memset (op_comm, 0, sizeof (*op_comm)); - memset (op_code, 0, sizeof (*op_code)); - - if (b->header) - FREE (b->header); - if (b->header1) - FREE (b->header1); - if (b->header2) - FREE (b->header2); - b->header = NULL; - b->header1 = NULL; - b->header2 = NULL; - return (ret); -} diff --git a/ext/tarkin/mem.c b/ext/tarkin/mem.c deleted file mode 100644 index 5ef59f2f65..0000000000 --- a/ext/tarkin/mem.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Debugging implementation of MALLOC and friends - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mem.h" - -#if defined(DBG_MEMLEAKS) - -typedef struct -{ - void *mem; - char *allocated_in_func; - char *allocated_in_file; - unsigned int allocated_in_line; -} -MemDesc; - - -static int initialized = 0; -static int alloc_count = 0; -static MemDesc *alloc_list = NULL; - - -static void -dbg_memleaks_done (int exitcode, void *dummy) -{ - unsigned int i; - - (void) dummy; - - if (exitcode == 0 && alloc_count != 0) { - fprintf (stderr, "\nmemory leak detected !!!\n"); - fprintf (stderr, "\nalloc_count == %i\n\n", alloc_count); - for (i = 0; i < alloc_count; i++) { - MemDesc *d = &alloc_list[i]; - - fprintf (stderr, "chunk %p allocated in %s (%s: %u) not free'd !!\n", - d->mem, d->allocated_in_func, d->allocated_in_file, - d->allocated_in_line); - } - free (alloc_list); - } - fprintf (stderr, "\n"); -} - - -static void -dbg_memleaks_init (void) -{ - on_exit (dbg_memleaks_done, NULL); - initialized = 1; -} - - -void * -dbg_malloc (char *file, int line, char *func, size_t bytes) -{ - void *mem = (void *) malloc (bytes); - MemDesc *d; - - if (!initialized) - dbg_memleaks_init (); - - alloc_count++; - alloc_list = realloc (alloc_list, alloc_count * sizeof (MemDesc)); - - d = &alloc_list[alloc_count - 1]; - d->mem = mem; - d->allocated_in_func = func; - d->allocated_in_file = file; - d->allocated_in_line = line; - - return mem; -} - - -void * -dbg_calloc (char *file, int line, char *func, size_t count, size_t bytes) -{ - void *mem = (void *) calloc (count, bytes); - MemDesc *d; - - if (!initialized) - dbg_memleaks_init (); - - alloc_count++; - alloc_list = realloc (alloc_list, alloc_count * sizeof (MemDesc)); - - d = &alloc_list[alloc_count - 1]; - d->mem = mem; - d->allocated_in_func = func; - d->allocated_in_file = file; - d->allocated_in_line = line; - - return mem; -} - - -void * -dbg_realloc (char *file, int line, char *func, char *what, - void *mem, size_t bytes) -{ - unsigned int i; - - for (i = 0; i < alloc_count; i++) { - if (alloc_list[i].mem == mem) { - alloc_list[i].mem = (void *) realloc (mem, bytes); - return alloc_list[i].mem; - } - } - - if (mem != NULL) { - fprintf (stderr, - "%s: trying to reallocate unknown chunk %p (%s)\n" - " in %s (%s: %u) !!!\n", - __FUNCTION__, mem, what, func, file, line); - exit (-1); - } - - return dbg_malloc (file, line, func, bytes); -} - - -void -dbg_free (char *file, int line, char *func, char *what, void *mem) -{ - unsigned int i; - - if (!initialized) - dbg_memleaks_init (); - - for (i = 0; i < alloc_count; i++) { - if (alloc_list[i].mem == mem) { - free (mem); - alloc_count--; - memmove (&alloc_list[i], &alloc_list[i + 1], - (alloc_count - i) * sizeof (MemDesc)); - return; - } - } - - fprintf (stderr, "%s: trying to free unknown chunk %p (%s)\n" - " in %s (%s: %u) !!!\n", - __FUNCTION__, mem, what, func, file, line); - exit (-1); -} - - -#endif diff --git a/ext/tarkin/mem.h b/ext/tarkin/mem.h deleted file mode 100644 index 4cd8518321..0000000000 --- a/ext/tarkin/mem.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __MEM_H -#define __MEM_H - -#include "_stdint.h" -#include -#include -#include - - -#if defined(DBG_MEMLEAKS) - -extern void* dbg_malloc (char *file, int line, char *func, size_t bytes); -extern void* dbg_calloc (char *file, int line, char *func, size_t count, size_t bytes); -extern void* dbg_realloc (char *file, int line, char *func, char *what, void *mem, size_t bytes); -extern void dbg_free (char *file, int line, char *func, char *what, void *mem); - -#define MALLOC(bytes) dbg_malloc(__FILE__,__LINE__,__FUNCTION__,bytes) -#define CALLOC(count,bytes) dbg_calloc(__FILE__,__LINE__,__FUNCTION__,count,bytes) -#define FREE(mem) dbg_free(__FILE__,__LINE__,__FUNCTION__,#mem,mem) -#define REALLOC(mem,bytes) dbg_realloc(__FILE__,__LINE__,__FUNCTION__,#mem,mem,bytes) - -#else - -#define MALLOC malloc -#define CALLOC calloc -#define REALLOC realloc -#define FREE free - -#endif - -#endif - diff --git a/ext/tarkin/rle.h b/ext/tarkin/rle.h deleted file mode 100644 index 7cf795173e..0000000000 --- a/ext/tarkin/rle.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef __RLE_H -#define __RLE_H - -#include -#include -#include "mem.h" -#include "bitcoder.h" -#include "golomb.h" - -#if defined(RLECODER) - -#define OUTPUT_BIT(rlecoder,bit) rlecoder_write_bit(rlecoder,bit) -#define INPUT_BIT(rlecoder) rlecoder_read_bit(rlecoder) -#define OUTPUT_BIT_DIRECT(coder,bit) bitcoder_write_bit(&(coder)->bitcoder,bit) -#define INPUT_BIT_DIRECT(rlecoder) bitcoder_read_bit(&(rlecoder)->bitcoder) -#define ENTROPY_CODER RLECoderState -#define ENTROPY_ENCODER_INIT(coder,limit) rlecoder_encoder_init(coder,limit) -#define ENTROPY_ENCODER_DONE(coder) rlecoder_encoder_done(coder) -#define ENTROPY_ENCODER_FLUSH(coder) rlecoder_encoder_flush(coder) -#define ENTROPY_DECODER_INIT(coder,bitstream,limit) \ - rlecoder_decoder_init(coder,bitstream,limit) -#define ENTROPY_DECODER_DONE(coder) /* nothing to do ... */ -#define ENTROPY_CODER_BITSTREAM(coder) ((coder)->bitcoder.bitstream) -#define ENTROPY_CODER_EOS(coder) ((coder)->bitcoder.eos) - -#define ENTROPY_CODER_SYMBOL(coder) ((coder)->symbol) -#define ENTROPY_CODER_RUNLENGTH(coder) ((coder)->count) -#define ENTROPY_CODER_SKIP(coder,skip) do { (coder)->count -= skip; } while (0) -#endif - - - - -typedef struct { - int symbol; - uint32_t count; /* have seen count symbol's */ - BitCoderState bitcoder; - GolombAdaptiveCoderState golomb_state [2]; /* 2 states for 2 symbols... */ - int have_seen_1; -} RLECoderState; - - - -/* - * bit should be 0 or 1 !!! - */ -static inline -void rlecoder_write_bit (RLECoderState *s, int bit) -{ - assert (bit == 0 || bit == 1); - - if (s->symbol == -1) { - s->symbol = bit & 1; - s->count = 1; - s->have_seen_1 = bit; - bitcoder_write_bit (&s->bitcoder, bit); - } - - if (s->symbol != bit) { - golombcoder_encode_number (&s->golomb_state[s->symbol], - &s->bitcoder, s->count); - s->symbol = ~s->symbol & 1; - s->have_seen_1 = 1; - s->count = 1; - } else - s->count++; -} - -static inline -int rlecoder_read_bit (RLECoderState *s) -{ - if (s->count == 0) { - s->symbol = ~s->symbol & 1; - s->count = golombcoder_decode_number (&s->golomb_state[s->symbol], - &s->bitcoder); - if (s->bitcoder.eos) { - s->symbol = 0; - s->count = ~0; - } - } - s->count--; - return (s->symbol); -} - - -int coder_id = 0; -FILE *file = NULL; - -static inline -void rlecoder_encoder_init (RLECoderState *s, uint32_t limit) -{ - bitcoder_encoder_init (&s->bitcoder, limit); - s->symbol = -1; - s->have_seen_1 = 0; - s->golomb_state[0].count = 0; - s->golomb_state[1].count = 0; - s->golomb_state[0].bits = 5 << 3; - s->golomb_state[1].bits = 5 << 3; -} - - -/** - * once you called this, you better should not encode any more symbols ... - */ -static inline -uint32_t rlecoder_encoder_flush (RLECoderState *s) -{ - if (s->symbol == -1 || !s->have_seen_1) - return 0; - - golombcoder_encode_number (&s->golomb_state[s->symbol], - &s->bitcoder, s->count); - return bitcoder_flush (&s->bitcoder); -} - - -static inline -void rlecoder_decoder_init (RLECoderState *s, uint8_t *bitstream, uint32_t limit) -{ - bitcoder_decoder_init (&s->bitcoder, bitstream, limit); - s->golomb_state[0].count = 0; - s->golomb_state[1].count = 0; - s->golomb_state[0].bits = 5 << 3; - s->golomb_state[1].bits = 5 << 3; - s->symbol = bitcoder_read_bit (&s->bitcoder); - s->count = golombcoder_decode_number (&s->golomb_state[s->symbol], - &s->bitcoder) - 1; - if (s->bitcoder.eos) { - s->symbol = 0; - s->count = ~0; - } -} - - -static inline -void rlecoder_encoder_done (RLECoderState *s) -{ - bitcoder_encoder_done (&s->bitcoder); -} - - -#endif - diff --git a/ext/tarkin/tarkin.c b/ext/tarkin/tarkin.c deleted file mode 100644 index f1047e9e4e..0000000000 --- a/ext/tarkin/tarkin.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * The real io-stuff is in tarkin-io.c - * (this one has to be rewritten to write ogg streams ...) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mem.h" -#include "tarkin.h" -#include "yuv.h" - - -#define N_FRAMES 1 - - - -TarkinStream * -tarkin_stream_new () -{ - TarkinStream *s = (TarkinStream *) CALLOC (1, sizeof (TarkinStream)); - - if (!s) - return NULL; - memset (s, 0, sizeof (*s)); - - s->frames_per_buf = N_FRAMES; - - return s; -} - - -void -tarkin_stream_destroy (TarkinStream * s) -{ - uint32_t i, j; - - if (!s) - return; - - for (i = 0; i < s->n_layers; i++) { - if (s->layer[i].waveletbuf) { - for (j = 0; j < s->layer[i].n_comp; j++) { - wavelet_3d_buf_destroy (s->layer[i].waveletbuf[j]); - FREE (s->layer[i].packet[j].data); - } - FREE (s->layer[i].waveletbuf); - FREE (s->layer[i].packet); - } - } - - if (s->layer) - FREE (s->layer); - - if (s->headers.header) - FREE (s->headers.header); - - if (s->headers.header1) - FREE (s->headers.header1); - - if (s->headers.header2) - FREE (s->headers.header2); - - - FREE (s); -} - - -int -tarkin_analysis_init (TarkinStream * s, TarkinInfo * ti, - TarkinError (*free_frame) (void *s, void *ptr), - TarkinError (*packet_out) (void *s, ogg_packet * ptr), void *user_ptr) -{ - if ((!ti->inter.numerator) || (!ti->inter.denominator)) - return (-TARKIN_FAULT); - if ((!free_frame) || (!packet_out)) - return (-TARKIN_FAULT); - s->ti = ti; - s->free_frame = free_frame; - s->packet_out = packet_out; - s->user_ptr = user_ptr; - return (0); -} - - -extern int -tarkin_analysis_add_layer (TarkinStream * s, TarkinVideoLayerDesc * tvld) -{ - int i; - TarkinVideoLayer *layer; - - if (s->n_layers) { - s->layer = REALLOC (s->layer, (s->n_layers + 1) * sizeof (*s->layer)); - } else { - s->layer = MALLOC (sizeof (*s->layer)); - } - layer = s->layer + s->n_layers; - memset (layer, 0, sizeof (*s->layer)); - memcpy (&layer->desc, tvld, sizeof (TarkinVideoLayerDesc)); - - s->n_layers++; - s->ti->n_layers = s->n_layers; - s->ti->layer = s->layer; - - switch (layer->desc.format) { - case TARKIN_GRAYSCALE: - layer->n_comp = 1; - layer->color_fwd_xform = grayscale_to_y; - layer->color_inv_xform = y_to_grayscale; - break; - case TARKIN_RGB24: - layer->n_comp = 3; - layer->color_fwd_xform = rgb24_to_yuv; - layer->color_inv_xform = yuv_to_rgb24; - break; - case TARKIN_RGB32: - layer->n_comp = 3; - layer->color_fwd_xform = rgb32_to_yuv; - layer->color_inv_xform = yuv_to_rgb32; - break; - case TARKIN_RGBA: - layer->n_comp = 4; - layer->color_fwd_xform = rgba_to_yuv; - layer->color_inv_xform = yuv_to_rgba; - break; - default: - return -TARKIN_INVALID_COLOR_FORMAT; - }; - -#ifdef DBG_OGG - printf ("dbg_ogg:add_layer %d with %d components\n", - s->n_layers, layer->n_comp); -#endif - - layer->waveletbuf = (Wavelet3DBuf **) CALLOC (layer->n_comp, - sizeof (Wavelet3DBuf *)); - - layer->packet = MALLOC (layer->n_comp * sizeof (*layer->packet)); - memset (layer->packet, 0, layer->n_comp * sizeof (*layer->packet)); - - for (i = 0; i < layer->n_comp; i++) { - layer->waveletbuf[i] = wavelet_3d_buf_new (layer->desc.width, - layer->desc.height, layer->desc.frames_per_buf); - layer->packet[i].data = MALLOC (layer->desc.bitstream_len); - layer->packet[i].storage = layer->desc.bitstream_len; - } - /* - max_bitstream_len += layer->desc.bitstream_len - + 2 * 10 * sizeof(uint32_t) * layer->n_comp; - */ - return (TARKIN_OK); -} - -TarkinError -_analysis_packetout (TarkinStream * s, uint32_t layer_id, uint32_t comp) -{ - ogg_packet op; - oggpack_buffer opb; - uint8_t *data; - uint32_t data_len; - int i; - - data = s->layer[layer_id].packet[comp].data; - data_len = s->layer[layer_id].packet[comp].data_len; - - oggpack_writeinit (&opb); - oggpack_write (&opb, 0, 8); /* No feature flags for now */ - oggpack_write (&opb, layer_id, 12); - oggpack_write (&opb, comp, 12); - for (i = 0; i < data_len; i++) - oggpack_write (&opb, *(data + i), 8); - - op.b_o_s = 0; - op.e_o_s = data_len ? 0 : 1; - op.granulepos = 0; - op.bytes = oggpack_bytes (&opb) + 4; - op.packet = opb.buffer; -#ifdef DBG_OGG - printf ("dbg_ogg: writing packet layer %d, comp %d, data_len %d %s\n", - layer_id, comp, data_len, op.e_o_s ? "eos" : ""); -#endif - s->layer[layer_id].packet[comp].data_len = 0; /* so direct call => eos */ - return (s->packet_out (s, &op)); -} - -void -_stream_flush (TarkinStream * s) -{ - uint32_t i, j; - - s->current_frame_in_buf = 0; - - for (i = 0; i < s->n_layers; i++) { - TarkinVideoLayer *layer = &s->layer[i]; - - for (j = 0; j < layer->n_comp; j++) { - uint32_t comp_bitstream_len; - TarkinPacket *packet = layer->packet + j; - - /** - * implicit 6:1:1 subsampling - */ - if (j == 0) - comp_bitstream_len = - 6 * layer->desc.bitstream_len / (layer->n_comp + 5); - else - comp_bitstream_len = layer->desc.bitstream_len / (layer->n_comp + 5); - - if (packet->storage < comp_bitstream_len) { - packet->storage = comp_bitstream_len; - packet->data = REALLOC (packet->data, comp_bitstream_len); - } - - wavelet_3d_buf_dump ("color-%d-%03d.pgm", - s->current_frame, j, layer->waveletbuf[j], j == 0 ? 0 : 128); - - wavelet_3d_buf_fwd_xform (layer->waveletbuf[j], - layer->desc.a_moments, layer->desc.s_moments); - - wavelet_3d_buf_dump ("coeff-%d-%03d.pgm", - s->current_frame, j, layer->waveletbuf[j], 128); - - packet->data_len = wavelet_3d_buf_encode_coeff (layer->waveletbuf[j], - packet->data, comp_bitstream_len); - - _analysis_packetout (s, i, j); - } - } -} - - -uint32_t -tarkin_analysis_framein (TarkinStream * s, uint8_t * frame, - uint32_t layer_id, TarkinTime * date) -{ - TarkinVideoLayer *layer; - - if (!frame) - return (_analysis_packetout (s, 0, 0)); /* eos */ - if ((layer_id >= s->n_layers) || (date->denominator == 0)) - return (TARKIN_FAULT); - - layer = s->layer + layer_id; - layer->color_fwd_xform (frame, layer->waveletbuf, s->current_frame_in_buf); - /* We don't use this feature for now, neither date... */ - s->free_frame (s, frame); - - s->current_frame_in_buf++; - - if (s->current_frame_in_buf == s->frames_per_buf) - _stream_flush (s); - -#ifdef DBG_OGG - printf ("dbg_ogg: framein at pos %d/%d, n? %d,%d on layer %d\n", - date->numerator, date->denominator, - layer->frameno, s->current_frame, layer_id); -#endif - - layer->frameno++; - return (++s->current_frame); -} - - - - -/** - * tarkin_stream_read_header() is now info.c:_tarkin_unpack_layer_desc() - */ - - - -TarkinError -tarkin_stream_get_layer_desc (TarkinStream * s, - uint32_t layer_id, TarkinVideoLayerDesc * desc) -{ - if (layer_id > s->n_layers - 1) - return -TARKIN_INVALID_LAYER; - - memcpy (desc, &(s->layer[layer_id].desc), sizeof (TarkinVideoLayerDesc)); - - return TARKIN_OK; -} - -TarkinError -tarkin_synthesis_init (TarkinStream * s, TarkinInfo * ti) -{ - s->ti = ti; - s->layer = ti->layer; /* It was malloc()ed by headerin() */ - s->n_layers = ti->n_layers; - return (TARKIN_OK); -} - -TarkinError -tarkin_synthesis_packetin (TarkinStream * s, ogg_packet * op) -{ - uint32_t i, layer_id, comp, data_len; - uint32_t flags, junk; - int nread; - oggpack_buffer opb; - TarkinPacket *packet; - -#ifdef DBG_OGG - printf ("dbg_ogg: Reading packet n? %lld, granulepos %lld, len %ld, %s%s\n", - op->packetno, op->granulepos, op->bytes, - op->b_o_s ? "b_o_s" : "", op->e_o_s ? "e_o_s" : ""); -#endif - oggpack_readinit (&opb, op->packet, op->bytes); - flags = oggpack_read (&opb, 8); - layer_id = oggpack_read (&opb, 12); /* Theses are required for */ - comp = oggpack_read (&opb, 12); /* data hole handling (or maybe - * packetno would be enough ?) */ - nread = 4; - - if (flags) { /* This is void "infinite future features" feature ;) */ - if (flags & 1 << 7) { - junk = flags; - while (junk & 1 << 7) - junk = oggpack_read (&opb, 8); /* allow for many future flags - that must be correctly ordonned. */ - } - /* This shows how to get a feature's data: - if (flags & TARKIN_FLAGS_EXAMPLE){ - tp->example = oggpack_read(&opb,32); - junk = tp->example & 3<<30; - tp->example &= 0x4fffffff; - } - */ - for (junk = 1 << 31; junk & 1 << 31;) /* and many future data */ - while ((junk = oggpack_read (&opb, 32)) & 1 << 30); - /* That is, feature data comes in 30 bit chunks. We also have - * 31 potentially useful bits in last chunk. */ - } - - nread = (opb.ptr - opb.buffer); - data_len = op->bytes - nread; - -#ifdef DBG_OGG - printf (" layer_id %d, comp %d, meta-data %dB, w3d data %dB.\n", - layer_id, comp, nread, data_len); -#endif - - /* We now have for shure our data. */ - packet = &s->layer[layer_id].packet[comp]; - if (packet->data_len) - return (-TARKIN_UNUSED); /* Previous data wasn't used */ - - if (packet->storage < data_len) { - packet->storage = data_len + 255; - packet->data = REALLOC (packet->data, packet->storage); - } - - for (i = 0; i < data_len; i++) - packet->data[i] = oggpack_read (&opb, 8); - - packet->data_len = data_len; - - return (TARKIN_OK); -} - -TarkinError -tarkin_synthesis_frameout (TarkinStream * s, - uint8_t ** frame, uint32_t layer_id, TarkinTime * date) -{ - int j; - TarkinVideoLayer *layer = &s->layer[layer_id]; - - if (s->current_frame_in_buf == 0) { - *frame = MALLOC (layer->desc.width * layer->desc.height * layer->n_comp); - for (j = 0; j < layer->n_comp; j++) { - TarkinPacket *packet = layer->packet + j; - - if (packet->data_len == 0) - goto err_out; - - wavelet_3d_buf_decode_coeff (layer->waveletbuf[j], packet->data, - packet->data_len); - - wavelet_3d_buf_dump ("rcoeff-%d-%03d.pgm", - s->current_frame, j, layer->waveletbuf[j], 128); - - wavelet_3d_buf_inv_xform (layer->waveletbuf[j], - layer->desc.a_moments, layer->desc.s_moments); - - wavelet_3d_buf_dump ("rcolor-%d-%03d.pgm", - s->current_frame, j, layer->waveletbuf[j], j == 0 ? 0 : 128); - } - - /* We did successfylly read a block from this layer, acknowledge it. */ - for (j = 0; j < layer->n_comp; j++) - layer->packet[j].data_len = 0; - } - - layer->color_inv_xform (layer->waveletbuf, *frame, s->current_frame_in_buf); - s->current_frame_in_buf++; - s->current_frame++; - - if (s->current_frame_in_buf == s->frames_per_buf) - s->current_frame_in_buf = 0; - - date->numerator = layer->frameno * s->ti->inter.numerator; - date->denominator = s->ti->inter.denominator; -#ifdef DBG_OGG - printf ("dbg_ogg: outputting frame pos %d/%d from layer %d.\n", - date->numerator, date->denominator, layer_id); -#endif - layer->frameno++; - return (TARKIN_OK); -err_out: - FREE (*frame); - return (TARKIN_NEED_MORE); -} - -int -tarkin_synthesis_freeframe (TarkinStream * s, uint8_t * frame) -{ - FREE (frame); - - return (TARKIN_OK); -} diff --git a/ext/tarkin/tarkin.h b/ext/tarkin/tarkin.h deleted file mode 100644 index 633f9a141f..0000000000 --- a/ext/tarkin/tarkin.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef __TARKIN_H -#define __TARKIN_H - -#include -#include "wavelet.h" -#include - - -#define BUG(x...) \ - do { \ - printf("BUG in %s (%s: line %i): ", __FUNCTION__, __FILE__, __LINE__); \ - printf(#x); \ - printf("\n"); \ - exit (-1); \ - } while (0); - - -/* Theses determine what infos the packet comes with */ -#define TARKIN_PACK_EXAMPLE 1 - -typedef struct { - uint8_t *data; - uint32_t data_len; - uint32_t storage; -} TarkinPacket; - - -typedef enum { - TARKIN_GRAYSCALE, - TARKIN_RGB24, /* tight packed RGB */ - TARKIN_RGB32, /* 32bit, no alphachannel */ - TARKIN_RGBA, /* dito w/ alphachannel */ - TARKIN_YUV2, /* 16 bits YUV */ - TARKIN_YUV12, /* 12 bits YUV */ - TARKIN_FYUV, /* Tarkin's Fast YUV-like? */ -} TarkinColorFormat; - -#define TARKIN_INTERNAL_FORMAT TARKIN_FYUV - -typedef enum { - TARKIN_OK = 0, - TARKIN_IO_ERROR, - TARKIN_SIGNATURE_NOT_FOUND, - TARKIN_INVALID_LAYER, - TARKIN_INVALID_COLOR_FORMAT, - TARKIN_VERSION, - TARKIN_BAD_HEADER, - TARKIN_NOT_TARKIN, - TARKIN_FAULT, - TARKIN_UNUSED, - TARKIN_NEED_MORE, - TARKIN_NOT_IMPLEMENTED -} TarkinError; - - - -typedef struct { - uint32_t width; - uint32_t height; - uint32_t a_moments; - uint32_t s_moments; - uint32_t frames_per_buf; - uint32_t bitstream_len; /* for all color components, bytes */ - TarkinColorFormat format; -} TarkinVideoLayerDesc; - - -typedef struct { - TarkinVideoLayerDesc desc; - uint32_t n_comp; /* number of color components */ - Wavelet3DBuf **waveletbuf; - TarkinPacket *packet; - uint32_t current_frame_in_buf; - uint32_t frameno; - - void (*color_fwd_xform) (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t count); - void (*color_inv_xform) (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t count); -} TarkinVideoLayer; - -typedef struct { - uint32_t numerator; - uint32_t denominator; -} TarkinTime; /* Let's say the unit is 1 second */ - -typedef struct TarkinInfo { - int version; - int n_layers; - TarkinVideoLayer *layer; - TarkinTime inter; /* numerator == O if per-frame time info. */ - int frames_per_block; - int comp_per_block; /* AKA "packets per block" for now */ - uint32_t max_bitstream_len; - - /* The below bitrate declarations are *hints*. - Combinations of the three values carry the following implications: - - all three set to the same value: - implies a fixed rate bitstream - only nominal set: - implies a VBR stream that averages the nominal bitrate. No hard - upper/lower limit - upper and or lower set: - implies a VBR bitstream that obeys the bitrate limits. nominal - may also be set to give a nominal rate. - none set: - the coder does not care to speculate. - */ - - long bitrate_upper; - long bitrate_nominal; - long bitrate_lower; - long bitrate_window; -} TarkinInfo; - -/* This is used for encoding */ -typedef struct { - unsigned char *header; - unsigned char *header1; - unsigned char *header2; -} tarkin_header_store; - - - - - /* Some of the fields in TarkinStream are redundent with TarkinInfo ones - * and will probably get deleted, namely n_layers and frames_per_buf */ -typedef struct TarkinStream { - uint32_t n_layers; - TarkinVideoLayer *layer; - uint32_t current_frame; - uint32_t current_frame_in_buf; - ogg_int64_t packetno; - uint32_t frames_per_buf; - uint32_t max_bitstream_len; - TarkinInfo *ti; - tarkin_header_store headers; - /* These callbacks are only used for encoding */ - TarkinError (*free_frame)(void *tarkinstream, void *ptr); - /* These thing allows not to buffer but it needs global var in caller. */ - TarkinError (*packet_out)(void *tarkinstream, ogg_packet *ptr); - void * user_ptr; -} TarkinStream; - - -typedef struct TarkinComment{ - /* unlimited user comment fields. libtarkin writes 'libtarkin' - whatever vendor is set to in encode */ - char **user_comments; - int *comment_lengths; - int comments; - char *vendor; - -} TarkinComment; - -/* Tarkin PRIMITIVES: general ***************************************/ - -/* The Tarkin header is in three packets, the initial small packet in - the first page that identifies basic parameters, that is a TarkinInfo - structure, a second packet with bitstream comments and a third packet - that holds the layers description structures. */ - - -/* Theses are the very same than Vorbis versions, they could be shared. */ -extern TarkinStream* tarkin_stream_new (); -extern void tarkin_stream_destroy (TarkinStream *s); -extern void tarkin_info_init(TarkinInfo *vi); -extern void tarkin_info_clear(TarkinInfo *vi); -extern void tarkin_comment_init(TarkinComment *vc); -extern void tarkin_comment_add(TarkinComment *vc, char *comment); -extern void tarkin_comment_add_tag(TarkinComment *vc, - char *tag, char *contents); -extern char *tarkin_comment_query(TarkinComment *vc, char *tag, int count); -extern int tarkin_comment_query_count(TarkinComment *vc, char *tag); -extern void tarkin_comment_clear(TarkinComment *vc); - -/* Tarkin PRIMITIVES: analysis layer ****************************/ -/* Tarkin encoding is done this way : you init it passing a fresh - * TarkinStream and a fresh TarkinInfo which has at least the rate_num - * field renseigned. You also pass it two callback functions: free_frame() - * is called when the lib doesn't need a frame anymore, and packet_out - * is called when a packet is ready. The pointers given as arguments to - * these callback functions are of course only valid at the function call - * time. The user_ptr is stored in s and can be used by packet_out(). */ -extern int tarkin_analysis_init(TarkinStream *s, - TarkinInfo *ti, - TarkinError (*free_frame)(void *tarkinstream, void *ptr), - TarkinError (*packet_out)(void *tarkinstream, ogg_packet *ptr), - void *user_ptr - ); -/* Then you need to add at least a layer in your stream, passing a - * TarkinVideoLayerDesc renseigned at least on the width, height and - * format parameters. */ -extern int tarkin_analysis_add_layer(TarkinStream *s, - TarkinVideoLayerDesc *tvld); -/* At that point you are ready to get headers out the lib by calling - * tarkin_analysis_headerout() passing it a renseigned TarkinComment - * structure. It does fill your 3 ogg_packet headers, which are valid - * till next call */ -extern int TarkinCommentheader_out(TarkinComment *vc, ogg_packet *op); -extern TarkinError tarkin_analysis_headerout(TarkinStream *s, - TarkinComment *vc, - ogg_packet *op, - ogg_packet *op_comm, - ogg_packet *op_code); -/* You are now ready to pass in frames to the codec, however don't free - * them before the codec told you so. It'll tell you when packets are - * ready to be taken out. When you have no more frame, simply pass NULL. - * If you encode multiple layers you have to do it synchronously, putting - * one frame from each layer at a time. */ -extern uint32_t tarkin_analysis_framein(TarkinStream *s, - uint8_t *frame, /* NULL for EOS */ - uint32_t layer, - TarkinTime *date); - -/* Tarkin PRIMITIVES: synthesis layer *******************************/ -/* For decoding, you needs first to give the three first packet of the - * stream to tarkin_synthesis_headerin() which will fill for you blank - * TarkinInfo and TarkinComment. */ -extern TarkinError tarkin_synthesis_headerin(TarkinInfo *vi,TarkinComment *vc, - ogg_packet *op); -/* Then you can init your stream with your TarkinInfo struct. */ -extern TarkinError tarkin_synthesis_init(TarkinStream *s,TarkinInfo *ti); -/* All subsequent packets are to this be passed to tarkin_synthesis_packetin*/ -extern TarkinError tarkin_synthesis_packetin(TarkinStream *s, ogg_packet *op); -/* and then tarkin_synthesis_frameout gives you ptr on next frame, or NULL. It - * also fills for you date. */ -extern TarkinError tarkin_synthesis_frameout(TarkinStream *s, - uint8_t **frame, uint32_t layer_id, TarkinTime *date); -/* When you're done with a frame, tell it to the codec with this. */ -extern int tarkin_synthesis_freeframe(TarkinStream *s, uint8_t *frame); - - -#endif - - - - - - diff --git a/ext/tarkin/wavelet.c b/ext/tarkin/wavelet.c deleted file mode 100644 index f6aeedc977..0000000000 --- a/ext/tarkin/wavelet.c +++ /dev/null @@ -1,124 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mem.h" -#include "wavelet.h" - -/* - * (The transform code is in wavelet_xform.c) - */ - - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MAX3(a,b,c) (MAX(a,MAX(b,c))) - - - -Wavelet3DBuf * -wavelet_3d_buf_new (uint32_t width, uint32_t height, uint32_t frames) -{ - Wavelet3DBuf *buf = (Wavelet3DBuf *) MALLOC (sizeof (Wavelet3DBuf)); - uint32_t _w = width; - uint32_t _h = height; - uint32_t _f = frames; - int level; - - if (!buf) - return NULL; - - buf->data = (TYPE *) MALLOC (width * height * frames * sizeof (TYPE)); - - if (!buf->data) { - wavelet_3d_buf_destroy (buf); - return NULL; - } - - buf->width = width; - buf->height = height; - buf->frames = frames; - buf->scales = 1; - - while (_w > 1 || _h > 1 || _f > 1) { - buf->scales++; - _w = (_w + 1) / 2; - _h = (_h + 1) / 2; - _f = (_f + 1) / 2; - } - - buf->w = (uint32_t *) MALLOC (buf->scales * sizeof (uint32_t)); - buf->h = (uint32_t *) MALLOC (buf->scales * sizeof (uint32_t)); - buf->f = (uint32_t *) MALLOC (buf->scales * sizeof (uint32_t)); - buf->offset = (uint32_t (*)[8]) MALLOC (8 * buf->scales * sizeof (uint32_t)); - - buf->scratchbuf = - (TYPE *) MALLOC (MAX3 (width, height, frames) * sizeof (TYPE)); - - if (!buf->w || !buf->h || !buf->f || !buf->offset || !buf->scratchbuf) { - wavelet_3d_buf_destroy (buf); - return NULL; - } - - buf->w[buf->scales - 1] = width; - buf->h[buf->scales - 1] = height; - buf->f[buf->scales - 1] = frames; - - for (level = buf->scales - 2; level >= 0; level--) { - buf->w[level] = (buf->w[level + 1] + 1) / 2; - buf->h[level] = (buf->h[level + 1] + 1) / 2; - buf->f[level] = (buf->f[level + 1] + 1) / 2; - buf->offset[level][0] = 0; - buf->offset[level][1] = buf->w[level]; - buf->offset[level][2] = buf->h[level] * width; - buf->offset[level][3] = buf->f[level] * width * height; - buf->offset[level][4] = buf->offset[level][2] + buf->w[level]; - buf->offset[level][5] = buf->offset[level][3] + buf->w[level]; - buf->offset[level][6] = buf->offset[level][3] + buf->offset[level][2]; - buf->offset[level][7] = buf->offset[level][6] + buf->w[level]; - } - - return buf; -} - - -void -wavelet_3d_buf_destroy (Wavelet3DBuf * buf) -{ - if (buf) { - if (buf->data) - FREE (buf->data); - if (buf->w) - FREE (buf->w); - if (buf->h) - FREE (buf->h); - if (buf->f) - FREE (buf->f); - if (buf->offset) - FREE (buf->offset); - if (buf->scratchbuf) - FREE (buf->scratchbuf); - FREE (buf); - } -} - - -#if defined(DBG_XFORM) - -#include "pnm.h" - -void -wavelet_3d_buf_dump (char *fmt, - uint32_t first_frame_in_buf, - uint32_t id, Wavelet3DBuf * buf, int16_t offset) -{ - char fname[256]; - uint32_t f; - - for (f = 0; f < buf->frames; f++) { - snprintf (fname, 256, fmt, id, first_frame_in_buf + f); - - write_pgm16 (fname, buf->data + f * buf->width * buf->height, - buf->width, buf->height, offset); - } -} -#endif diff --git a/ext/tarkin/wavelet.h b/ext/tarkin/wavelet.h deleted file mode 100644 index 6b7a7af4c0..0000000000 --- a/ext/tarkin/wavelet.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __WAVELET_H -#define __WAVELET_H - -#include "_stdint.h" - - -typedef struct { - TYPE *data; - uint32_t width; - uint32_t height; - uint32_t frames; - uint32_t scales; - uint32_t *w; - uint32_t *h; - uint32_t *f; - uint32_t (*offset)[8]; - TYPE *scratchbuf; -} Wavelet3DBuf; - - -extern Wavelet3DBuf* wavelet_3d_buf_new (uint32_t width, uint32_t height, - uint32_t frames); - -extern void wavelet_3d_buf_destroy (Wavelet3DBuf* buf); - -/* - * transform buf->data - * a_moments is the number of vanishing moments of the analyzing - * highpass filter, - * s_moments the one of the synthesizing lowpass filter. - */ -extern void wavelet_3d_buf_fwd_xform (Wavelet3DBuf* buf, - int a_moments, int s_moments); -extern void wavelet_3d_buf_inv_xform (Wavelet3DBuf* buf, - int a_moments, int s_moments); - -extern int wavelet_3d_buf_encode_coeff (const Wavelet3DBuf* buf, - uint8_t *bitstream, - uint32_t limit); - -extern void wavelet_3d_buf_decode_coeff (Wavelet3DBuf* buf, - uint8_t *bitstream, - uint32_t limit); - -#if defined(DBG_XFORM) -extern void wavelet_3d_buf_dump (char *fmt, - uint32_t first_frame_in_buf, - uint32_t id, - Wavelet3DBuf* buf, - int16_t offset); -#else -#define wavelet_3d_buf_dump(x...) -#endif - -#endif diff --git a/ext/tarkin/wavelet_coeff.c b/ext/tarkin/wavelet_coeff.c deleted file mode 100644 index fbe08f7813..0000000000 --- a/ext/tarkin/wavelet_coeff.c +++ /dev/null @@ -1,517 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mem.h" -#include "wavelet.h" -#include "rle.h" - -#define printf(args...) - -#define GRAY_CODES 1 - -#if defined(GRAY_CODES) -static inline uint16_t -binary_to_gray (uint16_t x) -{ - return x ^ (x >> 1); -} - -static inline uint16_t -gray_to_binary (uint16_t x) -{ - int i; - - for (i = 1; i < 16; i += i) - x ^= x >> i; - return x; -} -#endif - - -static inline void -encode_coeff (ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[], TYPE coeff) -{ - int sign = (coeff >> (8 * sizeof (TYPE) - 1)) & 1; - -#if defined(GRAY_CODES) - TYPE significance = binary_to_gray (coeff); -#else - static TYPE mask[2] = { 0, ~0 }; - TYPE significance = coeff ^ mask[sign]; -#endif - int i = TYPE_BITS; - - do { - i--; - OUTPUT_BIT (&significand_bitstream[i], (significance >> i) & 1); - } while (!((significance >> i) & 1) && i > 0); - - OUTPUT_BIT (&significand_bitstream[i], sign); - - while (--i >= 0) - OUTPUT_BIT (&insignificand_bitstream[i], (significance >> i) & 1); -} - - - -static inline TYPE -decode_coeff (ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[]) -{ -#if !defined(GRAY_CODES) - static TYPE mask[2] = { 0, ~0 }; -#endif - TYPE significance = 0; - int sign; - int i = TYPE_BITS; - - do { - i--; - significance |= INPUT_BIT (&significand_bitstream[i]) << i; -/* if (ENTROPY_CODER_EOS(&significand_bitstream[i])) */ -/* return 0; */ - } while (!significance && i > 0); - - sign = INPUT_BIT (&significand_bitstream[i]); -/* if (ENTROPY_CODER_EOS(&significand_bitstream[i])) */ -/* return 0; */ - - while (--i >= 0) - significance |= INPUT_BIT (&insignificand_bitstream[i]) << i; - -#if defined(GRAY_CODES) - significance |= sign << (8 * sizeof (TYPE) - 1); - return gray_to_binary (significance); -#else - return (significance ^ mask[sign]); -#endif -} - - -static inline uint32_t -skip_0coeffs (Wavelet3DBuf * buf, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[], uint32_t limit) -{ - int i; - uint32_t skip = limit; - - for (i = 0; i < TYPE_BITS; i++) { - if (ENTROPY_CODER_SYMBOL (&s_stream[i]) != 0) { - return 0; - } else { - uint32_t runlength = ENTROPY_CODER_RUNLENGTH (&s_stream[i]); - - if (i == 0) - runlength /= 2; /* sign bits are in this bitplane ... */ - if (skip > runlength) - skip = runlength; - if (skip <= 2) - return 0; - } - } - - ENTROPY_CODER_SKIP (&s_stream[0], 2 * skip); /* kill sign+significance bits */ - - for (i = 1; i < TYPE_BITS; i++) - ENTROPY_CODER_SKIP (&s_stream[i], skip); - - return skip; -} - - - -#if 1 -static inline void -encode_quadrant (const Wavelet3DBuf * buf, - int level, int quadrant, uint32_t w, uint32_t h, uint32_t f, - ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[]) -{ - uint32_t x, y, z; - - for (z = 0; z < f; z++) { - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - unsigned int index = buf->offset[level][quadrant] - + z * buf->width * buf->height + y * buf->width + x; - - encode_coeff (significand_bitstream, insignificand_bitstream, - buf->data[index]); - } - } - } -} - - -static void -encode_coefficients (const Wavelet3DBuf * buf, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[]) -{ - int level; - - encode_coeff (s_stream, i_stream, buf->data[0]); - - for (level = 0; level < buf->scales - 1; level++) { - uint32_t w, h, f, w1, h1, f1; - - w = buf->w[level]; - h = buf->h[level]; - f = buf->f[level]; - w1 = buf->w[level + 1] - w; - h1 = buf->h[level + 1] - h; - f1 = buf->f[level + 1] - f; - - if (w1 > 0) - encode_quadrant (buf, level, 1, w1, h, f, s_stream, i_stream); - if (h1 > 0) - encode_quadrant (buf, level, 2, w, h1, f, s_stream, i_stream); - if (f1 > 0) - encode_quadrant (buf, level, 3, w, h, f1, s_stream, i_stream); - if (w1 > 0 && h1 > 0) - encode_quadrant (buf, level, 4, w1, h1, f, s_stream, i_stream); - if (w1 > 0 && f1 > 0) - encode_quadrant (buf, level, 5, w1, h, f1, s_stream, i_stream); - if (h1 > 0 && f1 > 0) - encode_quadrant (buf, level, 6, w, h1, f1, s_stream, i_stream); - if (h1 > 0 && f1 > 0 && f1 > 0) - encode_quadrant (buf, level, 7, w1, h1, f1, s_stream, i_stream); - } -} - - -static inline void -decode_quadrant (Wavelet3DBuf * buf, - int level, int quadrant, uint32_t w, uint32_t h, uint32_t f, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[]) -{ - uint32_t x, y, z; - - z = 0; - do { - y = 0; - do { - x = 0; - do { - uint32_t skip; - uint32_t index = buf->offset[level][quadrant] - + z * buf->width * buf->height + y * buf->width + x; - - buf->data[index] = decode_coeff (s_stream, i_stream); - - skip = skip_0coeffs (buf, s_stream, i_stream, - (w - x - 1) + (h - y - 1) * w + (f - z - 1) * w * h); - if (skip > 0) { - x += skip; - while (x >= w) { - y++; - x -= w; - while (y >= h) { - z++; - y -= h; - if (z >= f) - return; - } - } - } - x++; - } while (x < w); - y++; - } while (y < h); - z++; - } while (z < f); -} - - -static void -decode_coefficients (Wavelet3DBuf * buf, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[]) -{ - int level; - - buf->data[0] = decode_coeff (s_stream, i_stream); - - for (level = 0; level < buf->scales - 1; level++) { - uint32_t w, h, f, w1, h1, f1; - - w = buf->w[level]; - h = buf->h[level]; - f = buf->f[level]; - w1 = buf->w[level + 1] - w; - h1 = buf->h[level + 1] - h; - f1 = buf->f[level + 1] - f; - - if (w1 > 0) - decode_quadrant (buf, level, 1, w1, h, f, s_stream, i_stream); - if (h1 > 0) - decode_quadrant (buf, level, 2, w, h1, f, s_stream, i_stream); - if (f1 > 0) - decode_quadrant (buf, level, 3, w, h, f1, s_stream, i_stream); - if (w1 > 0 && h1 > 0) - decode_quadrant (buf, level, 4, w1, h1, f, s_stream, i_stream); - if (w1 > 0 && f1 > 0) - decode_quadrant (buf, level, 5, w1, h, f1, s_stream, i_stream); - if (h1 > 0 && f1 > 0) - decode_quadrant (buf, level, 6, w, h1, f1, s_stream, i_stream); - if (h1 > 0 && f1 > 0 && f1 > 0) - decode_quadrant (buf, level, 7, w1, h1, f1, s_stream, i_stream); - } -} -#else - -static void -encode_coefficients (const Wavelet3DBuf * buf, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[]) -{ - uint32_t i; - - for (i = 0; i < buf->width * buf->height * buf->frames; i++) - encode_coeff (s_stream, i_stream, buf->data[i]); -} - - - - -static void -decode_coefficients (Wavelet3DBuf * buf, - ENTROPY_CODER s_stream[], ENTROPY_CODER i_stream[]) -{ - uint32_t i; - - for (i = 0; i < buf->width * buf->height * buf->frames; i++) { - uint32_t skip; - - buf->data[i] = decode_coeff (s_stream, i_stream); - - skip = skip_0coeffs (buf, s_stream, i_stream, - buf->width * buf->height * buf->frames - i); - i += skip; - } -} -#endif - - - -static uint32_t -setup_limittabs (ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[], - uint32_t significand_limittab[], - uint32_t insignificand_limittab[], uint32_t limit) -{ - uint32_t significand_limit; - uint32_t insignificand_limit; - uint32_t byte_count; - int i; - - assert (limit > 2 * TYPE_BITS * sizeof (uint32_t)); /* limit too small */ - - printf ("%s: limit == %u\n", __FUNCTION__, limit); - byte_count = 2 * TYPE_BITS * sizeof (uint32_t); /* 2 binary coded limittabs */ - limit -= byte_count; - printf ("%s: rem. limit == %u\n", __FUNCTION__, limit); - - significand_limit = limit * 7 / 8; - insignificand_limit = limit - significand_limit; - - printf ("%s: limit == %u\n", __FUNCTION__, limit); - printf ("significand limit == %u\n", significand_limit); - printf ("insignificand limit == %u\n", insignificand_limit); - - for (i = TYPE_BITS - 1; i >= 0; i--) { - uint32_t s_bytes, i_bytes; - - if (i > 0) { - significand_limittab[i] = (significand_limit + 1) / 2; - insignificand_limittab[i] = (insignificand_limit + 1) / 2; - } else { - significand_limittab[0] = significand_limit; - insignificand_limittab[0] = insignificand_limit; - } - - s_bytes = ENTROPY_ENCODER_FLUSH (&significand_bitstream[i]); - i_bytes = ENTROPY_ENCODER_FLUSH (&insignificand_bitstream[i]); - - if (s_bytes < significand_limittab[i]) - significand_limittab[i] = s_bytes; - - if (i_bytes < insignificand_limittab[i]) - insignificand_limittab[i] = i_bytes; - - byte_count += significand_limittab[i]; - byte_count += insignificand_limittab[i]; - - printf ("insignificand_limittab[%i] == %u / %u\n", - i, insignificand_limittab[i], i_bytes); - printf (" significand_limittab[%i] == %u / %u\n", - i, significand_limittab[i], s_bytes); - - significand_limit -= significand_limittab[i]; - insignificand_limit -= insignificand_limittab[i]; - } - - printf ("byte_count == %u\n", byte_count); - - return byte_count; -} - - -/** - * write 'em binary for now, should be easy to compress ... - */ -static uint8_t * -write_limittabs (uint8_t * bitstream, - uint32_t significand_limittab[], uint32_t insignificand_limittab[]) -{ - int i; - - for (i = 0; i < TYPE_BITS; i++) { - *(uint32_t *) bitstream = significand_limittab[i]; - bitstream += 4; - } - - for (i = 0; i < TYPE_BITS; i++) { - *(uint32_t *) bitstream = insignificand_limittab[i]; - bitstream += 4; - } - - return bitstream; -} - - -static uint8_t * -read_limittabs (uint8_t * bitstream, - uint32_t significand_limittab[], uint32_t insignificand_limittab[]) -{ - int i; - - for (i = 0; i < TYPE_BITS; i++) { - significand_limittab[i] = *(uint32_t *) bitstream; - printf ("significand_limittab[%i] == %u\n", i, significand_limittab[i]); - bitstream += 4; - } - - for (i = 0; i < TYPE_BITS; i++) { - insignificand_limittab[i] = *(uint32_t *) bitstream; - printf ("insignificand_limittab[%i] == %u\n", i, - insignificand_limittab[i]); - bitstream += 4; - } - - return bitstream; -} - - -/** - * concatenate entropy coder bitstreams - */ -static void -merge_bitstreams (uint8_t * bitstream, - ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[], - uint32_t significand_limittab[], uint32_t insignificand_limittab[]) -{ - int i; - - for (i = TYPE_BITS - 1; i >= 0; i--) { - memcpy (bitstream, - ENTROPY_CODER_BITSTREAM (&significand_bitstream[i]), - significand_limittab[i]); - - bitstream += significand_limittab[i]; - } - - for (i = TYPE_BITS - 1; i >= 0; i--) { - memcpy (bitstream, - ENTROPY_CODER_BITSTREAM (&insignificand_bitstream[i]), - insignificand_limittab[i]); - - bitstream += insignificand_limittab[i]; - } -} - - -static void -split_bitstreams (uint8_t * bitstream, - ENTROPY_CODER significand_bitstream[], - ENTROPY_CODER insignificand_bitstream[], - uint32_t significand_limittab[], uint32_t insignificand_limittab[]) -{ - uint32_t byte_count; - int i; - - for (i = TYPE_BITS - 1; i >= 0; i--) { - byte_count = significand_limittab[i]; - ENTROPY_DECODER_INIT (&significand_bitstream[i], bitstream, byte_count); - bitstream += byte_count; - } - - for (i = TYPE_BITS - 1; i >= 0; i--) { - byte_count = insignificand_limittab[i]; - ENTROPY_DECODER_INIT (&insignificand_bitstream[i], bitstream, byte_count); - bitstream += byte_count; - } -} - - -int -wavelet_3d_buf_encode_coeff (const Wavelet3DBuf * buf, - uint8_t * bitstream, uint32_t limit) -{ - ENTROPY_CODER significand_bitstream[TYPE_BITS]; - ENTROPY_CODER insignificand_bitstream[TYPE_BITS]; - uint32_t significand_limittab[TYPE_BITS]; - uint32_t insignificand_limittab[TYPE_BITS]; - uint32_t byte_count; - int i; - - for (i = 0; i < TYPE_BITS; i++) - ENTROPY_ENCODER_INIT (&significand_bitstream[i], limit); - for (i = 0; i < TYPE_BITS; i++) - ENTROPY_ENCODER_INIT (&insignificand_bitstream[i], limit); - - encode_coefficients (buf, significand_bitstream, insignificand_bitstream); - - byte_count = setup_limittabs (significand_bitstream, insignificand_bitstream, - significand_limittab, insignificand_limittab, limit); - - bitstream = write_limittabs (bitstream, - significand_limittab, insignificand_limittab); - - merge_bitstreams (bitstream, significand_bitstream, insignificand_bitstream, - significand_limittab, insignificand_limittab); - - for (i = 0; i < TYPE_BITS; i++) { - ENTROPY_ENCODER_DONE (&significand_bitstream[i]); - ENTROPY_ENCODER_DONE (&insignificand_bitstream[i]); - } - - return byte_count; -} - - -void -wavelet_3d_buf_decode_coeff (Wavelet3DBuf * buf, - uint8_t * bitstream, uint32_t byte_count) -{ - ENTROPY_CODER significand_bitstream[TYPE_BITS]; - ENTROPY_CODER insignificand_bitstream[TYPE_BITS]; - uint32_t significand_limittab[TYPE_BITS]; - uint32_t insignificand_limittab[TYPE_BITS]; - int i; - - memset (buf->data, 0, buf->width * buf->height * buf->frames * sizeof (TYPE)); - - bitstream = read_limittabs (bitstream, - significand_limittab, insignificand_limittab); - - split_bitstreams (bitstream, significand_bitstream, insignificand_bitstream, - significand_limittab, insignificand_limittab); - - decode_coefficients (buf, significand_bitstream, insignificand_bitstream); - - for (i = 0; i < TYPE_BITS; i++) { - ENTROPY_DECODER_DONE (&significand_bitstream[i]); - ENTROPY_DECODER_DONE (&insignificand_bitstream[i]); - } -} diff --git a/ext/tarkin/wavelet_xform.c b/ext/tarkin/wavelet_xform.c deleted file mode 100644 index c6eed7910a..0000000000 --- a/ext/tarkin/wavelet_xform.c +++ /dev/null @@ -1,421 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mem.h" -#include -#include "wavelet.h" - - - -static void -fwd_analyze_1 (const TYPE * x, TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - for (i = 0; i < k; i++) - d[i] = x[(2 * i + 1) * stride] - x[2 * i * stride]; -} - - -static void -fwd_synthesize_1 (const TYPE * x, TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - for (i = 0; i < k; i++) - s[i * stride] = x[2 * i * stride] + d[i] / 2; - if (n & 1) - s[k * stride] = x[2 * k * stride] + d[k - 1] / 2; -} - - -static void -inv_analyze_1 (TYPE * x, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - for (i = 0; i < k; i++) - x[(2 * i + 1) * stride] = d[i] + x[2 * i * stride]; -} - - -static void -inv_synthesize_1 (TYPE * x, const TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - for (i = 0; i < k; i++) - x[2 * i * stride] = s[i] - d[i] / 2; - if (n & 1) - x[2 * k * stride] = s[k] - d[k - 1] / 2; -} - - - -static void -fwd_analyze_2 (const TYPE * x, TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - if (n & 1) { - for (i = 0; i < k; i++) - d[i] = - x[(2 * i + 1) * stride] - (x[2 * i * stride] + x[(2 * i + - 2) * stride]) / 2; - } else { - for (i = 0; i < k - 1; i++) - d[i] = - x[(2 * i + 1) * stride] - (x[2 * i * stride] + x[(2 * i + - 2) * stride]) / 2; - d[k - 1] = x[(n - 1) * stride] - x[(n - 2) * stride]; - } -} - - - -static void -fwd_synthesize_2 (const TYPE * x, TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - s[0] = x[0] + d[1] / 2; - for (i = 1; i < k; i++) - s[i * stride] = x[2 * i * stride] + (d[i - 1] + d[i]) / 4; - if (n & 1) - s[k * stride] = x[2 * k * stride] + d[k - 1] / 2; -} - - -static inline void -inv_analyze_2 (TYPE * x, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - if (n & 1) { - for (i = 0; i < k; i++) - x[(2 * i + 1) * stride] = - d[i] + (x[2 * i * stride] + x[(2 * i + 2) * stride]) / 2; - } else { - for (i = 0; i < k - 1; i++) - x[(2 * i + 1) * stride] = - d[i] + (x[2 * i * stride] + x[(2 * i + 2) * stride]) / 2; - x[(n - 1) * stride] = d[k - 1] + x[(n - 2) * stride]; - } -} - - -static inline void -inv_synthesize_2 (TYPE * x, const TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - x[0] = s[0] - d[1] / 2; - for (i = 1; i < k; i++) - x[2 * i * stride] = s[i] - (d[i - 1] + d[i]) / 4; - if (n & 1) - x[2 * k * stride] = s[k] - d[k - 1] / 2; -} - - - -static void -fwd_analyze_4 (const TYPE * x, TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - d[0] = x[stride] - (x[0] + x[2 * stride]) / 2; - - if (n & 1) { - for (i = 1; i < k - 1; i++) - d[i] = x[(2 * i + 1) * stride] - - ((uint32_t) 9 * (x[2 * i * stride] + x[(2 * i + 2) * stride]) - - (x[(2 * i - 2) * stride] + x[(2 * i + 4) * stride])) / 16; - if (k > 1) - d[k - 1] = - x[(2 * k - 1) * stride] - (x[(2 * k - 2) * stride] + - x[2 * k * stride]) / 2; - } else { - for (i = 1; i < k - 2; i++) - d[i] = x[(2 * i + 1) * stride] - - ((uint32_t) 9 * (x[2 * i * stride] + x[(2 * i + 2) * stride]) - - (x[(2 * i - 2) * stride] + x[(2 * i + 4) * stride])) / 16; - if (k > 2) - d[k - 2] = x[(2 * k - 3) * stride] - (x[(2 * k - 4) * stride] - + x[(2 * k - 2) * stride]) / 2; - if (k > 1) - d[k - 1] = x[(n - 1) * stride] - x[(n - 2) * stride]; - } -} - - -static void -fwd_synthesize_4 (const TYPE * x, TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - s[0] = x[0] + d[1] / 2; - if (k > 1) - s[stride] = x[2 * stride] + (d[0] + d[1]) / 4; - for (i = 2; i < k - 1; i++) - s[i * stride] = x[2 * i * stride] - + ((uint32_t) 9 * (d[i - 1] + d[i]) - (d[i - 2] + d[i + 1])) / 32; - if (k > 2) - s[(k - 1) * stride] = x[(2 * k - 2) * stride] + (d[k - 2] + d[k - 1]) / 4; - if (n & 1) - s[k * stride] = x[2 * k * stride] + d[k - 1] / 2; -} - - -static void -inv_analyze_4 (TYPE * x, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - x[stride] = d[0] + (x[0] + x[2 * stride]) / 2; - - if (n & 1) { - for (i = 1; i < k - 1; i++) - x[(2 * i + 1) * stride] = d[i] - + ((uint32_t) 9 * (x[2 * i * stride] + x[(2 * i + 2) * stride]) - - (x[(2 * i - 2) * stride] + x[(2 * i + 4) * stride])) / 16; - if (k > 1) - x[(2 * k - 1) * stride] = - d[k - 1] + (x[(2 * k - 2) * stride] + x[2 * k * stride]) / 2; - } else { - for (i = 1; i < k - 2; i++) - x[(2 * i + 1) * stride] = d[i] - + (9 * (x[2 * i * stride] + x[(2 * i + 2) * stride]) - - (x[(2 * i - 2) * stride] + x[(2 * i + 4) * stride])) / 16; - if (k > 2) - x[(2 * k - 3) * stride] = d[k - 2] + (x[(2 * k - 4) * stride] - + x[(2 * k - 2) * stride]) / 2; - if (k > 1) - x[(n - 1) * stride] = d[k - 1] + x[(n - 2) * stride]; - } -} - - -static void -inv_synthesize_4 (TYPE * x, const TYPE * s, const TYPE * d, int stride, int n) -{ - int i, k = n / 2; - - x[0] = s[0] - d[1] / 2; - if (k > 1) - x[2 * stride] = s[1] - (d[0] + d[1]) / 4; - for (i = 2; i < k - 1; i++) - x[2 * i * stride] = s[i] - ((uint32_t) 9 * (d[i - 1] + d[i]) - - (d[i - 2] + d[i + 1])) / 32; - if (k > 2) - x[(2 * k - 2) * stride] = s[k - 1] - (d[k - 2] + d[k - 1]) / 4; - if (n & 1) - x[2 * k * stride] = s[k] - d[k - 1] / 2; -} - - -static inline void -copyback_d (TYPE * x, const TYPE * d, int stride, int n) -{ - int i, j, k = n / 2; - - for (i = n - k, j = 0; i < n; i++, j++) - x[i * stride] = d[j]; -} - - -static inline void -copy_s_d (const TYPE * x, TYPE * s_d, int stride, int n) -{ - int i; - - for (i = 0; i < n; i++) - s_d[i] = x[i * stride]; -} - - - -typedef - void (*FwdSFnc) (const TYPE * x, TYPE * s, const TYPE * d, int stride, - int n); - -typedef void (*FwdAFnc) (const TYPE * x, TYPE * d, int stride, int n); - -typedef - void (*InvSFnc) (TYPE * x, const TYPE * s, const TYPE * d, int stride, - int n); - -typedef void (*InvAFnc) (TYPE * x, const TYPE * d, int stride, int n); - - - -static FwdSFnc fwd_synthesize[] = { NULL, fwd_synthesize_1, fwd_synthesize_2, - NULL, fwd_synthesize_4 -}; - -static FwdAFnc fwd_analyze[] = { NULL, fwd_analyze_1, fwd_analyze_2, - NULL, fwd_analyze_4 -}; - -static InvSFnc inv_synthesize[] = { NULL, inv_synthesize_1, inv_synthesize_2, - NULL, inv_synthesize_4 -}; - -static InvAFnc inv_analyze[] = { NULL, inv_analyze_1, inv_analyze_2, - NULL, inv_analyze_4 -}; - - - -static inline void -fwd_xform (TYPE * scratchbuf, TYPE * data, int stride, int n, - int a_moments, int s_moments) -{ - TYPE *x = data; - TYPE *d = scratchbuf; - TYPE *s = data; - - assert (a_moments == 1 || a_moments == 2 || a_moments == 4); - assert (s_moments == 1 || s_moments == 2 || s_moments == 4); - - /* XXX FIXME: Ugly hack to work around */ - /* the short-row bug in high */ - /* order xform functions */ - if (n < 9) - a_moments = s_moments = 2; - if (n < 5) - a_moments = s_moments = 1; - - fwd_analyze[a_moments] (x, d, stride, n); - fwd_synthesize[s_moments] (x, s, d, stride, n); - copyback_d (x, d, stride, n); -} - - -static inline void -inv_xform (TYPE * scratchbuf, TYPE * data, int stride, int n, - int a_moments, int s_moments) -{ - int k = n / 2; - TYPE *x = data; - TYPE *s = scratchbuf; - TYPE *d = scratchbuf + n - k; - - assert (a_moments == 1 || a_moments == 2 || a_moments == 4); - assert (s_moments == 1 || s_moments == 2 || s_moments == 4); - - /* XXX FIXME: Ugly hack to work around */ - /* the short-row bug in high */ - /* order xform functions */ - if (n < 9) - a_moments = s_moments = 2; - if (n < 5) - a_moments = s_moments = 1; - - copy_s_d (data, scratchbuf, stride, n); - inv_synthesize[s_moments] (x, s, d, stride, n); - inv_analyze[a_moments] (x, d, stride, n); -} - - - -void -wavelet_3d_buf_fwd_xform (Wavelet3DBuf * buf, int a_moments, int s_moments) -{ - int level; - - for (level = buf->scales - 1; level > 0; level--) { - uint32_t w = buf->w[level]; - uint32_t h = buf->h[level]; - uint32_t f = buf->f[level]; - - if (w > 1) { - int row, frame; - - for (frame = 0; frame < f; frame++) { - for (row = 0; row < h; row++) { - TYPE *data = buf->data + (frame * buf->height + row) * buf->width; - - fwd_xform (buf->scratchbuf, data, 1, w, a_moments, s_moments); - } - } - } - - if (h > 1) { - int col, frame; - - for (frame = 0; frame < f; frame++) { - for (col = 0; col < w; col++) { - TYPE *data = buf->data + frame * buf->width * buf->height + col; - - fwd_xform (buf->scratchbuf, data, buf->width, h, - a_moments, s_moments); - } - } - } - - if (f > 1) { - int i, j; - - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - TYPE *data = buf->data + j * buf->width + i; - - fwd_xform (buf->scratchbuf, data, buf->width * buf->height, f, - a_moments, s_moments); - } - } - } - } -} - - -void -wavelet_3d_buf_inv_xform (Wavelet3DBuf * buf, int a_moments, int s_moments) -{ - int level; - - for (level = 1; level < buf->scales; level++) { - uint32_t w = buf->w[level]; - uint32_t h = buf->h[level]; - uint32_t f = buf->f[level]; - - if (f > 1) { - int i, j; - - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - TYPE *data = buf->data + j * buf->width + i; - - inv_xform (buf->scratchbuf, data, buf->width * buf->height, f, - a_moments, s_moments); - } - } - } - - if (h > 1) { - int col, frame; - - for (frame = 0; frame < f; frame++) { - for (col = 0; col < w; col++) { - TYPE *data = buf->data + frame * buf->width * buf->height + col; - - inv_xform (buf->scratchbuf, data, buf->width, h, - a_moments, s_moments); - } - } - } - - if (w > 1) { - int row, frame; - - for (frame = 0; frame < f; frame++) { - for (row = 0; row < h; row++) { - TYPE *data = buf->data + (frame * buf->height + row) * buf->width; - - inv_xform (buf->scratchbuf, data, 1, w, a_moments, s_moments); - } - } - } - } -} diff --git a/ext/tarkin/yuv.c b/ext/tarkin/yuv.c deleted file mode 100644 index d781a3c8f2..0000000000 --- a/ext/tarkin/yuv.c +++ /dev/null @@ -1,234 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "yuv.h" - -/*#define TARKIN_YUV_EXACT*/ -/*#define TARKIN_YUV_LXY*/ - - -static inline uint8_t -CLAMP (int16_t x) -{ - return ((x > 255) ? 255 : (x < 0) ? 0 : x); -} - - - -void -rgb24_to_yuv (uint8_t * rgb, Wavelet3DBuf * yuv[], uint32_t frame) -{ - int count = yuv[0]->width * yuv[0]->height; - int16_t *y = yuv[0]->data + frame * count; - int16_t *u = yuv[1]->data + frame * count; - int16_t *v = yuv[2]->data + frame * count; - int i; - - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgb += 3) { - y[i] = ((int16_t) 77 * rgb[0] + 150 * rgb[1] + 29 * rgb[2]) / 256; - u[i] = ((int16_t) - 44 * rgb[0] - 87 * rgb[1] + 131 * rgb[2]) / 256; - v[i] = ((int16_t) 131 * rgb[0] - 110 * rgb[1] - 21 * rgb[2]) / 256; - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgb += 3) { - y[i] = ((int16_t) 54 * rgb[0] + 182 * rgb[1] + 18 * rgb[2]) / 256; - u[i] = rgb[0] - y[i]; - v[i] = rgb[2] - y[i]; - } -#else - for (i = 0; i < count; i++, rgb += 3) { - v[i] = rgb[0] - rgb[1]; - u[i] = rgb[2] - rgb[1]; - y[i] = rgb[1] + (u[i] + v[i]) / 4; - } -#endif -} - - -void -yuv_to_rgb24 (Wavelet3DBuf * yuv[], uint8_t * rgb, uint32_t frame) -{ - int count = yuv[0]->width * yuv[0]->height; - int16_t *y = yuv[0]->data + frame * count; - int16_t *u = yuv[1]->data + frame * count; - int16_t *v = yuv[2]->data + frame * count; - int i; - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgb += 3) { - rgb[0] = CLAMP (y[i] + 1.371 * v[i]); - rgb[1] = CLAMP (y[i] - 0.698 * v[i] - 0.336 * u[i]); - rgb[2] = CLAMP (y[i] + 1.732 * u[i]); - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgb += 3) { - rgb[1] = CLAMP (y[i] - (76 * u[i] - 26 * v[i]) / 256); - rgb[0] = CLAMP (y[i] + u[i]); - rgb[2] = CLAMP (y[i] + v[i]); - } -#else - for (i = 0; i < count; i++, rgb += 3) { - rgb[1] = CLAMP (y[i] - (u[i] + v[i]) / 4); - rgb[2] = CLAMP (u[i] + rgb[1]); - rgb[0] = CLAMP (v[i] + rgb[1]); - } -#endif -} - - -void -rgb32_to_yuv (uint8_t * rgb, Wavelet3DBuf * yuv[], uint32_t frame) -{ - int count = yuv[0]->width * yuv[0]->height; - int16_t *y = yuv[0]->data + frame * count; - int16_t *u = yuv[1]->data + frame * count; - int16_t *v = yuv[2]->data + frame * count; - int i; - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgb += 4) { - y[i] = ((int16_t) 77 * rgb[0] + 150 * rgb[1] + 29 * rgb[2]) / 256; - u[i] = ((int16_t) - 44 * rgb[0] - 87 * rgb[1] + 131 * rgb[2]) / 256; - v[i] = ((int16_t) 131 * rgb[0] - 110 * rgb[1] - 21 * rgb[2]) / 256; - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgb += 4) { - y[i] = ((int16_t) 54 * rgb[0] + 182 * rgb[1] + 18 * rgb[2]) / 256; - u[i] = rgb[0] - y[i]; - v[i] = rgb[2] - y[i]; - } -#else - for (i = 0; i < count; i++, rgb += 4) { - v[i] = rgb[0] - rgb[1]; - u[i] = rgb[2] - rgb[1]; - y[i] = rgb[1] + (u[i] + v[i]) / 4; - } -#endif -} - - -void -yuv_to_rgb32 (Wavelet3DBuf * yuv[], uint8_t * rgb, uint32_t frame) -{ - int count = yuv[0]->width * yuv[0]->height; - int16_t *y = yuv[0]->data + frame * count; - int16_t *u = yuv[1]->data + frame * count; - int16_t *v = yuv[2]->data + frame * count; - int i; - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgb += 4) { - rgb[0] = CLAMP (y[i] + 1.371 * v[i]); - rgb[1] = CLAMP (y[i] - 0.698 * v[i] - 0.336 * u[i]); - rgb[2] = CLAMP (y[i] + 1.732 * u[i]); - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgb += 4) { - rgb[1] = CLAMP (y[i] - (76 * u[i] - 26 * v[i]) / 256); - rgb[0] = CLAMP (y[i] + u[i]); - rgb[2] = CLAMP (y[i] + v[i]); - } -#else - for (i = 0; i < count; i++, rgb += 4) { - rgb[1] = CLAMP (y[i] - (u[i] + v[i]) / 4); - rgb[2] = CLAMP (u[i] + rgb[1]); - rgb[0] = CLAMP (v[i] + rgb[1]); - } -#endif -} - - -void -rgba_to_yuv (uint8_t * rgba, Wavelet3DBuf * yuva[], uint32_t frame) -{ - int count = yuva[0]->width * yuva[0]->height; - int16_t *y = yuva[0]->data + frame * count; - int16_t *u = yuva[1]->data + frame * count; - int16_t *v = yuva[2]->data + frame * count; - int16_t *a = yuva[3]->data + frame * count; - int i; - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgba += 4) { - y[i] = ((int16_t) 77 * rgba[0] + 150 * rgba[1] + 29 * rgba[2]) / 256; - u[i] = ((int16_t) - 44 * rgba[0] - 87 * rgba[1] + 131 * rgba[2]) / 256; - v[i] = ((int16_t) 131 * rgba[0] - 110 * rgba[1] - 21 * rgba[2]) / 256; - a[i] = rgba[3]; - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgba += 4) { - y[i] = ((int16_t) 54 * rgba[0] + 182 * rgba[1] + 18 * rgba[2]) / 256; - u[i] = rgba[0] - y[i]; - v[i] = rgba[2] - y[i]; - a[i] = rgba[3]; - } -#else - for (i = 0; i < count; i++, rgba += 4) { - v[i] = rgba[0] - rgba[1]; - u[i] = rgba[2] - rgba[1]; - y[i] = rgba[1] + (u[i] + v[i]) / 4; - a[i] = rgba[3]; - } -#endif -} - - -void -yuv_to_rgba (Wavelet3DBuf * yuva[], uint8_t * rgba, uint32_t frame) -{ - int count = yuva[0]->width * yuva[0]->height; - int16_t *y = yuva[0]->data + frame * count; - int16_t *u = yuva[1]->data + frame * count; - int16_t *v = yuva[2]->data + frame * count; - int16_t *a = yuva[3]->data + frame * count; - int i; - -#if defined(TARKIN_YUV_EXACT) - for (i = 0; i < count; i++, rgba += 4) { - rgba[0] = CLAMP (y[i] + 1.371 * v[i]); - rgba[1] = CLAMP (y[i] - 0.698 * v[i] - 0.336 * u[i]); - rgba[2] = CLAMP (y[i] + 1.732 * u[i]); - rgba[3] = a[i]; - } -#elif defined(TARKIN_YUV_LXY) - for (i = 0; i < count; i++, rgba += 4) { - rgba[1] = CLAMP (y[i] - (76 * u[i] - 26 * v[i]) / 256); - rgba[0] = CLAMP (y[i] + u[i]); - rgba[2] = CLAMP (y[i] + v[i]); - rgba[3] = a[i]; - } -#else - for (i = 0; i < count; i++, rgba += 4) { - rgba[1] = CLAMP (y[i] - (u[i] + v[i]) / 4); - rgba[2] = CLAMP (u[i] + rgba[1]); - rgba[0] = CLAMP (v[i] + rgba[1]); - rgba[3] = a[i]; - } -#endif -} - -void -grayscale_to_y (uint8_t * rgba, Wavelet3DBuf * y[], uint32_t frame) -{ - int count = y[0]->width * y[0]->height; - int16_t *_y = y[0]->data + frame * count; - int i; - - for (i = 0; i < count; i++) - _y[i] = rgba[i]; -} - - -void -y_to_grayscale (Wavelet3DBuf * y[], uint8_t * rgba, uint32_t frame) -{ - int count = y[0]->width * y[0]->height; - int16_t *_y = y[0]->data + frame * count; - int i; - - for (i = 0; i < count; i++) - rgba[i] = CLAMP (_y[i]); -} diff --git a/ext/tarkin/yuv.h b/ext/tarkin/yuv.h deleted file mode 100644 index 036fc3549b..0000000000 --- a/ext/tarkin/yuv.h +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef __YUV_H -#define __YUV_H - -#include "_stdint.h" -#include "wavelet.h" - -extern void rgb24_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame); -extern void yuv_to_rgb24 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame); - -extern void rgb32_to_yuv (uint8_t *rgb, Wavelet3DBuf *yuv [], uint32_t frame); -extern void yuv_to_rgb32 (Wavelet3DBuf *yuv [], uint8_t *rgb, uint32_t frame); - -extern void rgba_to_yuv (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t frame); -extern void yuv_to_rgba (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t frame); - -extern void grayscale_to_y (uint8_t *rgba, Wavelet3DBuf *y [], uint32_t frame); -extern void y_to_grayscale (Wavelet3DBuf *y [], uint8_t *rgba, uint32_t frame); - -#endif - diff --git a/ext/theora/Makefile.am b/ext/theora/Makefile.am deleted file mode 100644 index 91702a5e56..0000000000 --- a/ext/theora/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -### FIXME: rename directory to theoraexp - -plugin_LTLIBRARIES = libgsttheoraexp.la - -noinst_HEADERS = theoradec.h - -libgsttheoraexp_la_SOURCES = theoradec.c -libgsttheoraexp_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(THEORADEC_CFLAGS) -libgsttheoraexp_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) \ - -lgsttag-$(GST_MAJORMINOR) \ - $(GST_LIBS) \ - $(THEORADEC_LIBS) -libgsttheoraexp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgsttheoraexp_la_LIBTOOLFLAGS = --tag=disable-static - diff --git a/ext/theora/theoradec.c b/ext/theora/theoradec.c deleted file mode 100644 index f5dba2f773..0000000000 --- a/ext/theora/theoradec.c +++ /dev/null @@ -1,1412 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Benjamin Otte - * 2006 Michael Smith - * - * 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. - */ - -/** - * SECTION:element-theoradecexp - * @see_also: theoradec, theoraenc, oggdemux - * - * This element decodes theora streams into raw video using the theora-exp - * decoder - * Theora is a royalty-free - * video codec maintained by the Xiph.org - * Foundation, based on the VP3 codec. - * - * - * Example pipeline - * |[ - * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoraexpdec ! xvimagesink - * ]| This example pipeline will demux an ogg stream and decode the theora video, - * displaying it on screen. - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "theoradec.h" -#include - -GST_DEBUG_CATEGORY_STATIC (theoradecexp_debug); -#define GST_CAT_DEFAULT theoradecexp_debug - -static GstStaticPadTemplate theora_dec_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-yuv, " - "format = (fourcc) { I420, YUY2, Y444 }, " - "framerate = (fraction) [0/1, MAX], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") - ); - -static GstStaticPadTemplate theora_dec_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-theora") - ); - -GST_BOILERPLATE (GstTheoraExpDec, gst_theoradec, GstElement, GST_TYPE_ELEMENT); - -static gboolean theora_dec_sink_event (GstPad * pad, GstEvent * event); -static GstFlowReturn theora_dec_chain (GstPad * pad, GstBuffer * buffer); -static GstStateChangeReturn theora_dec_change_state (GstElement * element, - GstStateChange transition); -static gboolean theora_dec_src_event (GstPad * pad, GstEvent * event); -static gboolean theora_dec_src_query (GstPad * pad, GstQuery * query); -static gboolean theora_dec_src_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value); -static gboolean theora_dec_sink_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value); -static gboolean theora_dec_sink_query (GstPad * pad, GstQuery * query); - -static const GstQueryType *theora_get_query_types (GstPad * pad); - -static void -gst_theoradec_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&theora_dec_src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&theora_dec_sink_factory)); - gst_element_class_set_details_simple (element_class, "Theora video decoder", - "Codec/Decoder/Video", - "decode raw theora streams to raw YUV video using libtheoradec", - "Benjamin Otte , " - "Wim Taymans , " "Michael Smith "); -} - -static void -gst_theoradec_class_init (GstTheoraExpDecClass * klass) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - - gstelement_class->change_state = theora_dec_change_state; - - GST_DEBUG_CATEGORY_INIT (theoradecexp_debug, "theoradecexp", 0, - "Theora decoder"); -} - -static void -gst_theoradec_init (GstTheoraExpDec * dec, GstTheoraExpDecClass * g_class) -{ - dec->sinkpad = - gst_pad_new_from_static_template (&theora_dec_sink_factory, "sink"); - gst_pad_set_query_function (dec->sinkpad, theora_dec_sink_query); - gst_pad_set_event_function (dec->sinkpad, theora_dec_sink_event); - gst_pad_set_chain_function (dec->sinkpad, theora_dec_chain); - gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad); - - dec->srcpad = - gst_pad_new_from_static_template (&theora_dec_src_factory, "src"); - gst_pad_set_event_function (dec->srcpad, theora_dec_src_event); - gst_pad_set_query_type_function (dec->srcpad, theora_get_query_types); - gst_pad_set_query_function (dec->srcpad, theora_dec_src_query); - gst_pad_use_fixed_caps (dec->srcpad); - - gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); - - dec->queued = NULL; -} - -static void -gst_theoradec_reset (GstTheoraExpDec * dec) -{ - GList *walk; - - dec->need_keyframe = TRUE; - dec->last_timestamp = -1; - dec->granulepos = -1; - dec->discont = TRUE; - dec->frame_nr = -1; - gst_segment_init (&dec->segment, GST_FORMAT_TIME); - - GST_OBJECT_LOCK (dec); - dec->proportion = 1.0; - dec->earliest_time = -1; - GST_OBJECT_UNLOCK (dec); - - for (walk = dec->queued; walk; walk = g_list_next (walk)) { - gst_buffer_unref (GST_BUFFER_CAST (walk->data)); - } - g_list_free (dec->queued); - dec->queued = NULL; -} - -static gint64 -inc_granulepos (GstTheoraExpDec * dec, gint64 granulepos) -{ - gint framecount; - - if (granulepos == -1) - return -1; - - framecount = th_granule_frame (dec->dec, granulepos); - - return (framecount + 1) << dec->info.keyframe_granule_shift; -} - -static const GstQueryType * -theora_get_query_types (GstPad * pad) -{ - static const GstQueryType theora_src_query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - 0 - }; - - return theora_src_query_types; -} - -static GstClockTime -gst_theoradec_granule_clocktime (GstTheoraExpDec * dec, ogg_int64_t granulepos) -{ - /* Avoid using theora_granule_time, which returns a double (in seconds); not - * what we want - */ - if (granulepos >= 0) { - guint64 framecount = th_granule_frame (dec->dec, granulepos); - - return gst_util_uint64_scale_int (framecount * GST_SECOND, - dec->info.fps_denominator, dec->info.fps_numerator); - } - return -1; -} - -static gboolean -theora_dec_src_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - GstTheoraExpDec *dec; - guint64 scale = 1; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - /* we need the info part before we can done something */ - if (!dec->have_header) - goto no_header; - - switch (src_format) { - case GST_FORMAT_BYTES: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - *dest_value = gst_util_uint64_scale_int (src_value, 8, - dec->info.pic_height * dec->info.pic_width * dec->output_bpp); - break; - case GST_FORMAT_TIME: - /* seems like a rather silly conversion, implement me if you like */ - default: - res = FALSE; - } - break; - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_BYTES: - scale = dec->output_bpp * - (dec->info.pic_width * dec->info.pic_height) / 8; - case GST_FORMAT_DEFAULT: - if (dec->info.fps_numerator && dec->info.fps_denominator) - *dest_value = scale * gst_util_uint64_scale (src_value, - dec->info.fps_numerator, - dec->info.fps_denominator * GST_SECOND); - else - res = FALSE; - break; - default: - res = FALSE; - } - break; - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - if (dec->info.fps_numerator && dec->info.fps_denominator) - *dest_value = gst_util_uint64_scale (src_value, - GST_SECOND * dec->info.fps_denominator, - dec->info.fps_numerator); - else - res = FALSE; - break; - case GST_FORMAT_BYTES: - *dest_value = gst_util_uint64_scale_int (src_value, - dec->output_bpp * dec->info.pic_width * dec->info.pic_height, 8); - break; - default: - res = FALSE; - } - break; - default: - res = FALSE; - } -done: - gst_object_unref (dec); - return res; - - /* ERRORS */ -no_header: - { - GST_DEBUG_OBJECT (dec, "no header yet, cannot convert"); - res = FALSE; - goto done; - } -} - -static gboolean -theora_dec_sink_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - GstTheoraExpDec *dec; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - /* we need the info part before we can done something */ - if (!dec->have_header) - goto no_header; - - switch (src_format) { - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = gst_theoradec_granule_clocktime (dec, src_value); - break; - default: - res = FALSE; - } - break; - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - { - guint rest; - - if (!dec->info.fps_numerator || !dec->info.fps_denominator) { - res = FALSE; - break; - } - - /* framecount */ - *dest_value = gst_util_uint64_scale (src_value, - dec->info.fps_numerator, GST_SECOND * dec->info.fps_denominator); - - /* funny way of calculating granulepos in theora */ - rest = *dest_value / (1 << dec->info.keyframe_granule_shift); - *dest_value -= rest; - *dest_value <<= dec->info.keyframe_granule_shift; - *dest_value += rest; - break; - } - default: - res = FALSE; - break; - } - break; - default: - res = FALSE; - } -done: - gst_object_unref (dec); - return res; - - /* ERRORS */ -no_header: - { - GST_DEBUG_OBJECT (dec, "no header yet, cannot convert"); - res = FALSE; - goto done; - } -} - -static gboolean -theora_dec_src_query (GstPad * pad, GstQuery * query) -{ - GstTheoraExpDec *dec; - - gboolean res = FALSE; - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION: - { - gint64 granulepos, value; - GstFormat my_format, format; - gint64 time; - - /* we can convert a granule position to everything */ - granulepos = dec->granulepos; - - GST_LOG_OBJECT (dec, - "query %p: we have current granule: %lld", query, granulepos); - - /* parse format */ - gst_query_parse_position (query, &format, NULL); - - /* and convert to the final format in two steps with time as the - * intermediate step */ - my_format = GST_FORMAT_TIME; - if (!(res = - theora_dec_sink_convert (dec->sinkpad, GST_FORMAT_DEFAULT, - granulepos, &my_format, &time))) - goto error; - - time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); - - GST_LOG_OBJECT (dec, - "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time)); - - if (!(res = - theora_dec_src_convert (pad, my_format, time, &format, &value))) - goto error; - - gst_query_set_position (query, format, value); - - GST_LOG_OBJECT (dec, - "query %p: we return %lld (format %u)", query, value, format); - - break; - } - case GST_QUERY_DURATION: - { - /* forward to peer for total */ - GstPad *peer; - - if (!(peer = gst_pad_get_peer (dec->sinkpad))) - goto error; - - res = gst_pad_query (peer, query); - gst_object_unref (peer); - if (!res) - goto error; - break; - } - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - if (!(res = - theora_dec_src_convert (pad, src_fmt, src_val, &dest_fmt, - &dest_val))) - goto error; - - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } -done: - gst_object_unref (dec); - - return res; - - /* ERRORS */ -error: - { - GST_DEBUG_OBJECT (dec, "query failed"); - goto done; - } -} - -static gboolean -theora_dec_sink_query (GstPad * pad, GstQuery * query) -{ - gboolean res = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - if (!(res = - theora_dec_sink_convert (pad, src_fmt, src_val, &dest_fmt, - &dest_val))) - goto error; - - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - -error: - return res; -} - -static gboolean -theora_dec_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - GstTheoraExpDec *dec; - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - GstFormat format, tformat; - gdouble rate; - GstEvent *real_seek; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gint64 tcur, tstop; - - gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, - &stop_type, &stop); - gst_event_unref (event); - - /* we have to ask our peer to seek to time here as we know - * nothing about how to generate a granulepos from the src - * formats or anything. - * - * First bring the requested format to time - */ - tformat = GST_FORMAT_TIME; - if (!(res = theora_dec_src_convert (pad, format, cur, &tformat, &tcur))) - goto convert_error; - if (!(res = theora_dec_src_convert (pad, format, stop, &tformat, &tstop))) - goto convert_error; - - /* then seek with time on the peer */ - real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, - flags, cur_type, tcur, stop_type, tstop); - - res = gst_pad_push_event (dec->sinkpad, real_seek); - - gst_event_unref (event); - break; - } - case GST_EVENT_QOS: - { - gdouble proportion; - GstClockTimeDiff diff; - GstClockTime timestamp; - - gst_event_parse_qos (event, &proportion, &diff, ×tamp); - - /* we cannot randomly skip frame decoding since we don't have - * B frames. we can however use the timestamp and diff to not - * push late frames. This would let us save the time for copying and - * cropping the frame. */ - GST_OBJECT_LOCK (dec); - dec->proportion = proportion; - dec->earliest_time = timestamp + diff; - GST_OBJECT_UNLOCK (dec); - - res = gst_pad_event_default (pad, event); - break; - } - default: - res = gst_pad_event_default (pad, event); - break; - } -done: - gst_object_unref (dec); - - return res; - - /* ERRORS */ -convert_error: - { - GST_DEBUG_OBJECT (dec, "could not convert format"); - goto done; - } -} - -static gboolean -theora_dec_sink_event (GstPad * pad, GstEvent * event) -{ - gboolean ret = FALSE; - GstTheoraExpDec *dec; - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - GST_LOG_OBJECT (dec, "handling event"); - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - ret = gst_pad_push_event (dec->srcpad, event); - break; - case GST_EVENT_FLUSH_STOP: - /* TODO: Call appropriate func with OC_DECCTL_SET_GRANPOS? */ - gst_theoradec_reset (dec); - ret = gst_pad_push_event (dec->srcpad, event); - break; - case GST_EVENT_EOS: - ret = gst_pad_push_event (dec->srcpad, event); - break; - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - /* we need TIME and a positive rate */ - if (format != GST_FORMAT_TIME) - goto newseg_wrong_format; - - if (rate <= 0.0) - goto newseg_wrong_rate; - - /* now configure the values */ - gst_segment_set_newsegment_full (&dec->segment, update, - rate, arate, format, start, stop, time); - - /* and forward */ - ret = gst_pad_push_event (dec->srcpad, event); - break; - } - default: - ret = gst_pad_push_event (dec->srcpad, event); - break; - } -done: - gst_object_unref (dec); - - return ret; - - /* ERRORS */ -newseg_wrong_format: - { - GST_DEBUG_OBJECT (dec, "received non TIME newsegment"); - gst_event_unref (event); - goto done; - } -newseg_wrong_rate: - { - GST_DEBUG_OBJECT (dec, "negative rates not supported yet"); - gst_event_unref (event); - goto done; - } -} - -static GstFlowReturn -theora_handle_comment_packet (GstTheoraExpDec * dec, ogg_packet * packet) -{ - gchar *encoder = NULL; - GstBuffer *buf; - GstTagList *list; - - GST_DEBUG_OBJECT (dec, "parsing comment packet"); - - buf = gst_buffer_new_and_alloc (packet->bytes); - memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes); - - list = - gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\201theora", 7, - &encoder); - - gst_buffer_unref (buf); - - if (!list) { - GST_ERROR_OBJECT (dec, "couldn't decode comments"); - list = gst_tag_list_new (); - } - if (encoder) { - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_ENCODER, encoder, NULL); - g_free (encoder); - } - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_ENCODER_VERSION, dec->info.version_major, - GST_TAG_VIDEO_CODEC, "Theora", NULL); - - if (dec->info.target_bitrate > 0) { - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_BITRATE, dec->info.target_bitrate, - GST_TAG_NOMINAL_BITRATE, dec->info.target_bitrate, NULL); - } - - gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), dec->srcpad, list); - - return GST_FLOW_OK; -} - -static GstFlowReturn -theora_handle_type_packet (GstTheoraExpDec * dec, ogg_packet * packet) -{ - GstCaps *caps; - gint par_num, par_den; - guint32 fourcc; - - GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d", - dec->info.fps_numerator, dec->info.fps_denominator, - dec->info.aspect_numerator, dec->info.aspect_denominator); - - /* calculate par - * the info.aspect_* values reflect PAR; - * 0 for either is undefined; we're told to assume 1:1 */ - par_num = dec->info.aspect_numerator; - par_den = dec->info.aspect_denominator; - if (par_num == 0 || par_den == 0) { - par_num = par_den = 1; - } - /* theora has: - * - * frame_width/frame_height : dimension of the encoded frame - * pic_width/pic_height : dimension of the visible part - * pic_x/pic_y : offset in encoded frame where visible part starts - */ - GST_DEBUG_OBJECT (dec, "dimension %dx%d, PAR %d/%d", dec->info.frame_width, - dec->info.frame_height, par_num, par_den); - GST_DEBUG_OBJECT (dec, "pic dimension %dx%d, offset %d:%d", - dec->info.pic_width, dec->info.pic_height, - dec->info.pic_x, dec->info.pic_y); - - /* add black borders to make width/height/offsets even. we need this because - * we cannot express an offset to the peer plugin. */ - dec->width = GST_ROUND_UP_2 (dec->info.pic_width + (dec->info.pic_x & 1)); - dec->height = GST_ROUND_UP_2 (dec->info.pic_height + (dec->info.pic_y & 1)); - dec->offset_x = dec->info.pic_x & ~1; - dec->offset_y = dec->info.pic_y & ~1; - - GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d", - dec->width, dec->height, dec->offset_x, dec->offset_y); - - if (dec->info.pixel_fmt == TH_PF_420) { - dec->output_bpp = 12; /* Average bits per pixel. */ - - /* This is bad. I420 is very specific, and has implicit stride. This means - * we can't use the native output of the decoder, we have to memcpy it to - * an I420 buffer. For now, GStreamer gives us no better alternative. - */ - fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0'); - } else if (dec->info.pixel_fmt == TH_PF_422) { - dec->output_bpp = 16; - /* Unfortunately, we don't have a planar 'fourcc' value, which means we - * can't represent the output format of the decoder at all in gstreamer. - * So, we convert to a widely-supported packed format. - */ - fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'); - } else if (dec->info.pixel_fmt == TH_PF_444) { - dec->output_bpp = 24; - /* As for I420, we can't define the stride for this, so we need to memcpy, - * though at least this is a planar format... - */ - fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4'); - } else { - GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt); - return GST_FLOW_ERROR; - } - - dec->dec = th_decode_alloc (&dec->info, dec->setup); - - th_setup_free (dec->setup); - dec->setup = NULL; - - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, fourcc, - "framerate", GST_TYPE_FRACTION, - dec->info.fps_numerator, dec->info.fps_denominator, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den, - "width", G_TYPE_INT, dec->width, "height", G_TYPE_INT, dec->height, NULL); - gst_pad_set_caps (dec->srcpad, caps); - gst_caps_unref (caps); - - dec->have_header = TRUE; - - return GST_FLOW_OK; -} - -static GstFlowReturn -theora_handle_header_packet (GstTheoraExpDec * dec, ogg_packet * packet) -{ - GstFlowReturn res; - int ret; - - GST_DEBUG_OBJECT (dec, "parsing header packet"); - - ret = th_decode_headerin (&dec->info, &dec->comment, &dec->setup, packet); - if (ret < 0) - goto header_read_error; - - /* We can never get here unless we have at least a one-byte packet */ - switch (packet->packet[0]) { - case 0x81: - res = theora_handle_comment_packet (dec, packet); - break; - case 0x82: - res = theora_handle_type_packet (dec, packet); - break; - default: - /* ignore */ - g_warning ("unknown theora header packet found"); - case 0x80: - /* nothing special, this is the identification header */ - res = GST_FLOW_OK; - break; - } - return res; - - /* ERRORS */ -header_read_error: - { - GST_WARNING_OBJECT (dec, "Header parsing failed: %d", ret); - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("couldn't read header packet")); - return GST_FLOW_ERROR; - } -} - -/* returns TRUE if buffer is within segment, else FALSE. - * if buffer is on segment border, its timestamp and duration will be clipped */ -static gboolean -clip_buffer (GstTheoraExpDec * dec, GstBuffer * buf) -{ - gboolean res = TRUE; - GstClockTime in_ts, in_dur, stop; - gint64 cstart, cstop; - - in_ts = GST_BUFFER_TIMESTAMP (buf); - in_dur = GST_BUFFER_DURATION (buf); - - GST_LOG_OBJECT (dec, - "timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT, - GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur)); - - /* can't clip without TIME segment */ - if (dec->segment.format != GST_FORMAT_TIME) - goto beach; - - /* we need a start time */ - if (!GST_CLOCK_TIME_IS_VALID (in_ts)) - goto beach; - - /* generate valid stop, if duration unknown, we have unknown stop */ - stop = - GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE; - - /* now clip */ - if (!(res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME, - in_ts, stop, &cstart, &cstop))) - goto beach; - - /* update timestamp and possibly duration if the clipped stop time is valid */ - GST_BUFFER_TIMESTAMP (buf) = cstart; - if (GST_CLOCK_TIME_IS_VALID (cstop)) - GST_BUFFER_DURATION (buf) = cstop - cstart; - -beach: - GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : "")); - return res; -} - - -/* FIXME, this needs to be moved to the demuxer */ -static GstFlowReturn -theora_dec_push (GstTheoraExpDec * dec, GstBuffer * buf) -{ - GstFlowReturn result = GST_FLOW_OK; - GstClockTime outtime = GST_BUFFER_TIMESTAMP (buf); - - if (outtime == GST_CLOCK_TIME_NONE) { - dec->queued = g_list_append (dec->queued, buf); - GST_DEBUG_OBJECT (dec, "queued buffer"); - result = GST_FLOW_OK; - } else { - if (dec->queued) { - gint64 size; - GList *walk; - - GST_DEBUG_OBJECT (dec, "first buffer with time %" GST_TIME_FORMAT, - GST_TIME_ARGS (outtime)); - - size = g_list_length (dec->queued); - for (walk = dec->queued; walk; walk = g_list_next (walk)) { - GstBuffer *buffer = GST_BUFFER (walk->data); - GstClockTime time; - - time = outtime - gst_util_uint64_scale_int (size * GST_SECOND, - dec->info.fps_denominator, dec->info.fps_numerator); - - GST_DEBUG_OBJECT (dec, "patch buffer %lld %lld", size, time); - GST_BUFFER_TIMESTAMP (buffer) = time; - - if (dec->discont) { - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); - dec->discont = FALSE; - } - - /* ignore the result.. */ - if (clip_buffer (dec, buffer)) - gst_pad_push (dec->srcpad, buffer); - else - gst_buffer_unref (buffer); - size--; - } - g_list_free (dec->queued); - dec->queued = NULL; - } - - if (dec->discont) { - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - dec->discont = FALSE; - } - - if (clip_buffer (dec, buf)) - result = gst_pad_push (dec->srcpad, buf); - else - gst_buffer_unref (buf); - } - - return result; -} - -/* Create a packed 'YUY2' image, push it. - */ -static GstFlowReturn -theora_handle_422_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv, - GstClockTime outtime) -{ - int i, j; - gint width, height; - gint out_size; - gint stride; - GstBuffer *out; - GstFlowReturn result; - - width = dec->width; - height = dec->height; - - stride = GST_ROUND_UP_2 (width) * 2; - - out_size = stride * height; - - /* now copy over the area contained in offset_x,offset_y, - * frame_width, frame_height */ - result = - gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, - out_size, GST_PAD_CAPS (dec->srcpad), &out); - if (result != GST_FLOW_OK) - goto no_buffer; - - /* The output pixels look like: - * YUYVYUYV.... - * - * Do the interleaving... Note that this is kinda messed up if our width is - * odd. In that case, we can't represent it properly in YUY2, so we just - * pad out to even in that case (this is why we have GST_ROUND_UP_2() above). - */ - { - guchar *src_y; - guchar *src_cb; - guchar *src_cr; - guchar *dest; - guchar *curdest; - guchar *src; - - dest = GST_BUFFER_DATA (out); - - src_y = yuv[0].data + dec->offset_x + dec->offset_y * yuv[0].ystride; - src_cb = yuv[1].data + dec->offset_x / 2 + dec->offset_y * yuv[1].ystride; - src_cr = yuv[2].data + dec->offset_x / 2 + dec->offset_y * yuv[2].ystride; - - for (i = 0; i < height; i++) { - /* Y first */ - curdest = dest; - src = src_y; - for (j = 0; j < width; j++) { - *curdest = *src++; - curdest += 2; - } - src_y += yuv[0].ystride; - - curdest = dest + 1; - src = src_cb; - for (j = 0; j < width; j++) { - *curdest = *src++; - curdest += 4; - } - src_cb += yuv[1].ystride; - - curdest = dest + 3; - src = src_cr; - for (j = 0; j < width; j++) { - *curdest = *src++; - curdest += 4; - } - src_cr += yuv[2].ystride; - - dest += stride; - } - } - - GST_BUFFER_OFFSET (out) = dec->frame_nr; - if (dec->frame_nr != -1) - dec->frame_nr++; - GST_BUFFER_OFFSET_END (out) = dec->frame_nr; - GST_BUFFER_DURATION (out) = - gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator, - dec->info.fps_numerator); - GST_BUFFER_TIMESTAMP (out) = outtime; - - return theora_dec_push (dec, out); - -no_buffer: - { - GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s", - gst_flow_get_name (result)); - return result; - } -} - -/* Get buffer, populate with original data (we must memcpy to get things to - * have the expected strides, etc...), and push. - */ -static GstFlowReturn -theora_handle_444_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv, - GstClockTime outtime) -{ - int i, plane; - gint width, height; - gint out_size; - gint stride; - GstBuffer *out; - GstFlowReturn result; - - width = dec->width; - height = dec->height; - - /* TODO: Check if we have any special alignment requirements for the planes, - * or for each line within a plane. */ - stride = width; - out_size = stride * height * 3; - - /* now copy over the area contained in offset_x,offset_y, - * frame_width, frame_height */ - result = - gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, - out_size, GST_PAD_CAPS (dec->srcpad), &out); - if (result != GST_FLOW_OK) - goto no_buffer; - - { - guchar *dest, *src; - - for (plane = 0; plane < 3; plane++) { - /* TODO: do we have to use something different here? */ - dest = GST_BUFFER_DATA (out) + plane * stride * height; - - src = yuv[plane].data + dec->offset_x + - dec->offset_y * yuv[plane].ystride; - - for (i = 0; i < height; i++) { - memcpy (dest, src, width); - - dest += stride; - src += yuv[plane].ystride; - } - - } - } - - /* FIXME, frame_nr not correct */ - GST_BUFFER_OFFSET (out) = dec->frame_nr; - dec->frame_nr++; - GST_BUFFER_OFFSET_END (out) = dec->frame_nr; - GST_BUFFER_DURATION (out) = - gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator, - dec->info.fps_numerator); - GST_BUFFER_TIMESTAMP (out) = outtime; - - return theora_dec_push (dec, out); - -no_buffer: - { - GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s", - gst_flow_get_name (result)); - return result; - } -} - -/* Create a (planar, but with special alignment and stride requirements) 'I420' - * buffer, populate, push. - */ -static GstFlowReturn -theora_handle_420_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv, - GstClockTime outtime) -{ - int i; - gint width, height, cwidth, cheight; - gint out_size; - gint stride_y, stride_uv; - GstBuffer *out; - GstFlowReturn result; - - width = dec->width; - height = dec->height; - cwidth = width / 2; - cheight = height / 2; - - /* should get the stride from the caps, for now we round up to the nearest - * multiple of 4 because some element needs it. chroma needs special - * treatment, see videotestsrc. */ - stride_y = GST_ROUND_UP_4 (width); - stride_uv = GST_ROUND_UP_8 (width) / 2; - - out_size = stride_y * height + stride_uv * cheight * 2; - - /* now copy over the area contained in offset_x,offset_y, - * frame_width, frame_height */ - result = - gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, - out_size, GST_PAD_CAPS (dec->srcpad), &out); - if (result != GST_FLOW_OK) - goto no_buffer; - - /* copy the visible region to the destination. This is actually pretty - * complicated and gstreamer doesn't support all the needed caps to do this - * correctly. For example, when we have an odd offset, we should only combine - * 1 row/column of luma samples with one chroma sample in colorspace conversion. - * We compensate for this by adding a black border around the image when the - * offset or size is odd (see above). - */ - { - guchar *dest_y, *src_y; - guchar *dest_u, *src_u; - guchar *dest_v, *src_v; - gint offset_u, offset_v; - - dest_y = GST_BUFFER_DATA (out); - dest_u = dest_y + stride_y * height; - dest_v = dest_u + stride_uv * cheight; - - src_y = yuv[0].data + dec->offset_x + dec->offset_y * yuv[0].ystride; - - for (i = 0; i < height; i++) { - memcpy (dest_y, src_y, width); - - dest_y += stride_y; - src_y += yuv[0].ystride; - } - - offset_u = dec->offset_x / 2 + dec->offset_y / 2 * yuv[1].ystride; - offset_v = dec->offset_x / 2 + dec->offset_y / 2 * yuv[2].ystride; - - src_u = yuv[1].data + offset_u; - src_v = yuv[2].data + offset_v; - - for (i = 0; i < cheight; i++) { - memcpy (dest_u, src_u, cwidth); - memcpy (dest_v, src_v, cwidth); - - dest_u += stride_uv; - src_u += yuv[1].ystride; - dest_v += stride_uv; - src_v += yuv[2].ystride; - } - } - - /* FIXME, frame_nr not correct */ - GST_BUFFER_OFFSET (out) = dec->frame_nr; - dec->frame_nr++; - GST_BUFFER_OFFSET_END (out) = dec->frame_nr; - GST_BUFFER_DURATION (out) = - gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator, - dec->info.fps_numerator); - GST_BUFFER_TIMESTAMP (out) = outtime; - - return theora_dec_push (dec, out); - -no_buffer: - { - GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s", - gst_flow_get_name (result)); - return result; - } -} - -static GstFlowReturn -theora_handle_data_packet (GstTheoraExpDec * dec, ogg_packet * packet, - GstClockTime outtime) -{ - /* normal data packet */ - th_ycbcr_buffer yuv; - GstFlowReturn result; - ogg_int64_t gp; - - if (G_UNLIKELY (!dec->have_header)) - goto not_initialized; - - if (th_packet_iskeyframe (packet)) { - dec->need_keyframe = FALSE; - } else if (G_UNLIKELY (dec->need_keyframe)) { - goto dropping; - } - - /* this does the decoding */ - if (G_UNLIKELY (th_decode_packetin (dec->dec, packet, &gp))) - goto decode_error; - - if (outtime != -1) { - gboolean need_skip; - GstClockTime qostime; - - /* QoS is done on running time */ - qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME, - outtime); - - GST_OBJECT_LOCK (dec); - /* check for QoS, don't perform the last steps of getting and - * pushing the buffers that are known to be late. */ - /* FIXME, we can also entirely skip decoding if the next valid buffer is - * known to be after a keyframe (using the granule_shift) */ - need_skip = dec->earliest_time != -1 && qostime <= dec->earliest_time; - GST_OBJECT_UNLOCK (dec); - - if (need_skip) - goto dropping_qos; - } - - /* this does postprocessing and set up the decoded frame - * pointers in our yuv variable */ - if (G_UNLIKELY (th_decode_ycbcr_out (dec->dec, yuv) < 0)) - goto no_yuv; - - if (G_UNLIKELY ((yuv[0].width != dec->info.frame_width) || - (yuv[0].height != dec->info.frame_height))) - goto wrong_dimensions; - - if (dec->info.pixel_fmt == TH_PF_420) { - result = theora_handle_420_image (dec, yuv, outtime); - } else if (dec->info.pixel_fmt == TH_PF_422) { - result = theora_handle_422_image (dec, yuv, outtime); - } else if (dec->info.pixel_fmt == TH_PF_444) { - result = theora_handle_444_image (dec, yuv, outtime); - } else { - g_assert_not_reached (); - } - - return result; - - /* ERRORS */ -not_initialized: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("no header sent yet")); - return GST_FLOW_ERROR; - } -dropping: - { - GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe"); - dec->discont = TRUE; - return GST_FLOW_OK; - } -dropping_qos: - { - if (dec->frame_nr != -1) - dec->frame_nr++; - dec->discont = TRUE; - GST_WARNING_OBJECT (dec, "dropping frame because of QoS"); - return GST_FLOW_OK; - } -decode_error: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("theora decoder did not decode data packet")); - return GST_FLOW_ERROR; - } -no_yuv: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("couldn't read out YUV image")); - return GST_FLOW_ERROR; - } -wrong_dimensions: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, FORMAT, - (NULL), ("dimensions of image do not match header")); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -theora_dec_chain (GstPad * pad, GstBuffer * buf) -{ - GstTheoraExpDec *dec; - ogg_packet packet; - GstFlowReturn result = GST_FLOW_OK; - gboolean isheader; - - dec = GST_THEORA_DEC_EXP (gst_pad_get_parent (pad)); - - /* resync on DISCONT */ - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { - GST_DEBUG_OBJECT (dec, "Received DISCONT buffer"); - dec->need_keyframe = TRUE; - dec->last_timestamp = -1; - dec->granulepos = -1; - dec->discont = TRUE; - } - - GST_DEBUG ("Offset end is %d, k-g-s %d", (int) (GST_BUFFER_OFFSET_END (buf)), - dec->info.keyframe_granule_shift); - /* make ogg_packet out of the buffer */ - packet.packet = GST_BUFFER_DATA (buf); - packet.bytes = GST_BUFFER_SIZE (buf); - packet.granulepos = GST_BUFFER_OFFSET_END (buf); - packet.packetno = 0; /* we don't really care */ - packet.b_o_s = dec->have_header ? 0 : 1; - /* EOS does not matter for the decoder */ - packet.e_o_s = 0; - - if (dec->have_header) { - if (packet.granulepos != -1) { - GST_DEBUG_OBJECT (dec, "Granulepos from packet: %lld", packet.granulepos); - dec->granulepos = packet.granulepos; - dec->last_timestamp = - gst_theoradec_granule_clocktime (dec, packet.granulepos); - } else if (dec->last_timestamp != -1) { - GST_DEBUG_OBJECT (dec, "Granulepos inferred?: %lld", dec->granulepos); - dec->last_timestamp = - gst_theoradec_granule_clocktime (dec, dec->granulepos); - } else { - GST_DEBUG_OBJECT (dec, "Granulepos unknown"); - dec->last_timestamp = GST_CLOCK_TIME_NONE; - } - if (dec->last_timestamp == GST_CLOCK_TIME_NONE && - GST_BUFFER_TIMESTAMP_IS_VALID (buf)) - dec->last_timestamp = GST_BUFFER_TIMESTAMP (buf); - - } else { - GST_DEBUG_OBJECT (dec, "Granulepos not usable: no headers seen"); - dec->last_timestamp = -1; - } - - /* A zero-byte packet is a valid data packet, meaning 'duplicate frame' */ - if (packet.bytes > 0 && packet.packet[0] & 0x80) - isheader = TRUE; - else - isheader = FALSE; - - GST_DEBUG_OBJECT (dec, "header=%d packetno=%lld, outtime=%" GST_TIME_FORMAT, - packet.bytes ? packet.packet[0] : -1, packet.packetno, - GST_TIME_ARGS (dec->last_timestamp)); - - /* switch depending on packet type */ - if (isheader) { - if (dec->have_header) { - GST_WARNING_OBJECT (GST_OBJECT (dec), "Ignoring header"); - goto done; - } - result = theora_handle_header_packet (dec, &packet); - } else { - result = theora_handle_data_packet (dec, &packet, dec->last_timestamp); - } - -done: - /* interpolate granule pos */ - dec->granulepos = inc_granulepos (dec, dec->granulepos); - - gst_object_unref (dec); - - gst_buffer_unref (buf); - - return result; -} - -static GstStateChangeReturn -theora_dec_change_state (GstElement * element, GstStateChange transition) -{ - GstTheoraExpDec *dec = GST_THEORA_DEC_EXP (element); - GstStateChangeReturn ret; - - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - th_info_init (&dec->info); - th_comment_init (&dec->comment); - dec->have_header = FALSE; - gst_theoradec_reset (dec); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = parent_class->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - th_decode_free (dec->dec); - dec->dec = NULL; - - th_comment_clear (&dec->comment); - th_info_clear (&dec->info); - gst_theoradec_reset (dec); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "theoradecexp", GST_RANK_PRIMARY, - gst_theoradec_get_type ())) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "theoradec", - "Theora dec (exp) plugin library", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/theora/theoradec.h b/ext/theora/theoradec.h deleted file mode 100644 index e9f0eb73b2..0000000000 --- a/ext/theora/theoradec.h +++ /dev/null @@ -1,99 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Benjamin Otte - * 2006 Michael Smith - * - * 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_THEORADEC_H__ -#define __GST_THEORADEC_H__ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_THEORA_DEC_EXP \ - (gst_theoradec_get_type()) -#define GST_THEORA_DEC_EXP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_THEORA_DEC_EXP,GstTheoraExpDec)) -#define GST_THEORA_DEC_EXP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_THEORA_DEC_EXP,GstTheoraExpDecClass)) -#define GST_IS_THEORA_DEC_EXP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_THEORA_DEC_EXP)) -#define GST_IS_THEORA_DEC_EXP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_THEORA_DEC_EXP)) - -typedef struct _GstTheoraExpDec GstTheoraExpDec; -typedef struct _GstTheoraExpDecClass GstTheoraExpDecClass; - -/** - * GstTheoraExpDec: - * - * Decoder using theora-exp - */ -struct _GstTheoraExpDec -{ - /* */ - GstElement element; - - /* Pads */ - GstPad *sinkpad; - GstPad *srcpad; - - /* theora decoder state */ - th_dec_ctx *dec; - th_setup_info *setup; - - th_info info; - th_comment comment; - - gboolean have_header; - guint64 granulepos; - guint64 granule_shift; - - GstClockTime last_timestamp; - gboolean need_keyframe; - gint width, height; - gint offset_x, offset_y; - gint output_bpp; - - int frame_nr; - gboolean discont; - - GList *queued; - - /* segment info */ /* with STREAM_LOCK */ - GstSegment segment; - - /* QoS stuff */ /* with LOCK*/ - gboolean proportion; - GstClockTime earliest_time; -}; - -struct _GstTheoraExpDecClass -{ - GstElementClass parent_class; -}; - -G_END_DECLS - -#endif /* __GST_THEORADEC_H__ */ diff --git a/gst/videofilters/gstzebrastripe.h b/gst/videofilters/gstzebrastripe.h index 41a7f170e5..f3c3c9c58d 100644 --- a/gst/videofilters/gstzebrastripe.h +++ b/gst/videofilters/gstzebrastripe.h @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2011 FIXME + * Copyright (C) 2011 David Schleef * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public