From 57ce0321c8971f964008920003a3e8b19649df85 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 3 Feb 2002 16:30:31 +0000 Subject: Added a tarkin encoder/decoder plugin. Original commit message from CVS: Added a tarkin encoder/decoder plugin. I moved the tarking CVS code in here temporarily until they have a library (hence this plugin is in ext) test with: ./gst-launch filesrc location=/opt/data/shihad.mpg ! mpegdemux video_00! { queue ! mpeg2dec ! colorspace ! tarkinenc bitrate=3000 ! disksink location=out.ogg } ./gst-launch filesrc location=out.ogg ! tarkindec ! colorspace ! xvideosink --- ext/tarkin/rle.h | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 ext/tarkin/rle.h (limited to 'ext/tarkin/rle.h') diff --git a/ext/tarkin/rle.h b/ext/tarkin/rle.h new file mode 100644 index 00000000..7cf79517 --- /dev/null +++ b/ext/tarkin/rle.h @@ -0,0 +1,143 @@ +#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 + -- cgit v1.2.1