[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