comparison rv10.c @ 0:986e461dc072 libavcodec

Initial revision
author glantau
date Sun, 22 Jul 2001 14:18:56 +0000
parents
children 35c1141e23d9
comparison
equal deleted inserted replaced
-1:000000000000 0:986e461dc072
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 static int done;
341
342 s->out_format = FMT_H263;
343
344 s->width = avctx->width;
345 s->height = avctx->height;
346
347 s->h263_rv10 = 1;
348 s->rv10_version = avctx->sub_id;
349
350 if (MPV_common_init(s) < 0)
351 return -1;
352
353 h263_decode_init_vlc(s);
354
355 /* init rv vlc */
356 if (!done) {
357 init_vlc(&rv_dc_lum, 9, 256,
358 rv_lum_bits, 1, 1,
359 rv_lum_code, 2, 2);
360 init_vlc(&rv_dc_chrom, 9, 256,
361 rv_chrom_bits, 1, 1,
362 rv_chrom_code, 2, 2);
363 done = 1;
364 }
365
366 return 0;
367 }
368
369 static int rv10_decode_end(AVCodecContext *avctx)
370 {
371 MpegEncContext *s = avctx->priv_data;
372
373 MPV_common_end(s);
374 return 0;
375 }
376
377 static int rv10_decode_frame(AVCodecContext *avctx,
378 void *data, int *data_size,
379 UINT8 *buf, int buf_size)
380 {
381 MpegEncContext *s = avctx->priv_data;
382 int i, mb_count, mb_pos, left;
383 DCTELEM block[6][64];
384 AVPicture *pict = data;
385
386 #ifdef DEBUG
387 printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
388 #endif
389
390 /* no supplementary picture */
391 if (buf_size == 0) {
392 *data_size = 0;
393 return 0;
394 }
395
396 init_get_bits(&s->gb, buf, buf_size);
397
398 mb_count = rv10_decode_picture_header(s);
399 if (mb_count < 0) {
400 #ifdef DEBUG
401 printf("HEADER ERROR\n");
402 #endif
403 return -1;
404 }
405
406 if (s->mb_x >= s->mb_width ||
407 s->mb_y >= s->mb_height) {
408 #ifdef DEBUG
409 printf("POS ERROR %d %d\n", s->mb_x, s->mb_y);
410 #endif
411 return -1;
412 }
413 mb_pos = s->mb_y * s->mb_width + s->mb_x;
414 left = s->mb_width * s->mb_height - mb_pos;
415 if (mb_count > left) {
416 #ifdef DEBUG
417 printf("COUNT ERROR\n");
418 #endif
419 return -1;
420 }
421
422 if (s->mb_x == 0 && s->mb_y == 0) {
423 MPV_frame_start(s);
424 }
425
426 #ifdef DEBUG
427 printf("qscale=%d\n", s->qscale);
428 #endif
429
430 /* default quantization values */
431 s->y_dc_scale = 8;
432 s->c_dc_scale = 8;
433 s->rv10_first_dc_coded[0] = 0;
434 s->rv10_first_dc_coded[1] = 0;
435 s->rv10_first_dc_coded[2] = 0;
436
437 /* decode each macroblock */
438 for(i=0;i<mb_count;i++) {
439 #ifdef DEBUG
440 printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
441 #endif
442
443 memset(block, 0, sizeof(block));
444 s->mv_dir = MV_DIR_FORWARD;
445 s->mv_type = MV_TYPE_16X16;
446 if (h263_decode_mb(s, block) < 0) {
447 #ifdef DEBUG
448 printf("ERROR\n");
449 #endif
450 return -1;
451 }
452 MPV_decode_mb(s, block);
453 if (++s->mb_x == s->mb_width) {
454 s->mb_x = 0;
455 s->mb_y++;
456 }
457 }
458
459 if (s->mb_x == 0 &&
460 s->mb_y == s->mb_height) {
461 MPV_frame_end(s);
462
463 pict->data[0] = s->current_picture[0];
464 pict->data[1] = s->current_picture[1];
465 pict->data[2] = s->current_picture[2];
466 pict->linesize[0] = s->linesize;
467 pict->linesize[1] = s->linesize / 2;
468 pict->linesize[2] = s->linesize / 2;
469
470 avctx->quality = s->qscale;
471 *data_size = sizeof(AVPicture);
472 } else {
473 *data_size = 0;
474 }
475 return buf_size;
476 }
477
478 AVCodec rv10_decoder = {
479 "rv10",
480 CODEC_TYPE_VIDEO,
481 CODEC_ID_RV10,
482 sizeof(MpegEncContext),
483 rv10_decode_init,
484 NULL,
485 rv10_decode_end,
486 rv10_decode_frame,
487 };