]> git.sesse.net Git - ffmpeg/blob - libavcodec/rv10.c
msmpeg4v2 encoding
[ffmpeg] / libavcodec / rv10.c
1 /*
2  * RV10 codec
3  * Copyright (c) 2000,2001 Gerard Lantau.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include "common.h"
23 #include "dsputil.h"
24 #include "avcodec.h"
25 #include "mpegvideo.h"
26
27 //#define DEBUG
28
29 static const UINT16 rv_lum_code[256] =
30 {
31  0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06,
32  0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
33  0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16,
34  0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e,
35  0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26,
36  0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e,
37  0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36,
38  0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e,
39  0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386,
40  0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e,
41  0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
42  0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e,
43  0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6,
44  0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
45  0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056,
46  0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004,
47  0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027,
48  0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
49  0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
50  0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
51  0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
52  0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
53  0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
54  0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
55  0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47,
56  0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f,
57  0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57,
58  0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
59  0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67,
60  0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f,
61  0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77,
62  0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f,
63 };
64
65 static const UINT8 rv_lum_bits[256] = 
66 {
67  14, 12, 12, 12, 12, 12, 12, 12,
68  12, 12, 12, 12, 12, 12, 12, 12,
69  12, 12, 12, 12, 12, 12, 12, 12,
70  12, 12, 12, 12, 12, 12, 12, 12,
71  12, 12, 12, 12, 12, 12, 12, 12,
72  12, 12, 12, 12, 12, 12, 12, 12,
73  12, 12, 12, 12, 12, 12, 12, 12,
74  12, 12, 12, 12, 12, 12, 12, 12,
75  12, 10, 10, 10, 10, 10, 10, 10,
76  10, 10, 10, 10, 10, 10, 10, 10,
77  10, 10, 10, 10, 10, 10, 10, 10,
78  10, 10, 10, 10, 10, 10, 10, 10,
79  10,  8,  8,  8,  8,  8,  8,  8,
80   8,  8,  8,  8,  8,  8,  8,  8,
81   8,  7,  7,  7,  7,  7,  7,  7,
82   7,  6,  6,  6,  6,  5,  5,  4,
83   2,  4,  5,  5,  6,  6,  6,  6,
84   7,  7,  7,  7,  7,  7,  7,  7,
85   8,  8,  8,  8,  8,  8,  8,  8,
86   8,  8,  8,  8,  8,  8,  8,  8,
87  10, 10, 10, 10, 10, 10, 10, 10,
88  10, 10, 10, 10, 10, 10, 10, 10,
89  10, 10, 10, 10, 10, 10, 10, 10,
90  10, 10, 10, 10, 10, 10, 10, 10,
91  12, 12, 12, 12, 12, 12, 12, 12,
92  12, 12, 12, 12, 12, 12, 12, 12,
93  12, 12, 12, 12, 12, 12, 12, 12,
94  12, 12, 12, 12, 12, 12, 12, 12,
95  12, 12, 12, 12, 12, 12, 12, 12,
96  12, 12, 12, 12, 12, 12, 12, 12,
97  12, 12, 12, 12, 12, 12, 12, 12,
98  12, 12, 12, 12, 12, 12, 12, 12,
99 };
100
101 static const UINT16 rv_chrom_code[256] =
102 {
103  0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06,
104  0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e,
105  0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16,
106  0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e,
107  0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26,
108  0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e,
109  0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36,
110  0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e,
111  0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86,
112  0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e,
113  0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96,
114  0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
115  0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6,
116  0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce,
117  0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6,
118  0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002,
119  0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037,
120  0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
121  0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7,
122  0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
123  0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
124  0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
125  0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
126  0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
127  0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47,
128  0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f,
129  0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57,
130  0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f,
131  0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67,
132  0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f,
133  0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77,
134  0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f,
135 };
136
137 static const UINT8 rv_chrom_bits[256] =
138 {
139  16, 14, 14, 14, 14, 14, 14, 14,
140  14, 14, 14, 14, 14, 14, 14, 14,
141  14, 14, 14, 14, 14, 14, 14, 14,
142  14, 14, 14, 14, 14, 14, 14, 14,
143  14, 14, 14, 14, 14, 14, 14, 14,
144  14, 14, 14, 14, 14, 14, 14, 14,
145  14, 14, 14, 14, 14, 14, 14, 14,
146  14, 14, 14, 14, 14, 14, 14, 14,
147  14, 12, 12, 12, 12, 12, 12, 12,
148  12, 12, 12, 12, 12, 12, 12, 12,
149  12, 12, 12, 12, 12, 12, 12, 12,
150  12, 12, 12, 12, 12, 12, 12, 12,
151  12, 10, 10, 10, 10, 10, 10, 10,
152  10, 10, 10, 10, 10, 10, 10, 10,
153  10,  8,  8,  8,  8,  8,  8,  8,
154   8,  6,  6,  6,  6,  4,  4,  3,
155   2,  3,  4,  4,  6,  6,  6,  6,
156   8,  8,  8,  8,  8,  8,  8,  8,
157  10, 10, 10, 10, 10, 10, 10, 10,
158  10, 10, 10, 10, 10, 10, 10, 10,
159  12, 12, 12, 12, 12, 12, 12, 12,
160  12, 12, 12, 12, 12, 12, 12, 12,
161  12, 12, 12, 12, 12, 12, 12, 12,
162  12, 12, 12, 12, 12, 12, 12, 12,
163  14, 14, 14, 14, 14, 14, 14, 14,
164  14, 14, 14, 14, 14, 14, 14, 14,
165  14, 14, 14, 14, 14, 14, 14, 14,
166  14, 14, 14, 14, 14, 14, 14, 14,
167  14, 14, 14, 14, 14, 14, 14, 14,
168  14, 14, 14, 14, 14, 14, 14, 14,
169  14, 14, 14, 14, 14, 14, 14, 14,
170  14, 14, 14, 14, 14, 14, 14, 14,
171 };
172
173 static VLC rv_dc_lum, rv_dc_chrom;
174
175 int rv_decode_dc(MpegEncContext *s, int n)
176 {
177     int code;
178
179     if (n < 4) {
180         code = get_vlc(&s->gb, &rv_dc_lum);
181         if (code < 0) {
182             /* XXX: I don't understand why they use LONGER codes than
183                necessary. The following code would be completely useless
184                if they had thought about it !!! */
185             code = get_bits(&s->gb, 7);
186             if (code == 0x7c) {
187                 code = (INT8)(get_bits(&s->gb, 7) + 1);
188             } else if (code == 0x7d) {
189                 code = -128 + get_bits(&s->gb, 7);
190             } else if (code == 0x7e) {
191                 if (get_bits(&s->gb, 1) == 0)
192                     code = (INT8)(get_bits(&s->gb, 8) + 1);
193                 else
194                     code = (INT8)(get_bits(&s->gb, 8));
195             } else if (code == 0x7f) {
196                 get_bits(&s->gb, 11);
197                 code = 1;
198             }
199         } else {
200             code -= 128;
201         }
202     } else {
203         code = get_vlc(&s->gb, &rv_dc_chrom);
204         /* same remark */
205         if (code < 0) {
206             code = get_bits(&s->gb, 9);
207             if (code == 0x1fc) {
208                 code = (INT8)(get_bits(&s->gb, 7) + 1);
209             } else if (code == 0x1fd) {
210                 code = -128 + get_bits(&s->gb, 7);
211             } else if (code == 0x1fe) {
212                 get_bits(&s->gb, 9);
213                 code = 1;
214             } else {
215                 return 0xffff;
216             }
217         } else {
218             code -= 128;
219         }
220     }
221     return -code;
222 }
223
224 /* write RV 1.0 compatible frame header */
225 void rv10_encode_picture_header(MpegEncContext *s, int picture_number)
226 {
227     align_put_bits(&s->pb);
228
229     put_bits(&s->pb, 1, 1);     /* marker */
230
231     put_bits(&s->pb, 1, (s->pict_type == P_TYPE));
232
233     put_bits(&s->pb, 1, 0);     /* not PB frame */
234
235     put_bits(&s->pb, 5, s->qscale);
236
237     if (s->pict_type == I_TYPE) {
238         /* specific MPEG like DC coding not used */
239     }
240     /* if multiple packets per frame are sent, the position at which
241        to display the macro blocks is coded here */
242     put_bits(&s->pb, 6, 0);     /* mb_x */
243     put_bits(&s->pb, 6, 0);     /* mb_y */
244     put_bits(&s->pb, 12, s->mb_width * s->mb_height);
245
246     put_bits(&s->pb, 3, 0);     /* ignored */
247 }
248
249 static int get_num(GetBitContext *gb)
250 {
251     int n, n1;
252
253     n = get_bits(gb, 16);
254     if (n >= 0x4000) {
255         return n - 0x4000;
256     } else {
257         n1 = get_bits(gb, 16);
258         return (n << 16) | n1;
259     }
260 }
261
262 /* read RV 1.0 compatible frame header */
263 static int rv10_decode_picture_header(MpegEncContext *s)
264 {
265     int mb_count, pb_frame, marker, h, full_frame;
266     
267     /* skip packet header */
268     h = get_bits(&s->gb, 8);
269     if ((h & 0xc0) == 0xc0) {
270         int len, pos;
271         full_frame = 1;
272         len = get_num(&s->gb);
273         pos = get_num(&s->gb);
274     } else {
275         int seq, frame_size, pos;
276         full_frame = 0;
277         seq = get_bits(&s->gb, 8);
278         frame_size = get_num(&s->gb);
279         pos = get_num(&s->gb);
280     }
281     /* picture number */
282     get_bits(&s->gb, 8);
283
284     marker = get_bits(&s->gb, 1);
285
286     if (get_bits(&s->gb, 1))
287         s->pict_type = P_TYPE;
288     else
289         s->pict_type = I_TYPE;
290
291     pb_frame = get_bits(&s->gb, 1);
292
293 #ifdef DEBUG
294     printf("pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame);
295 #endif
296     
297     if (pb_frame)
298         return -1;
299
300     s->qscale = get_bits(&s->gb, 5);
301
302     if (s->pict_type == I_TYPE) {
303         if (s->rv10_version == 3) {
304             /* specific MPEG like DC coding not used */
305             s->last_dc[0] = get_bits(&s->gb, 8);
306             s->last_dc[1] = get_bits(&s->gb, 8);
307             s->last_dc[2] = get_bits(&s->gb, 8);
308 #ifdef DEBUG
309             printf("DC:%d %d %d\n",
310                    s->last_dc[0],
311                    s->last_dc[1],
312                    s->last_dc[2]);
313 #endif
314         }
315     }
316     /* if multiple packets per frame are sent, the position at which
317        to display the macro blocks is coded here */
318     if (!full_frame) {
319         s->mb_x = get_bits(&s->gb, 6);  /* mb_x */
320         s->mb_y = get_bits(&s->gb, 6);  /* mb_y */
321         mb_count = get_bits(&s->gb, 12);
322     } else {
323         s->mb_x = 0;
324         s->mb_y = 0;
325         mb_count = s->mb_width * s->mb_height;
326     }
327
328     get_bits(&s->gb, 3);        /* ignored */
329     s->f_code = 1;
330     s->unrestricted_mv = 1;
331 #if 0
332     s->h263_long_vectors = 1;
333 #endif
334     return mb_count;
335 }
336
337 static int rv10_decode_init(AVCodecContext *avctx)
338 {
339     MpegEncContext *s = avctx->priv_data;
340     int i;
341     static int done;
342
343     s->out_format = FMT_H263;
344
345     s->width = avctx->width;
346     s->height = avctx->height;
347
348     s->h263_rv10 = 1;
349     s->rv10_version = avctx->sub_id;
350
351     if (MPV_common_init(s) < 0)
352         return -1;
353
354     /* XXX: suppress this matrix init, only needed because using mpeg1
355        dequantize in mmx case */
356     for(i=0;i<64;i++)
357         s->non_intra_matrix[i] = default_non_intra_matrix[i];
358
359     h263_decode_init_vlc(s);
360
361     /* init rv vlc */
362     if (!done) {
363         init_vlc(&rv_dc_lum, 9, 256, 
364                  rv_lum_bits, 1, 1,
365                  rv_lum_code, 2, 2);
366         init_vlc(&rv_dc_chrom, 9, 256, 
367                  rv_chrom_bits, 1, 1,
368                  rv_chrom_code, 2, 2);
369         done = 1;
370     }
371
372     return 0;
373 }
374
375 static int rv10_decode_end(AVCodecContext *avctx)
376 {
377     MpegEncContext *s = avctx->priv_data;
378
379     MPV_common_end(s);
380     return 0;
381 }
382
383 static int rv10_decode_frame(AVCodecContext *avctx, 
384                              void *data, int *data_size,
385                              UINT8 *buf, int buf_size)
386 {
387     MpegEncContext *s = avctx->priv_data;
388     int i, mb_count, mb_pos, left;
389     DCTELEM block[6][64];
390     AVPicture *pict = data; 
391
392 #ifdef DEBUG
393     printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
394 #endif
395
396     /* no supplementary picture */
397     if (buf_size == 0) {
398         *data_size = 0;
399         return 0;
400     }
401
402     init_get_bits(&s->gb, buf, buf_size);
403
404     mb_count = rv10_decode_picture_header(s);
405     if (mb_count < 0) {
406 #ifdef DEBUG
407         printf("HEADER ERROR\n");
408 #endif
409         return -1;
410     }
411     
412     if (s->mb_x >= s->mb_width ||
413         s->mb_y >= s->mb_height) {
414 #ifdef DEBUG
415         printf("POS ERROR %d %d\n", s->mb_x, s->mb_y);
416 #endif
417         return -1;
418     }
419     mb_pos = s->mb_y * s->mb_width + s->mb_x;
420     left = s->mb_width * s->mb_height - mb_pos;
421     if (mb_count > left) {
422 #ifdef DEBUG
423         printf("COUNT ERROR\n");
424 #endif
425         return -1;
426     }
427
428     if (s->mb_x == 0 && s->mb_y == 0) {
429         MPV_frame_start(s);
430     }
431
432 #ifdef DEBUG
433     printf("qscale=%d\n", s->qscale);
434 #endif
435
436     /* default quantization values */
437     s->y_dc_scale = 8;
438     s->c_dc_scale = 8;
439     s->rv10_first_dc_coded[0] = 0;
440     s->rv10_first_dc_coded[1] = 0;
441     s->rv10_first_dc_coded[2] = 0;
442     
443     /* decode each macroblock */
444     for(i=0;i<mb_count;i++) {
445 #ifdef DEBUG
446         printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
447 #endif
448         
449         memset(block, 0, sizeof(block));
450         s->mv_dir = MV_DIR_FORWARD;
451         s->mv_type = MV_TYPE_16X16; 
452         if (h263_decode_mb(s, block) < 0) {
453 #ifdef DEBUG
454             printf("ERROR\n");
455 #endif
456             return -1;
457         }
458         MPV_decode_mb(s, block);
459         if (++s->mb_x == s->mb_width) {
460             s->mb_x = 0;
461             s->mb_y++;
462         }
463     }
464
465     if (s->mb_x == 0 &&
466         s->mb_y == s->mb_height) {
467         MPV_frame_end(s);
468         
469         pict->data[0] = s->current_picture[0];
470         pict->data[1] = s->current_picture[1];
471         pict->data[2] = s->current_picture[2];
472         pict->linesize[0] = s->linesize;
473         pict->linesize[1] = s->linesize / 2;
474         pict->linesize[2] = s->linesize / 2;
475         
476         avctx->quality = s->qscale;
477         *data_size = sizeof(AVPicture);
478     } else {
479         *data_size = 0;
480     }
481     return buf_size;
482 }
483
484 AVCodec rv10_decoder = {
485     "rv10",
486     CODEC_TYPE_VIDEO,
487     CODEC_ID_RV10,
488     sizeof(MpegEncContext),
489     rv10_decode_init,
490     NULL,
491     rv10_decode_end,
492     rv10_decode_frame,
493 };