[FFmpeg-devel] [PATCH][RFC] Lagarith Decoder.
Michael Niedermayer
michaelni
Sat Aug 8 14:32:45 CEST 2009
On Thu, Aug 06, 2009 at 03:06:32PM -0600, Nathan Caldwell wrote:
> Here's my first attempt at a Lagarith decoder. At the moment it only
> handles YV12 content, I do plan on adding in the other modes (RGB24,
> YUY2, and RGBA). I just wanted some input on things that need changed
> before I get too far along.
[...]
> +
> +typedef struct lag_rac {
> + AVCodecContext *avctx;
> + unsigned low;
> + unsigned range;
> + unsigned scale;
> + unsigned hash_shift;
> +
> + uint8_t *bytestream_start;
> + uint8_t *bytestream;
> + uint8_t *bytestream_end;
> +
> + int prob[257];
> + int range_hash[256];
> +} lag_rac;
the coder could be put in a seperate file and patch
> +
> +/**
> +* local variable storage
> +*/
> +typedef struct LagarithContext{
> + AVCodecContext *avctx;
> + AVFrame picture;
> + int i_zeros;
> + int i_zeros_rem;
> + int i_frame;
> +} LagarithContext;
> +
> +/**
> +* initializes decoder
> +* @param avctx codec context
> +* @return 0 on success or negative if fails
> +*/
> +static av_cold int lag_decode_init(AVCodecContext *avctx)
> +{
> + LagarithContext *p_ctx = avctx->priv_data;
> +
trailing whitespace
> + avctx->pix_fmt= PIX_FMT_NONE;
that should alraedy be there i think
> +
> + p_ctx->avctx = avctx;
> +
> + av_log_set_level(AV_LOG_DEBUG);
that doesnt belong here
> +
> + return 0;
> +}
> +
> +static void lag_rac_init(lag_rac *l, GetBitContext *gb, int length)
> +{
> + int i,j;
> +
> + /* According to reference decoder "1st byte is garbage" */
> +// skip_bits(gb, 8);
> + align_get_bits(gb);
> + l->bytestream_start =
> + l->bytestream = gb->buffer + get_bits_count(gb)/8;
> + l->bytestream_end = l->bytestream_start + length;
> +
> + l->range = 0x80;
> + l->low = *l->bytestream >> 1;
> + l->hash_shift = FFMAX(l->scale-8, 0);
> +
> + for (i = 0, j = 0; i < 257; i++) {
i=j=0
if you have to set them both there
> + unsigned r = i << l->hash_shift;
> + while (l->prob[j + 1] <= r)
> + j++;
> + l->range_hash[i] = j;
> + }
> +}
> +
> +/* TODO: Optimize */
> +static inline void lag_rac_refill(struct lag_rac *l)
> +{
> + while (l->range <= 0x800000) {
> + l->low <<= 8;
> + l->range <<= 8;
> + l->low |= 0xff & (l->bytestream[0] << 7 | l->bytestream[1] >> 1);
isnt it possible to refill with normal aligned bytes?
> + l->bytestream++;
> + }
> +}
> +
> +/* TODO: Optimize */
> +// decodes a byte
> +static inline int lag_get_rac(struct lag_rac *l)
> +{
> + unsigned range_scaled, low_scaled;
> + int val = 0;
> +
> + lag_rac_refill(l);
> +
> + range_scaled = l->range >> l->scale;
> + low_scaled = l->low / range_scaled;
this possibly could be done with a LUT (of course that only makes
sense if it is faster
> +
> + if (low_scaled < l->prob[255]) {
> + val = l->range_hash[low_scaled >> l->hash_shift];
> + while (l->prob[val+1] <= low_scaled)
> + val++;
> +
> + l->low -= range_scaled * l->prob[val];
> + l->range = range_scaled * (l->prob[val+1] - l->prob[val]);
> + } else {
> + val = 255;
> + l->low -= range_scaled * l->prob[255];
> + l->range -= range_scaled * l->prob[255];
> + }
> + return val;
> +}
> +
> +void lag_memset(uint8_t *s, uint8_t c, size_t n, int i_step)
static
> +{
> + if(n == 0) return;
this is never true
> + if(i_step == 1) {
> + memset(s, c, n);
> + return;
> + }
> +
> + for(int i=0; i < n*i_step; i+=i_step)
> + s[i] = c;
> + return;
> +}
unneeded
and the function should possibly be marked as inline
> +
> +uint8_t *lag_memcpy(uint8_t *dest, const uint8_t *src, size_t n, int i_step)
> +{
> + if(n == 0) return dest;
> + if(i_step == 1)
> + return memcpy(dest, src, n);
> +
> + for(int i=0; i < n*i_step; i+=i_step)
> + dest[i] = src[i];
> + return dest;
> +}
> +
> +static inline int lag_predict(uint8_t *p_src, int i_stride, int i_step)
> +{
> + int T = p_src[-i_stride];
> + int L = p_src[-i_step];
> + int TL = p_src[-i_stride - i_step];
> +
> + return mid_pred( T, L, L + T - TL);
> +}
thats a duplicate
> +
> +static uint32_t lag_decode_prob(GetBitContext *p_gb)
> +{
> + unsigned int bit=0;
> + unsigned int series[]={1,2,3,5,8,13,21,34};
> + unsigned int prevbit=0;
> + unsigned int bits=0;
> + unsigned int i=0;
> + unsigned int value=1;
> +
> + for( i=0 ; !( prevbit && bit ); i++)
> + {
> + prevbit = bit;
> + bit = get_bits1(p_gb);
> + if ( bit && !prevbit )
> + bits+=series[i];
> + }
inconsistent {} placement style
tabs
> + bits--;
> + if (bits == 0) return 0;
> +
> + value = get_bits_long(p_gb, bits);
> + value |= 1 << bits;
> +
> + return value-1;
> +}
> +
> +/* Fast round up to least power of 2 >= to x */
> +static inline uint32_t clp2(uint32_t x)
> +{
> + x--;
> + x |= (x >> 1);
> + x |= (x >> 2);
> + x |= (x >> 4);
> + x |= (x >> 8);
> + x |= (x >> 16);
> + return x+1;
> +}
is 1<<av_log2(x) faster?
[..]
> + return;
> +}
redundant
[...]
> +/**
> +* closes decoder
> +* @param avctx codec context
> +* @return 0 on success or negative if fails
> +*/
> +static av_cold int lag_decode_end(AVCodecContext *avctx)
> +{
> +
> + return 0;
> +}
redudnant
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I am the wisest man alive, for I know one thing, and that is that I know
nothing. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090808/11686762/attachment.pgp>
More information about the ffmpeg-devel
mailing list