Mercurial > libavcodec.hg
comparison rv40.c @ 5983:f0ae240d8349 libavcodec
RV40 decoder specific functions
author | kostya |
---|---|
date | Tue, 04 Dec 2007 17:41:46 +0000 |
parents | |
children | 61f0987be684 |
comparison
equal
deleted
inserted
replaced
5982:1900b70712ab | 5983:f0ae240d8349 |
---|---|
1 /* | |
2 * RV40 decoder | |
3 * Copyright (c) 2007 Konstantin Shishkov | |
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 rv40.c | |
24 * RV40 decoder | |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 #include "dsputil.h" | |
29 #include "mpegvideo.h" | |
30 | |
31 #include "rv34.h" | |
32 #include "rv40vlc2.h" | |
33 #include "rv40data.h" | |
34 | |
35 static VLC aic_top_vlc; | |
36 static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; | |
37 static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; | |
38 | |
39 /** | |
40 * Initialize all tables. | |
41 */ | |
42 static void rv40_init_tables() | |
43 { | |
44 int i; | |
45 | |
46 init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, | |
47 rv40_aic_top_vlc_bits, 1, 1, | |
48 rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC); | |
49 for(i = 0; i < AIC_MODE1_NUM; i++){ | |
50 // Every tenth VLC table is empty | |
51 if((i % 10) == 9) continue; | |
52 init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, | |
53 aic_mode1_vlc_bits[i], 1, 1, | |
54 aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC); | |
55 } | |
56 for(i = 0; i < AIC_MODE2_NUM; i++){ | |
57 init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, | |
58 aic_mode2_vlc_bits[i], 1, 1, | |
59 aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC); | |
60 } | |
61 for(i = 0; i < NUM_PTYPE_VLCS; i++) | |
62 init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, | |
63 ptype_vlc_bits[i], 1, 1, | |
64 ptype_vlc_codes[i], 1, 1, | |
65 ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); | |
66 for(i = 0; i < NUM_BTYPE_VLCS; i++) | |
67 init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, | |
68 btype_vlc_bits[i], 1, 1, | |
69 btype_vlc_codes[i], 1, 1, | |
70 btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); | |
71 } | |
72 | |
73 /** | |
74 * Get stored dimension from bitstream. | |
75 * | |
76 * If the width/height is the standard one then it's coded as a 3-bit index. | |
77 * Otherwise it is coded as escaped 8-bit portions. | |
78 */ | |
79 static int get_dimension(GetBitContext *gb, const int *dim) | |
80 { | |
81 int t = get_bits(gb, 3); | |
82 int val = dim[t]; | |
83 if(val < 0) | |
84 val = dim[get_bits1(gb) - val]; | |
85 if(!val){ | |
86 do{ | |
87 t = get_bits(gb, 8); | |
88 val += t << 2; | |
89 }while(t == 0xFF); | |
90 } | |
91 return val; | |
92 } | |
93 | |
94 /** | |
95 * Get encoded picture size - usually this is called from rv40_parse_slice_header. | |
96 */ | |
97 static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) | |
98 { | |
99 *w = get_dimension(gb, rv40_standard_widths); | |
100 *h = get_dimension(gb, rv40_standard_heights); | |
101 } | |
102 | |
103 static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) | |
104 { | |
105 int t, mb_bits; | |
106 int w = r->s.width, h = r->s.height; | |
107 int mb_size; | |
108 | |
109 memset(si, 0, sizeof(SliceInfo)); | |
110 if(get_bits1(gb)) | |
111 return -1; | |
112 si->type = get_bits(gb, 2); | |
113 if(si->type == 1) si->type = 0; | |
114 si->quant = get_bits(gb, 5); | |
115 if(get_bits(gb, 2)) | |
116 return -1; | |
117 si->vlc_set = get_bits(gb, 2); | |
118 skip_bits1(gb); | |
119 t = get_bits(gb, 13); /// ??? | |
120 if(!si->type || !get_bits1(gb)) | |
121 rv40_parse_picture_size(gb, &w, &h); | |
122 si->width = w; | |
123 si->height = h; | |
124 mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); | |
125 mb_bits = ff_rv34_get_start_offset(gb, mb_size); | |
126 si->start = get_bits(gb, mb_bits); | |
127 | |
128 return 0; | |
129 } | |
130 | |
131 /** | |
132 * Decode 4x4 intra types array. | |
133 */ | |
134 static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst) | |
135 { | |
136 MpegEncContext *s = &r->s; | |
137 int i, j, k, v; | |
138 int A, B, C; | |
139 int pattern; | |
140 int *ptr; | |
141 | |
142 for(i = 0; i < 4; i++, dst += s->b4_stride){ | |
143 if(!i && s->first_slice_line){ | |
144 pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); | |
145 dst[0] = (pattern >> 2) & 2; | |
146 dst[1] = (pattern >> 1) & 2; | |
147 dst[2] = pattern & 2; | |
148 dst[3] = (pattern << 1) & 2; | |
149 continue; | |
150 } | |
151 ptr = dst; | |
152 for(j = 0; j < 4; j++){ | |
153 /* Coefficients are read using VLC chosen by the prediction pattern | |
154 * The first one (used for retrieving a pair of coefficients) is | |
155 * constructed from the top, top right and left coefficients | |
156 * The second one (used for retrieving only one coefficient) is | |
157 * top + 10 * left. | |
158 */ | |
159 A = ptr[-s->b4_stride + 1]; // it won't be used for the last coefficient in a row | |
160 B = ptr[-s->b4_stride]; | |
161 C = ptr[-1]; | |
162 pattern = A + (B << 4) + (C << 8); | |
163 for(k = 0; k < MODE2_PATTERNS_NUM; k++) | |
164 if(pattern == rv40_aic_table_index[k]) | |
165 break; | |
166 if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients | |
167 v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); | |
168 *ptr++ = v/9; | |
169 *ptr++ = v%9; | |
170 j++; | |
171 }else{ | |
172 if(B != -1 && C != -1) | |
173 v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); | |
174 else{ // tricky decoding | |
175 v = 0; | |
176 switch(C){ | |
177 case -1: // code 0 -> 1, 1 -> 0 | |
178 if(B < 2) | |
179 v = get_bits1(gb) ^ 1; | |
180 break; | |
181 case 0: | |
182 case 2: // code 0 -> 2, 1 -> 0 | |
183 v = (get_bits1(gb) ^ 1) << 1; | |
184 break; | |
185 } | |
186 } | |
187 *ptr++ = v; | |
188 } | |
189 } | |
190 } | |
191 return 0; | |
192 } | |
193 | |
194 /** | |
195 * Decode macroblock information. | |
196 */ | |
197 static int rv40_decode_mb_info(RV34DecContext *r) | |
198 { | |
199 MpegEncContext *s = &r->s; | |
200 GetBitContext *gb = &s->gb; | |
201 int q, i; | |
202 int prev_type = 0; | |
203 int mb_pos = s->mb_x + s->mb_y * s->mb_stride; | |
204 int blocks[RV34_MB_TYPES] = {0}; | |
205 int count = 0; | |
206 | |
207 if(!r->s.mb_skip_run) | |
208 r->s.mb_skip_run = ff_rv34_get_gamma(gb); | |
209 | |
210 if(--r->s.mb_skip_run) | |
211 return RV34_MB_SKIP; | |
212 | |
213 if(r->avail[0]) | |
214 blocks[r->mb_type[mb_pos - 1]]++; | |
215 if(r->avail[1]){ | |
216 blocks[r->mb_type[mb_pos - s->mb_stride]]++; | |
217 if(r->avail[2]) | |
218 blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; | |
219 if(r->avail[3]) | |
220 blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; | |
221 } | |
222 | |
223 for(i = 0; i < RV34_MB_TYPES; i++){ | |
224 if(blocks[i] > count){ | |
225 count = blocks[i]; | |
226 prev_type = i; | |
227 } | |
228 } | |
229 if(s->pict_type == P_TYPE){ | |
230 prev_type = block_num_to_ptype_vlc_num[prev_type]; | |
231 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); | |
232 if(q < PBTYPE_ESCAPE) | |
233 return q; | |
234 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); | |
235 av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); | |
236 }else{ | |
237 prev_type = block_num_to_btype_vlc_num[prev_type]; | |
238 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); | |
239 if(q < PBTYPE_ESCAPE) | |
240 return q; | |
241 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); | |
242 av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); | |
243 } | |
244 return 0; | |
245 } | |
246 | |
247 /** | |
248 * Initialize decoder. | |
249 */ | |
250 static int rv40_decode_init(AVCodecContext *avctx) | |
251 { | |
252 RV34DecContext *r = avctx->priv_data; | |
253 | |
254 r->rv30 = 0; | |
255 ff_rv34_decode_init(avctx); | |
256 if(!aic_top_vlc.bits) | |
257 rv40_init_tables(); | |
258 r->parse_slice_header = rv40_parse_slice_header; | |
259 r->decode_intra_types = rv40_decode_intra_types; | |
260 r->decode_mb_info = rv40_decode_mb_info; | |
261 r->luma_dc_quant_i = rv40_luma_dc_quant[0]; | |
262 r->luma_dc_quant_p = rv40_luma_dc_quant[1]; | |
263 return 0; | |
264 } | |
265 | |
266 AVCodec rv40_decoder = { | |
267 "rv40", | |
268 CODEC_TYPE_VIDEO, | |
269 CODEC_ID_RV40, | |
270 sizeof(RV34DecContext), | |
271 rv40_decode_init, | |
272 NULL, | |
273 ff_rv34_decode_end, | |
274 ff_rv34_decode_frame, | |
275 }; |