[FFmpeg-devel] [Toy] Xxan (aka Xan for WC4) decoder

Michael Niedermayer michaelni
Fri Dec 18 15:34:22 CET 2009


On Thu, Dec 17, 2009 at 03:15:31PM +0200, Kostya wrote:
> Well, $subj. Now it plays files almost fine.
> Mike should have finished it long time ago though.

[...]
> typedef struct XanContext {
> 
>     AVCodecContext *avctx;
>     AVFrame last_frame;
>     AVFrame current_frame;
> 

>     const unsigned char *buf;
>     int size;
> 
>     /* scratch space */
>     unsigned char *buffer1;
>     int buffer1_size;
>     unsigned char *buffer2;
>     int buffer2_size;
>     unsigned char *buffer3;
>     int buffer3_size;

i think buf, buffer1, buffer2, buffer3 need some more doxy



> 
>     int frame_size;
> 
> } XanContext;
> 
> static av_cold int xan_decode_init(AVCodecContext *avctx)
> {
>     XanContext *s = avctx->priv_data;
> 
>     s->avctx = avctx;
>     s->frame_size = 0;
> 
>     if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
>         (s->avctx->palctrl == NULL)) {
>         av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
>         return -1;
>     }
> 
>     avctx->pix_fmt = (avctx->codec->id == CODEC_ID_XAN_WC3) ? PIX_FMT_PAL8 : PIX_FMT_YUV420P;
> 

>     s->buffer1_size = avctx->width * avctx->height;
>     s->buffer1 = av_malloc(s->buffer1_size);
>     s->buffer2_size = avctx->width * avctx->height;
>     s->buffer2 = av_malloc(s->buffer2_size + 130);
>     s->buffer3_size = avctx->width * avctx->height;
>     s->buffer3 = av_malloc(s->buffer2_size + 130);
>     if (!s->buffer1 || !s->buffer2 || !s->buffer3)
>         return -1;

memleak


> 
>     return 0;
> }
> 
> static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
>     int dest_len)
> {
>     unsigned char byte = *src++;
>     unsigned char ival = byte + 0x16;
>     const unsigned char * ptr = src + byte*2;
>     unsigned char val = ival;
>     unsigned char *dest_end = dest + dest_len;
>     GetBitContext gb;
> 

>     init_get_bits(&gb, ptr, 0); // FIXME: no src size available

i dont belive that there is absolutely no source size available, especialy
as the decoders know the input packet size


> 
>     while ( val != 0x16 ) {
>         val = src[val - 0x17 + get_bits1(&gb) * byte];
> 
>         if ( val < 0x16 ) {
>             if (dest >= dest_end)
>                 return 0;
>             *dest++ = val;
>             val = ival;
>         }
>     }

This code isnt speed critical?
iam asking because this looks kinda inefficient


[...]
>     if (AV_RL16(&inputstream[-2])) {
>         for (j = 0; j < s->avctx->height / 2; j++) {
>             for (i = 0; i < s->avctx->width / 2; i++) {
>                 if (AV_RN16(&inputstream[*cdata * 2])) {
>                     table_value  = AV_RL16(&inputstream[*cdata * 2]);
>                     U[i] = (table_value >> 8) & 0xF8;
>                     V[i] = (table_value >> 3) & 0xF8;
>                 }
>                 cdata++;
>             }
>             U += s->current_frame.linesize[1];
>             V += s->current_frame.linesize[2];
>         }
>     } else {
>         for (j = 0; j < s->avctx->height / 4; j++) {
>             for (i = 0; i < s->avctx->width / 4; i++) {
>                 if (*cdata) {
>                     table_value  = AV_RL16(&inputstream[*cdata * 2]);

>                     U[i*2 + 0] = (table_value >> 8) & 0xF8;
>                     V[i*2 + 0] = (table_value >> 3) & 0xF8;
>                     U[i*2 + 1] = (table_value >> 8) & 0xF8;
>                     V[i*2 + 1] = (table_value >> 3) & 0xF8;

U[i*2 + 0] =
U[i*2 + 1] = (table_value >> 8) & 0xF8;
V[i*2 + 0] =
V[i*2 + 1] = (table_value >> 3) & 0xF8;


[...]
> static void xan_wc4_decode_frame(XanContext *s) {
>     uint8_t *Y, *pix;
>     int x, y;
> 
>     if (s->size < 16)
>         return;
> {
> static int frame = 0;
> av_log(NULL,0,"Frame %d(%d) - %d, %X %X %X\n",++frame,AV_RL32(s->buf),AV_RL32(s->buf+4),AV_RL16(s->buf + AV_RL32(&s->buf[4]) + 4),AV_RL32(s->buf+8),AV_RL32(s->buf+12));
> }

ehm


>     xan_wc4_decode_chroma(s);

>     if (AV_RL32(&s->buf[0]) == 0)
>         xan_wc4_decode_frame_type0(s);
>     else

{}


[...]
> static int xan_decode_frame(AVCodecContext *avctx,
>                             void *data, int *data_size,
>                             AVPacket *avpkt)
> {
>     const uint8_t *buf = avpkt->data;
>     int buf_size = avpkt->size;
>     XanContext *s = avctx->priv_data;

>     AVPaletteControl *palette_control = avctx->palctrl;

This struct is deprecated and will be removed with the next major ver bump


[...]
> AVCodec xan_wc3_decoder = {
>     "xan_wc3",
>     CODEC_TYPE_VIDEO,
>     CODEC_ID_XAN_WC3,
>     sizeof(XanContext),
>     xan_decode_init,
>     NULL,
>     xan_decode_end,
>     xan_decode_frame,
>     CODEC_CAP_DR1,
>     .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
> };
> 

> AVCodec xan_wc4_decoder = {
>     "xan_wc4",
>     CODEC_TYPE_VIDEO,
>     CODEC_ID_XAN_WC4,
>     sizeof(XanContext),
>     xan_decode_init,
>     NULL,
>     xan_decode_end,
>     xan_decode_frame,
>     CODEC_CAP_DR1,
> };

long name?


> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

No snowflake in an avalanche ever feels responsible. -- Voltaire
-------------- 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/20091218/4318579f/attachment.pgp>



More information about the ffmpeg-devel mailing list