mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 08:11:16 +00:00
57ce0321c8
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
143 lines
3.7 KiB
C
143 lines
3.7 KiB
C
#ifndef __RLE_H
|
|
#define __RLE_H
|
|
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#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
|
|
|