Mercurial > libavcodec.hg
annotate rv30.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 305536ce781f |
children | 8a4984c5cacc |
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 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8568
diff
changeset
|
23 * @file libavcodec/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); |
8568
4a93620c5aac
30l: when reading mb_offset in RV30 slice header its size
kostya
parents:
8566
diff
changeset
|
54 if(rpr){ |
4a93620c5aac
30l: when reading mb_offset in RV30 slice header its size
kostya
parents:
8566
diff
changeset
|
55 w = r->s.avctx->extradata[6 + rpr*2] << 2; |
4a93620c5aac
30l: when reading mb_offset in RV30 slice header its size
kostya
parents:
8566
diff
changeset
|
56 h = r->s.avctx->extradata[7 + rpr*2] << 2; |
8566
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
57 } |
8568
4a93620c5aac
30l: when reading mb_offset in RV30 slice header its size
kostya
parents:
8566
diff
changeset
|
58 si->width = w; |
4a93620c5aac
30l: when reading mb_offset in RV30 slice header its size
kostya
parents:
8566
diff
changeset
|
59 si->height = h; |
5968 | 60 mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); |
61 mb_bits = ff_rv34_get_start_offset(gb, mb_size); | |
62 si->start = get_bits(gb, mb_bits); | |
63 skip_bits1(gb); | |
64 return 0; | |
65 } | |
66 | |
67 /** | |
5981 | 68 * Decode 4x4 intra types array. |
5968 | 69 */ |
5993 | 70 static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) |
5968 | 71 { |
72 int i, j, k; | |
73 | |
9903
305536ce781f
RV3/4 intra types array causes alignment issues (at least on ARM5), thus change
kostya
parents:
9028
diff
changeset
|
74 for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ |
5968 | 75 for(j = 0; j < 4; j+= 2){ |
5995 | 76 int code = svq3_get_ue_golomb(gb) << 1; |
5968 | 77 if(code >= 81*2){ |
78 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); | |
79 return -1; | |
80 } | |
81 for(k = 0; k < 2; k++){ | |
9903
305536ce781f
RV3/4 intra types array causes alignment issues (at least on ARM5), thus change
kostya
parents:
9028
diff
changeset
|
82 int A = dst[-r->intra_types_stride] + 1; |
5968 | 83 int B = dst[-1] + 1; |
84 *dst++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]]; | |
85 if(dst[-1] == 9){ | |
86 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n"); | |
87 return -1; | |
88 } | |
89 } | |
90 } | |
91 } | |
92 return 0; | |
93 } | |
94 | |
95 /** | |
5981 | 96 * Decode macroblock information. |
5968 | 97 */ |
98 static int rv30_decode_mb_info(RV34DecContext *r) | |
99 { | |
100 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 }; | |
101 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 }; | |
102 MpegEncContext *s = &r->s; | |
103 GetBitContext *gb = &s->gb; | |
5995 | 104 int code = svq3_get_ue_golomb(gb); |
5968 | 105 |
106 if(code > 11){ | |
107 av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); | |
108 return -1; | |
109 } | |
110 if(code > 5){ | |
111 av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n"); | |
112 code -= 6; | |
113 } | |
6481 | 114 if(s->pict_type != FF_B_TYPE) |
5968 | 115 return rv30_p_types[code]; |
116 else | |
117 return rv30_b_types[code]; | |
118 } | |
119 | |
8409 | 120 static inline void rv30_weak_loop_filter(uint8_t *src, const int step, |
121 const int stride, const int lim) | |
122 { | |
123 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; | |
124 int i, diff; | |
125 | |
126 for(i = 0; i < 4; i++){ | |
127 diff = ((src[-2*step] - src[1*step]) - (src[-1*step] - src[0*step])*4) >> 3; | |
128 diff = av_clip(diff, -lim, lim); | |
129 src[-1*step] = cm[src[-1*step] + diff]; | |
130 src[ 0*step] = cm[src[ 0*step] - diff]; | |
131 src += stride; | |
132 } | |
133 } | |
134 | |
135 static void rv30_loop_filter(RV34DecContext *r, int row) | |
136 { | |
137 MpegEncContext *s = &r->s; | |
138 int mb_pos, mb_x; | |
139 int i, j, k; | |
140 uint8_t *Y, *C; | |
141 int loc_lim, cur_lim, left_lim = 0, top_lim = 0; | |
142 | |
143 mb_pos = row * s->mb_stride; | |
144 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
145 int mbtype = s->current_picture_ptr->mb_type[mb_pos]; | |
146 if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) | |
147 r->deblock_coefs[mb_pos] = 0xFFFF; | |
148 if(IS_INTRA(mbtype)) | |
149 r->cbp_chroma[mb_pos] = 0xFF; | |
150 } | |
151 | |
152 /* all vertical edges are filtered first | |
153 * and horizontal edges are filtered on the next iteration | |
154 */ | |
155 mb_pos = row * s->mb_stride; | |
156 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
157 cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; | |
158 if(mb_x) | |
159 left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]]; | |
160 for(j = 0; j < 16; j += 4){ | |
161 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; | |
162 for(i = !mb_x; i < 4; i++, Y += 4){ | |
163 int ij = i + j; | |
164 loc_lim = 0; | |
165 if(r->deblock_coefs[mb_pos] & (1 << ij)) | |
166 loc_lim = cur_lim; | |
167 else if(!i && r->deblock_coefs[mb_pos - 1] & (1 << (ij + 3))) | |
168 loc_lim = left_lim; | |
169 else if( i && r->deblock_coefs[mb_pos] & (1 << (ij - 1))) | |
170 loc_lim = cur_lim; | |
171 if(loc_lim) | |
172 rv30_weak_loop_filter(Y, 1, s->linesize, loc_lim); | |
173 } | |
174 } | |
175 for(k = 0; k < 2; k++){ | |
176 int cur_cbp, left_cbp = 0; | |
177 cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; | |
178 if(mb_x) | |
179 left_cbp = (r->cbp_chroma[mb_pos - 1] >> (k*4)) & 0xF; | |
180 for(j = 0; j < 8; j += 4){ | |
181 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x; | |
182 for(i = !mb_x; i < 2; i++, C += 4){ | |
183 int ij = i + (j >> 1); | |
184 loc_lim = 0; | |
185 if(cur_cbp && (1 << ij)) | |
186 loc_lim = cur_lim; | |
187 else if(!i && left_cbp & (1 << (ij + 1))) | |
188 loc_lim = left_lim; | |
189 else if( i && cur_cbp & (1 << (ij - 1))) | |
190 loc_lim = cur_lim; | |
191 if(loc_lim) | |
192 rv30_weak_loop_filter(C, 1, s->uvlinesize, loc_lim); | |
193 } | |
194 } | |
195 } | |
196 } | |
197 mb_pos = row * s->mb_stride; | |
198 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
199 cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; | |
200 if(row) | |
201 top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]]; | |
202 for(j = 4*!row; j < 16; j += 4){ | |
203 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; | |
204 for(i = 0; i < 4; i++, Y += 4){ | |
205 int ij = i + j; | |
206 loc_lim = 0; | |
207 if(r->deblock_coefs[mb_pos] & (1 << ij)) | |
208 loc_lim = cur_lim; | |
209 else if(!j && r->deblock_coefs[mb_pos - s->mb_stride] & (1 << (ij + 12))) | |
210 loc_lim = top_lim; | |
211 else if( j && r->deblock_coefs[mb_pos] & (1 << (ij - 4))) | |
212 loc_lim = cur_lim; | |
213 if(loc_lim) | |
214 rv30_weak_loop_filter(Y, s->linesize, 1, loc_lim); | |
215 } | |
216 } | |
217 for(k = 0; k < 2; k++){ | |
218 int cur_cbp, top_cbp = 0; | |
219 cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; | |
220 if(row) | |
221 top_cbp = (r->cbp_chroma[mb_pos - s->mb_stride] >> (k*4)) & 0xF; | |
222 for(j = 4*!row; j < 8; j += 4){ | |
223 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize; | |
224 for(i = 0; i < 2; i++, C += 4){ | |
225 int ij = i + (j >> 1); | |
226 loc_lim = 0; | |
227 if(r->cbp_chroma[mb_pos] && (1 << ij)) | |
228 loc_lim = cur_lim; | |
229 else if(!j && top_cbp & (1 << (ij + 2))) | |
230 loc_lim = top_lim; | |
231 else if( j && cur_cbp & (1 << (ij - 2))) | |
232 loc_lim = cur_lim; | |
233 if(loc_lim) | |
234 rv30_weak_loop_filter(C, s->uvlinesize, 1, loc_lim); | |
235 } | |
236 } | |
237 } | |
238 } | |
239 } | |
240 | |
5968 | 241 /** |
5981 | 242 * Initialize decoder. |
5968 | 243 */ |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
244 static av_cold int rv30_decode_init(AVCodecContext *avctx) |
5968 | 245 { |
246 RV34DecContext *r = avctx->priv_data; | |
247 | |
248 r->rv30 = 1; | |
249 ff_rv34_decode_init(avctx); | |
250 if(avctx->extradata_size < 2){ | |
5981 | 251 av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); |
5968 | 252 return -1; |
253 } | |
254 r->rpr = (avctx->extradata[1] & 7) >> 1; | |
255 r->rpr = FFMIN(r->rpr + 1, 3); | |
8566
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
256 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
|
257 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
|
258 6 + r->rpr * 2, avctx->extradata_size); |
48a4d9f4c6f8
RV30 decoder passes possible frame sizes in extradata and selects
kostya
parents:
8409
diff
changeset
|
259 } |
5968 | 260 r->parse_slice_header = rv30_parse_slice_header; |
261 r->decode_intra_types = rv30_decode_intra_types; | |
262 r->decode_mb_info = rv30_decode_mb_info; | |
8409 | 263 r->loop_filter = rv30_loop_filter; |
5968 | 264 r->luma_dc_quant_i = rv30_luma_dc_quant; |
265 r->luma_dc_quant_p = rv30_luma_dc_quant; | |
266 return 0; | |
267 } | |
268 | |
269 AVCodec rv30_decoder = { | |
270 "rv30", | |
271 CODEC_TYPE_VIDEO, | |
272 CODEC_ID_RV30, | |
273 sizeof(RV34DecContext), | |
274 rv30_decode_init, | |
275 NULL, | |
276 ff_rv34_decode_end, | |
277 ff_rv34_decode_frame, | |
5992 | 278 CODEC_CAP_DR1 | CODEC_CAP_DELAY, |
8753 | 279 .flush = ff_mpeg_flush, |
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"), |
9028 | 281 .pix_fmts= ff_pixfmt_list_420, |
5968 | 282 }; |