avcodec/xan: use init_get_bits8()
[ffmpeg.git] / libavcodec / xan.c
1 /*
2  * Wing Commander/Xan Video Decoder
3  * Copyright (C) 2003 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * Xan video decoder for Wing Commander III computer game
25  * by Mario Brito (mbrito@student.dei.uc.pt)
26  * and Mike Melanson (melanson@pcisys.net)
27  *
28  * The xan_wc3 decoder outputs PAL8 data.
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mem.h"
37 #include "avcodec.h"
38 #include "bytestream.h"
39 #define BITSTREAM_READER_LE
40 #include "get_bits.h"
41 #include "internal.h"
42
43 #define RUNTIME_GAMMA 0
44
45 #define VGA__TAG MKTAG('V', 'G', 'A', ' ')
46 #define PALT_TAG MKTAG('P', 'A', 'L', 'T')
47 #define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
48 #define PALETTE_COUNT 256
49 #define PALETTE_SIZE (PALETTE_COUNT * 3)
50 #define PALETTES_MAX 256
51
52 typedef struct XanContext {
53
54     AVCodecContext *avctx;
55     AVFrame *last_frame;
56
57     const uint8_t *buf;
58     int size;
59
60     /* scratch space */
61     uint8_t *buffer1;
62     int buffer1_size;
63     uint8_t *buffer2;
64     int buffer2_size;
65
66     unsigned *palettes;
67     int palettes_count;
68     int cur_palette;
69
70     int frame_size;
71
72 } XanContext;
73
74 static av_cold int xan_decode_end(AVCodecContext *avctx);
75
76 static av_cold int xan_decode_init(AVCodecContext *avctx)
77 {
78     XanContext *s = avctx->priv_data;
79
80     s->avctx = avctx;
81     s->frame_size = 0;
82
83     avctx->pix_fmt = AV_PIX_FMT_PAL8;
84
85     s->buffer1_size = avctx->width * avctx->height;
86     s->buffer1 = av_malloc(s->buffer1_size);
87     if (!s->buffer1)
88         return AVERROR(ENOMEM);
89     s->buffer2_size = avctx->width * avctx->height;
90     s->buffer2 = av_malloc(s->buffer2_size + 130);
91     if (!s->buffer2) {
92         av_freep(&s->buffer1);
93         return AVERROR(ENOMEM);
94     }
95     s->last_frame = av_frame_alloc();
96     if (!s->last_frame) {
97         xan_decode_end(avctx);
98         return AVERROR(ENOMEM);
99     }
100
101     return 0;
102 }
103
104 static int xan_huffman_decode(uint8_t *dest, int dest_len,
105                               const uint8_t *src, int src_len)
106 {
107     uint8_t byte = *src++;
108     uint8_t ival = byte + 0x16;
109     const uint8_t * ptr = src + byte*2;
110     int ptr_len = src_len - 1 - byte*2;
111     uint8_t val = ival;
112     uint8_t *dest_end = dest + dest_len;
113     uint8_t *dest_start = dest;
114     int ret;
115     GetBitContext gb;
116
117     if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)
118         return ret;
119
120     while (val != 0x16) {
121         unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
122         if (idx >= 2 * byte)
123             return AVERROR_INVALIDDATA;
124         val = src[idx];
125
126         if (val < 0x16) {
127             if (dest >= dest_end)
128                 return dest_len;
129             *dest++ = val;
130             val = ival;
131         }
132     }
133
134     return dest - dest_start;
135 }
136
137 /**
138  * unpack simple compression
139  *
140  * @param dest destination buffer of dest_len, must be padded with at least 130 bytes
141  */
142 static void xan_unpack(uint8_t *dest, int dest_len,
143                        const uint8_t *src, int src_len)
144 {
145     uint8_t opcode;
146     int size;
147     uint8_t *dest_org = dest;
148     uint8_t *dest_end = dest + dest_len;
149     GetByteContext ctx;
150
151     bytestream2_init(&ctx, src, src_len);
152     while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
153         opcode = bytestream2_get_byte(&ctx);
154
155         if (opcode < 0xe0) {
156             int size2, back;
157             if ((opcode & 0x80) == 0) {
158                 size = opcode & 3;
159
160                 back  = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
161                 size2 = ((opcode & 0x1c) >> 2) + 3;
162             } else if ((opcode & 0x40) == 0) {
163                 size = bytestream2_peek_byte(&ctx) >> 6;
164
165                 back  = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
166                 size2 = (opcode & 0x3f) + 4;
167             } else {
168                 size = opcode & 3;
169
170                 back  = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
171                 size2 = ((opcode & 0x0c) <<  6) + bytestream2_get_byte(&ctx) + 5;
172             }
173
174             if (dest_end - dest < size + size2 ||
175                 dest + size - dest_org < back ||
176                 bytestream2_get_bytes_left(&ctx) < size)
177                 return;
178             bytestream2_get_buffer(&ctx, dest, size);
179             dest += size;
180             av_memcpy_backptr(dest, back, size2);
181             dest += size2;
182         } else {
183             int finish = opcode >= 0xfc;
184             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
185
186             if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
187                 return;
188             bytestream2_get_buffer(&ctx, dest, size);
189             dest += size;
190             if (finish)
191                 return;
192         }
193     }
194 }
195
196 static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame,
197     const uint8_t *pixel_buffer, int x, int y, int pixel_count)
198 {
199     int stride;
200     int line_inc;
201     int index;
202     int current_x;
203     int width = s->avctx->width;
204     uint8_t *palette_plane;
205
206     palette_plane = frame->data[0];
207     stride = frame->linesize[0];
208     line_inc = stride - width;
209     index = y * stride + x;
210     current_x = x;
211     while (pixel_count && index < s->frame_size) {
212         int count = FFMIN(pixel_count, width - current_x);
213         memcpy(palette_plane + index, pixel_buffer, count);
214         pixel_count  -= count;
215         index        += count;
216         pixel_buffer += count;
217         current_x    += count;
218
219         if (current_x >= width) {
220             index += line_inc;
221             current_x = 0;
222         }
223     }
224 }
225
226 static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame,
227                                           int x, int y,
228                                           int pixel_count, int motion_x,
229                                           int motion_y)
230 {
231     int stride;
232     int line_inc;
233     int curframe_index, prevframe_index;
234     int curframe_x, prevframe_x;
235     int width = s->avctx->width;
236     uint8_t *palette_plane, *prev_palette_plane;
237
238     if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
239         x + motion_x < 0 || x + motion_x >= s->avctx->width)
240         return;
241
242     palette_plane = frame->data[0];
243     prev_palette_plane = s->last_frame->data[0];
244     if (!prev_palette_plane)
245         prev_palette_plane = palette_plane;
246     stride = frame->linesize[0];
247     line_inc = stride - width;
248     curframe_index = y * stride + x;
249     curframe_x = x;
250     prevframe_index = (y + motion_y) * stride + x + motion_x;
251     prevframe_x = x + motion_x;
252
253     if (prev_palette_plane == palette_plane && FFABS(curframe_index - prevframe_index) < pixel_count) {
254          avpriv_request_sample(s->avctx, "Overlapping copy\n");
255          return ;
256     }
257
258     while (pixel_count &&
259            curframe_index  < s->frame_size &&
260            prevframe_index < s->frame_size) {
261         int count = FFMIN3(pixel_count, width - curframe_x,
262                            width - prevframe_x);
263
264         memcpy(palette_plane + curframe_index,
265                prev_palette_plane + prevframe_index, count);
266         pixel_count     -= count;
267         curframe_index  += count;
268         prevframe_index += count;
269         curframe_x      += count;
270         prevframe_x     += count;
271
272         if (curframe_x >= width) {
273             curframe_index += line_inc;
274             curframe_x = 0;
275         }
276
277         if (prevframe_x >= width) {
278             prevframe_index += line_inc;
279             prevframe_x = 0;
280         }
281     }
282 }
283
284 static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
285 {
286
287     int width  = s->avctx->width;
288     int height = s->avctx->height;
289     int total_pixels = width * height;
290     uint8_t opcode;
291     uint8_t flag = 0;
292     int size = 0;
293     int motion_x, motion_y;
294     int x, y, ret;
295
296     uint8_t *opcode_buffer = s->buffer1;
297     uint8_t *opcode_buffer_end = s->buffer1 + s->buffer1_size;
298     int opcode_buffer_size = s->buffer1_size;
299     const uint8_t *imagedata_buffer = s->buffer2;
300
301     /* pointers to segments inside the compressed chunk */
302     const uint8_t *huffman_segment;
303     GetByteContext       size_segment;
304     GetByteContext       vector_segment;
305     const uint8_t *imagedata_segment;
306     int huffman_offset, size_offset, vector_offset, imagedata_offset,
307         imagedata_size;
308
309     if (s->size < 8)
310         return AVERROR_INVALIDDATA;
311
312     huffman_offset    = AV_RL16(&s->buf[0]);
313     size_offset       = AV_RL16(&s->buf[2]);
314     vector_offset     = AV_RL16(&s->buf[4]);
315     imagedata_offset  = AV_RL16(&s->buf[6]);
316
317     if (huffman_offset   >= s->size ||
318         size_offset      >= s->size ||
319         vector_offset    >= s->size ||
320         imagedata_offset >= s->size)
321         return AVERROR_INVALIDDATA;
322
323     huffman_segment   = s->buf + huffman_offset;
324     bytestream2_init(&size_segment,   s->buf + size_offset,   s->size - size_offset);
325     bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset);
326     imagedata_segment = s->buf + imagedata_offset;
327
328     if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size,
329                                   huffman_segment, s->size - huffman_offset)) < 0)
330         return AVERROR_INVALIDDATA;
331     opcode_buffer_end = opcode_buffer + ret;
332
333     if (imagedata_segment[0] == 2) {
334         xan_unpack(s->buffer2, s->buffer2_size,
335                    &imagedata_segment[1], s->size - imagedata_offset - 1);
336         imagedata_size = s->buffer2_size;
337     } else {
338         imagedata_size = s->size - imagedata_offset - 1;
339         imagedata_buffer = &imagedata_segment[1];
340     }
341
342     /* use the decoded data segments to build the frame */
343     x = y = 0;
344     while (total_pixels && opcode_buffer < opcode_buffer_end) {
345
346         opcode = *opcode_buffer++;
347         size = 0;
348
349         switch (opcode) {
350
351         case 0:
352             flag ^= 1;
353             continue;
354
355         case 1:
356         case 2:
357         case 3:
358         case 4:
359         case 5:
360         case 6:
361         case 7:
362         case 8:
363             size = opcode;
364             break;
365
366         case 12:
367         case 13:
368         case 14:
369         case 15:
370         case 16:
371         case 17:
372         case 18:
373             size += (opcode - 10);
374             break;
375
376         case 9:
377         case 19:
378             if (bytestream2_get_bytes_left(&size_segment) < 1) {
379                 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
380                 return AVERROR_INVALIDDATA;
381             }
382             size = bytestream2_get_byte(&size_segment);
383             break;
384
385         case 10:
386         case 20:
387             if (bytestream2_get_bytes_left(&size_segment) < 2) {
388                 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
389                 return AVERROR_INVALIDDATA;
390             }
391             size = bytestream2_get_be16(&size_segment);
392             break;
393
394         case 11:
395         case 21:
396             if (bytestream2_get_bytes_left(&size_segment) < 3) {
397                 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
398                 return AVERROR_INVALIDDATA;
399             }
400             size = bytestream2_get_be24(&size_segment);
401             break;
402         }
403
404         if (size > total_pixels)
405             break;
406
407         if (opcode < 12) {
408             flag ^= 1;
409             if (flag) {
410                 /* run of (size) pixels is unchanged from last frame */
411                 xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
412             } else {
413                 /* output a run of pixels from imagedata_buffer */
414                 if (imagedata_size < size)
415                     break;
416                 xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
417                 imagedata_buffer += size;
418                 imagedata_size -= size;
419             }
420         } else {
421             uint8_t vector;
422             if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
423                 av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
424                 return AVERROR_INVALIDDATA;
425             }
426             /* run-based motion compensation from last frame */
427             vector = bytestream2_get_byte(&vector_segment);
428             motion_x = sign_extend(vector >> 4,  4);
429             motion_y = sign_extend(vector & 0xF, 4);
430
431             /* copy a run of pixels from the previous frame */
432             xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
433
434             flag = 0;
435         }
436
437         /* coordinate accounting */
438         total_pixels -= size;
439         y += (x + size) / width;
440         x  = (x + size) % width;
441     }
442     return 0;
443 }
444
445 #if RUNTIME_GAMMA
446 static inline unsigned mul(unsigned a, unsigned b)
447 {
448     return (a * b) >> 16;
449 }
450
451 static inline unsigned pow4(unsigned a)
452 {
453     unsigned square = mul(a, a);
454     return mul(square, square);
455 }
456
457 static inline unsigned pow5(unsigned a)
458 {
459     return mul(pow4(a), a);
460 }
461
462 static uint8_t gamma_corr(uint8_t in) {
463     unsigned lo, hi = 0xff40, target;
464     int i = 15;
465     in = (in << 2) | (in >> 6);
466     /*  equivalent float code:
467     if (in >= 252)
468         return 253;
469     return round(pow(in / 256.0, 0.8) * 256);
470     */
471     lo = target = in << 8;
472     do {
473         unsigned mid = (lo + hi) >> 1;
474         unsigned pow = pow5(mid);
475         if (pow > target) hi = mid;
476         else lo = mid;
477     } while (--i);
478     return (pow4((lo + hi) >> 1) + 0x80) >> 8;
479 }
480 #else
481 /**
482  * This is a gamma correction that xan3 applies to all palette entries.
483  *
484  * There is a peculiarity, namely that the values are clamped to 253 -
485  * it seems likely that this table was calculated by a buggy fixed-point
486  * implementation, the one above under RUNTIME_GAMMA behaves like this for
487  * example.
488  * The exponent value of 0.8 can be explained by this as well, since 0.8 = 4/5
489  * and thus pow(x, 0.8) is still easy to calculate.
490  * Also, the input values are first rotated to the left by 2.
491  */
492 static const uint8_t gamma_lookup[256] = {
493     0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
494     0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
495     0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
496     0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
497     0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
498     0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
499     0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
500     0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
501     0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
502     0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
503     0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
504     0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
505     0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
506     0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
507     0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
508     0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
509     0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
510     0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
511     0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
512     0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
513     0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
514     0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
515     0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
516     0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
517     0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
518     0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
519     0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
520     0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
521     0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
522     0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
523     0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
524     0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
525 };
526 #endif
527
528 static int xan_decode_frame(AVCodecContext *avctx,
529                             void *data, int *got_frame,
530                             AVPacket *avpkt)
531 {
532     AVFrame *frame = data;
533     const uint8_t *buf = avpkt->data;
534     int ret, buf_size = avpkt->size;
535     XanContext *s = avctx->priv_data;
536     GetByteContext ctx;
537     int tag = 0;
538
539     bytestream2_init(&ctx, buf, buf_size);
540     while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
541         unsigned *tmpptr;
542         uint32_t new_pal;
543         int size;
544         int i;
545         tag  = bytestream2_get_le32(&ctx);
546         size = bytestream2_get_be32(&ctx);
547         if(size < 0) {
548             av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
549             return AVERROR_INVALIDDATA;
550         }
551         size = FFMIN(size, bytestream2_get_bytes_left(&ctx));
552         switch (tag) {
553         case PALT_TAG:
554             if (size < PALETTE_SIZE)
555                 return AVERROR_INVALIDDATA;
556             if (s->palettes_count >= PALETTES_MAX)
557                 return AVERROR_INVALIDDATA;
558             tmpptr = av_realloc(s->palettes,
559                                 (s->palettes_count + 1) * AVPALETTE_SIZE);
560             if (!tmpptr)
561                 return AVERROR(ENOMEM);
562             s->palettes = tmpptr;
563             tmpptr += s->palettes_count * AVPALETTE_COUNT;
564             for (i = 0; i < PALETTE_COUNT; i++) {
565 #if RUNTIME_GAMMA
566                 int r = gamma_corr(bytestream2_get_byteu(&ctx));
567                 int g = gamma_corr(bytestream2_get_byteu(&ctx));
568                 int b = gamma_corr(bytestream2_get_byteu(&ctx));
569 #else
570                 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
571                 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
572                 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
573 #endif
574                 *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
575             }
576             s->palettes_count++;
577             break;
578         case SHOT_TAG:
579             if (size < 4)
580                 return AVERROR_INVALIDDATA;
581             new_pal = bytestream2_get_le32(&ctx);
582             if (new_pal < s->palettes_count) {
583                 s->cur_palette = new_pal;
584             } else
585                 av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
586             break;
587         case VGA__TAG:
588             break;
589         default:
590             bytestream2_skip(&ctx, size);
591             break;
592         }
593     }
594     buf_size = bytestream2_get_bytes_left(&ctx);
595
596     if (s->palettes_count <= 0) {
597         av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
598         return AVERROR_INVALIDDATA;
599     }
600
601     if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
602         return ret;
603
604     if (!s->frame_size)
605         s->frame_size = frame->linesize[0] * s->avctx->height;
606
607     memcpy(frame->data[1],
608            s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
609
610     s->buf = ctx.buffer;
611     s->size = buf_size;
612
613     if (xan_wc3_decode_frame(s, frame) < 0)
614         return AVERROR_INVALIDDATA;
615
616     av_frame_unref(s->last_frame);
617     if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
618         return ret;
619
620     *got_frame = 1;
621
622     /* always report that the buffer was completely consumed */
623     return buf_size;
624 }
625
626 static av_cold int xan_decode_end(AVCodecContext *avctx)
627 {
628     XanContext *s = avctx->priv_data;
629
630     av_frame_free(&s->last_frame);
631
632     av_freep(&s->buffer1);
633     av_freep(&s->buffer2);
634     av_freep(&s->palettes);
635
636     return 0;
637 }
638
639 AVCodec ff_xan_wc3_decoder = {
640     .name           = "xan_wc3",
641     .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
642     .type           = AVMEDIA_TYPE_VIDEO,
643     .id             = AV_CODEC_ID_XAN_WC3,
644     .priv_data_size = sizeof(XanContext),
645     .init           = xan_decode_init,
646     .close          = xan_decode_end,
647     .decode         = xan_decode_frame,
648     .capabilities   = CODEC_CAP_DR1,
649 };