Mercurial > libavcodec.hg
annotate rv30.c @ 8566:48a4d9f4c6f8 libavcodec
RV30 decoder passes possible frame sizes in extradata and selects
an appropriate frame size from them in slice, make my decoder do
that as well.
This fixes issue 779
author | kostya |
---|---|
date | Sun, 11 Jan 2009 08:03:45 +0000 |
parents | 51c9946c70f9 |
children | 4a93620c5aac |
rev | line source |
---|---|
5968 | 1 /* |
2 * RV30 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 rv30.c | |
5981 | 24 * RV30 decoder |
5968 | 25 */ |
26 | |
27 #include "avcodec.h" | |
28 #include "dsputil.h" | |
29 #include "mpegvideo.h" | |
5995 | 30 #include "golomb.h" |
5968 | 31 |
32 #include "rv34.h" | |
33 #include "rv30data.h" | |
34 | |
35 | |
36 static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) | |
37 { | |
38 int mb_bits; | |
39 int w = r->s.width, h = r->s.height; | |
40 int mb_size; | |
8566
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
41 int rpr; |
5968 | 42 |
43 memset(si, 0, sizeof(SliceInfo)); | |
8075 | 44 if(get_bits(gb, 3)) |
45 return -1; | |
5968 | 46 si->type = get_bits(gb, 2); |
47 if(si->type == 1) si->type = 0; | |
48 if(get_bits1(gb)) | |
49 return -1; | |
50 si->quant = get_bits(gb, 5); | |
51 skip_bits1(gb); | |
6714
05c3a4b419e9
Calculate motion vector information based on PTS provided in slice header
kostya
parents:
6712
diff
changeset
|
52 si->pts = get_bits(gb, 13); |
8566
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
53 rpr = get_bits(gb, r->rpr); |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
54 if(!rpr){ |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
55 si->width = w; |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
56 si->height = h; |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
57 }else{ |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
58 si->width = r->s.avctx->extradata[6 + rpr*2] << 2; |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
59 si->height = r->s.avctx->extradata[7 + rpr*2] << 2; |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
60 } |
5968 | 61 mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); |
62 mb_bits = ff_rv34_get_start_offset(gb, mb_size); | |
63 si->start = get_bits(gb, mb_bits); | |
64 skip_bits1(gb); | |
65 return 0; | |
66 } | |
67 | |
68 /** | |
5981 | 69 * Decode 4x4 intra types array. |
5968 | 70 */ |
5993 | 71 static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) |
5968 | 72 { |
73 int i, j, k; | |
74 | |
75 for(i = 0; i < 4; i++, dst += r->s.b4_stride - 4){ | |
76 for(j = 0; j < 4; j+= 2){ | |
5995 | 77 int code = svq3_get_ue_golomb(gb) << 1; |
5968 | 78 if(code >= 81*2){ |
79 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); | |
80 return -1; | |
81 } | |
82 for(k = 0; k < 2; k++){ | |
83 int A = dst[-r->s.b4_stride] + 1; | |
84 int B = dst[-1] + 1; | |
85 *dst++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]]; | |
86 if(dst[-1] == 9){ | |
87 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n"); | |
88 return -1; | |
89 } | |
90 } | |
91 } | |
92 } | |
93 return 0; | |
94 } | |
95 | |
96 /** | |
5981 | 97 * Decode macroblock information. |
5968 | 98 */ |
99 static int rv30_decode_mb_info(RV34DecContext *r) | |
100 { | |
101 static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; | |
102 static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; | |
103 MpegEncContext *s = &r->s; | |
104 GetBitContext *gb = &s->gb; | |
5995 | 105 int code = svq3_get_ue_golomb(gb); |
5968 | 106 |
107 if(code > 11){ | |
108 av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); | |
109 return -1; | |
110 } | |
111 if(code > 5){ | |
112 av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n"); | |
113 code -= 6; | |
114 } | |
6481 | 115 if(s->pict_type != FF_B_TYPE) |
5968 | 116 return rv30_p_types[code]; |
117 else | |
118 return rv30_b_types[code]; | |
119 } | |
120 | |
8409 | 121 static inline void rv30_weak_loop_filter(uint8_t *src, const int step, |
122 const int stride, const int lim) | |
123 { | |
124 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; | |
125 int i, diff; | |
126 | |
127 for(i = 0; i < 4; i++){ | |
128 diff = ((src[-2*step] - src[1*step]) - (src[-1*step] - src[0*step])*4) >> 3; | |
129 diff = av_clip(diff, -lim, lim); | |
130 src[-1*step] = cm[src[-1*step] + diff]; | |
131 src[ 0*step] = cm[src[ 0*step] - diff]; | |
132 src += stride; | |
133 } | |
134 } | |
135 | |
136 static void rv30_loop_filter(RV34DecContext *r, int row) | |
137 { | |
138 MpegEncContext *s = &r->s; | |
139 int mb_pos, mb_x; | |
140 int i, j, k; | |
141 uint8_t *Y, *C; | |
142 int loc_lim, cur_lim, left_lim = 0, top_lim = 0; | |
143 | |
144 mb_pos = row * s->mb_stride; | |
145 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
146 int mbtype = s->current_picture_ptr->mb_type[mb_pos]; | |
147 if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) | |
148 r->deblock_coefs[mb_pos] = 0xFFFF; | |
149 if(IS_INTRA(mbtype)) | |
150 r->cbp_chroma[mb_pos] = 0xFF; | |
151 } | |
152 | |
153 /* all vertical edges are filtered first | |
154 * and horizontal edges are filtered on the next iteration | |
155 */ | |
156 mb_pos = row * s->mb_stride; | |
157 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
158 cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; | |
159 if(mb_x) | |
160 left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]]; | |
161 for(j = 0; j < 16; j += 4){ | |
162 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; | |
163 for(i = !mb_x; i < 4; i++, Y += 4){ | |
164 int ij = i + j; | |
165 loc_lim = 0; | |
166 if(r->deblock_coefs[mb_pos] & (1 << ij)) | |
167 loc_lim = cur_lim; | |
168 else if(!i && r->deblock_coefs[mb_pos - 1] & (1 << (ij + 3))) | |
169 loc_lim = left_lim; | |
170 else if( i && r->deblock_coefs[mb_pos] & (1 << (ij - 1))) | |
171 loc_lim = cur_lim; | |
172 if(loc_lim) | |
173 rv30_weak_loop_filter(Y, 1, s->linesize, loc_lim); | |
174 } | |
175 } | |
176 for(k = 0; k < 2; k++){ | |
177 int cur_cbp, left_cbp = 0; | |
178 cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; | |
179 if(mb_x) | |
180 left_cbp = (r->cbp_chroma[mb_pos - 1] >> (k*4)) & 0xF; | |
181 for(j = 0; j < 8; j += 4){ | |
182 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x; | |
183 for(i = !mb_x; i < 2; i++, C += 4){ | |
184 int ij = i + (j >> 1); | |
185 loc_lim = 0; | |
186 if(cur_cbp && (1 << ij)) | |
187 loc_lim = cur_lim; | |
188 else if(!i && left_cbp & (1 << (ij + 1))) | |
189 loc_lim = left_lim; | |
190 else if( i && cur_cbp & (1 << (ij - 1))) | |
191 loc_lim = cur_lim; | |
192 if(loc_lim) | |
193 rv30_weak_loop_filter(C, 1, s->uvlinesize, loc_lim); | |
194 } | |
195 } | |
196 } | |
197 } | |
198 mb_pos = row * s->mb_stride; | |
199 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
200 cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; | |
201 if(row) | |
202 top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]]; | |
203 for(j = 4*!row; j < 16; j += 4){ | |
204 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; | |
205 for(i = 0; i < 4; i++, Y += 4){ | |
206 int ij = i + j; | |
207 loc_lim = 0; | |
208 if(r->deblock_coefs[mb_pos] & (1 << ij)) | |
209 loc_lim = cur_lim; | |
210 else if(!j && r->deblock_coefs[mb_pos - s->mb_stride] & (1 << (ij + 12))) | |
211 loc_lim = top_lim; | |
212 else if( j && r->deblock_coefs[mb_pos] & (1 << (ij - 4))) | |
213 loc_lim = cur_lim; | |
214 if(loc_lim) | |
215 rv30_weak_loop_filter(Y, s->linesize, 1, loc_lim); | |
216 } | |
217 } | |
218 for(k = 0; k < 2; k++){ | |
219 int cur_cbp, top_cbp = 0; | |
220 cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; | |
221 if(row) | |
222 top_cbp = (r->cbp_chroma[mb_pos - s->mb_stride] >> (k*4)) & 0xF; | |
223 for(j = 4*!row; j < 8; j += 4){ | |
224 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize; | |
225 for(i = 0; i < 2; i++, C += 4){ | |
226 int ij = i + (j >> 1); | |
227 loc_lim = 0; | |
228 if(r->cbp_chroma[mb_pos] && (1 << ij)) | |
229 loc_lim = cur_lim; | |
230 else if(!j && top_cbp & (1 << (ij + 2))) | |
231 loc_lim = top_lim; | |
232 else if( j && cur_cbp & (1 << (ij - 2))) | |
233 loc_lim = cur_lim; | |
234 if(loc_lim) | |
235 rv30_weak_loop_filter(C, s->uvlinesize, 1, loc_lim); | |
236 } | |
237 } | |
238 } | |
239 } | |
240 } | |
241 | |
5968 | 242 /** |
5981 | 243 * Initialize decoder. |
5968 | 244 */ |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
245 static av_cold int rv30_decode_init(AVCodecContext *avctx) |
5968 | 246 { |
247 RV34DecContext *r = avctx->priv_data; | |
248 | |
249 r->rv30 = 1; | |
250 ff_rv34_decode_init(avctx); | |
251 if(avctx->extradata_size < 2){ | |
5981 | 252 av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); |
5968 | 253 return -1; |
254 } | |
255 r->rpr = (avctx->extradata[1] & 7) >> 1; | |
256 r->rpr = FFMIN(r->rpr + 1, 3); | |
8566
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
257 if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){ |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
258 av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n", |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
259 6 + r->rpr * 2, avctx->extradata_size); |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
260 } |
5968 | 261 r->parse_slice_header = rv30_parse_slice_header; |
262 r->decode_intra_types = rv30_decode_intra_types; | |
263 r->decode_mb_info = rv30_decode_mb_info; | |
8409 | 264 r->loop_filter = rv30_loop_filter; |
5968 | 265 r->luma_dc_quant_i = rv30_luma_dc_quant; |
266 r->luma_dc_quant_p = rv30_luma_dc_quant; | |
267 return 0; | |
268 } | |
269 | |
270 AVCodec rv30_decoder = { | |
271 "rv30", | |
272 CODEC_TYPE_VIDEO, | |
273 CODEC_ID_RV30, | |
274 sizeof(RV34DecContext), | |
275 rv30_decode_init, | |
276 NULL, | |
277 ff_rv34_decode_end, | |
278 ff_rv34_decode_frame, | |
5992 | 279 CODEC_CAP_DR1 | CODEC_CAP_DELAY, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6714
diff
changeset
|
280 .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), |
5968 | 281 }; |