Mercurial > libavcodec.hg
annotate svq3.c @ 4580:55d7ebd2d699 libavcodec
fix chroma mc2 bug, this is based on a patch by (Oleg Metelitsa oleg hitron co kr)
and does slow the mc2 chroma put down, avg interrestingly seems unaffected speedwise on duron
this of course should be rather done in a way which doesnt slow it down but its better a few %
slower but correct then incorrect
author | michael |
---|---|
date | Fri, 23 Feb 2007 14:29:13 +0000 |
parents | b0bfea78ca13 |
children | a96d905dcbaa |
rev | line source |
---|---|
1234 | 1 /* |
2 * Copyright (c) 2003 The FFmpeg Project. | |
3 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
4 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * FFmpeg is free software; you can redistribute it and/or |
1234 | 7 * modify it under the terms of the GNU Lesser General Public |
8 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
9 * version 2.1 of the License, or (at your option) any later version. |
1234 | 10 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
11 * FFmpeg is distributed in the hope that it will be useful, |
1234 | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
17 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1234 | 19 * |
20 * | |
21 * How to use this decoder: | |
22 * SVQ3 data is transported within Apple Quicktime files. Quicktime files | |
1235
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
23 * have stsd atoms to describe media trak properties. A stsd atom for a |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
24 * video trak contains 1 or more ImageDescription atoms. These atoms begin |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
25 * with the 4-byte length of the atom followed by the codec fourcc. Some |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
26 * decoders need information in this atom to operate correctly. Such |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
27 * is the case with SVQ3. In order to get the best use out of this decoder, |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
28 * the calling app must make the SVQ3 ImageDescription atom available |
1234 | 29 * via the AVCodecContext's extradata[_size] field: |
30 * | |
2967 | 31 * AVCodecContext.extradata = pointer to ImageDescription, first characters |
1235
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
32 * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length |
2967 | 33 * AVCodecContext.extradata_size = size of ImageDescription atom memory |
34 * buffer (which will be the same as the ImageDescription atom size field | |
1235
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
35 * from the QT file, minus 4 bytes since the length is missing) |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
36 * |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
37 * You will know you have these parameters passed correctly when the decoder |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
38 * correctly decodes this file: |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
39 * ftp://ftp.mplayerhq.hu/MPlayer/samples/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov |
1234 | 40 * |
41 */ | |
2967 | 42 |
1234 | 43 /** |
44 * @file svq3.c | |
45 * svq3 decoder. | |
46 */ | |
47 | |
2967 | 48 #define FULLPEL_MODE 1 |
49 #define HALFPEL_MODE 2 | |
1265 | 50 #define THIRDPEL_MODE 3 |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
51 #define PREDICT_MODE 4 |
2967 | 52 |
1252 | 53 /* dual scan (from some older h264 draft) |
54 o-->o-->o o | |
55 | /| | |
56 o o o / o | |
57 | / | |/ | | |
58 o o o o | |
2967 | 59 / |
1252 | 60 o-->o-->o-->o |
61 */ | |
1234 | 62 static const uint8_t svq3_scan[16]={ |
63 0+0*4, 1+0*4, 2+0*4, 2+1*4, | |
64 2+2*4, 3+0*4, 3+1*4, 3+2*4, | |
65 0+1*4, 0+2*4, 1+1*4, 1+2*4, | |
66 0+3*4, 1+3*4, 2+3*4, 3+3*4, | |
67 }; | |
68 | |
69 static const uint8_t svq3_pred_0[25][2] = { | |
70 { 0, 0 }, | |
71 { 1, 0 }, { 0, 1 }, | |
72 { 0, 2 }, { 1, 1 }, { 2, 0 }, | |
73 { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 }, | |
74 { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 }, | |
75 { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 }, | |
76 { 2, 4 }, { 3, 3 }, { 4, 2 }, | |
77 { 4, 3 }, { 3, 4 }, | |
78 { 4, 4 } | |
79 }; | |
80 | |
81 static const int8_t svq3_pred_1[6][6][5] = { | |
82 { { 2,-1,-1,-1,-1 }, { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, | |
83 { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, { 1, 2,-1,-1,-1 } }, | |
84 { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 }, | |
85 { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } }, | |
86 { { 2, 0,-1,-1,-1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 }, | |
87 { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } }, | |
88 { { 2, 0,-1,-1,-1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 }, | |
89 { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } }, | |
90 { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 }, | |
91 { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } }, | |
92 { { 0, 2,-1,-1,-1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 }, | |
93 { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } }, | |
94 }; | |
95 | |
96 static const struct { uint8_t run; uint8_t level; } svq3_dct_tables[2][16] = { | |
97 { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, | |
98 { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } }, | |
99 { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, | |
100 { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } } | |
101 }; | |
102 | |
103 static const uint32_t svq3_dequant_coeff[32] = { | |
104 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718, | |
105 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873, | |
106 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683, | |
107 61694, 68745, 77615, 89113,100253,109366,126635,141533 | |
108 }; | |
109 | |
110 | |
111 static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp){ | |
112 const int qmul= svq3_dequant_coeff[qp]; | |
113 #define stride 16 | |
114 int i; | |
115 int temp[16]; | |
116 static const int x_offset[4]={0, 1*stride, 4* stride, 5*stride}; | |
117 static const int y_offset[4]={0, 2*stride, 8* stride, 10*stride}; | |
118 | |
119 for(i=0; i<4; i++){ | |
120 const int offset= y_offset[i]; | |
121 const int z0= 13*(block[offset+stride*0] + block[offset+stride*4]); | |
122 const int z1= 13*(block[offset+stride*0] - block[offset+stride*4]); | |
123 const int z2= 7* block[offset+stride*1] - 17*block[offset+stride*5]; | |
124 const int z3= 17* block[offset+stride*1] + 7*block[offset+stride*5]; | |
125 | |
126 temp[4*i+0]= z0+z3; | |
127 temp[4*i+1]= z1+z2; | |
128 temp[4*i+2]= z1-z2; | |
129 temp[4*i+3]= z0-z3; | |
130 } | |
131 | |
132 for(i=0; i<4; i++){ | |
133 const int offset= x_offset[i]; | |
134 const int z0= 13*(temp[4*0+i] + temp[4*2+i]); | |
135 const int z1= 13*(temp[4*0+i] - temp[4*2+i]); | |
136 const int z2= 7* temp[4*1+i] - 17*temp[4*3+i]; | |
137 const int z3= 17* temp[4*1+i] + 7*temp[4*3+i]; | |
138 | |
139 block[stride*0 +offset]= ((z0 + z3)*qmul + 0x80000)>>20; | |
140 block[stride*2 +offset]= ((z1 + z2)*qmul + 0x80000)>>20; | |
141 block[stride*8 +offset]= ((z1 - z2)*qmul + 0x80000)>>20; | |
142 block[stride*10+offset]= ((z0 - z3)*qmul + 0x80000)>>20; | |
143 } | |
144 } | |
145 #undef stride | |
146 | |
147 static void svq3_add_idct_c (uint8_t *dst, DCTELEM *block, int stride, int qp, int dc){ | |
148 const int qmul= svq3_dequant_coeff[qp]; | |
149 int i; | |
4176 | 150 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
1234 | 151 |
152 if (dc) { | |
153 dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2)); | |
154 block[0] = 0; | |
155 } | |
156 | |
157 for (i=0; i < 4; i++) { | |
158 const int z0= 13*(block[0 + 4*i] + block[2 + 4*i]); | |
159 const int z1= 13*(block[0 + 4*i] - block[2 + 4*i]); | |
160 const int z2= 7* block[1 + 4*i] - 17*block[3 + 4*i]; | |
161 const int z3= 17* block[1 + 4*i] + 7*block[3 + 4*i]; | |
162 | |
163 block[0 + 4*i]= z0 + z3; | |
164 block[1 + 4*i]= z1 + z2; | |
165 block[2 + 4*i]= z1 - z2; | |
166 block[3 + 4*i]= z0 - z3; | |
167 } | |
168 | |
169 for (i=0; i < 4; i++) { | |
170 const int z0= 13*(block[i + 4*0] + block[i + 4*2]); | |
171 const int z1= 13*(block[i + 4*0] - block[i + 4*2]); | |
172 const int z2= 7* block[i + 4*1] - 17*block[i + 4*3]; | |
173 const int z3= 17* block[i + 4*1] + 7*block[i + 4*3]; | |
174 const int rr= (dc + 0x80000); | |
175 | |
176 dst[i + stride*0]= cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ]; | |
177 dst[i + stride*1]= cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ]; | |
178 dst[i + stride*2]= cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ]; | |
179 dst[i + stride*3]= cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ]; | |
180 } | |
181 } | |
182 | |
183 static void pred4x4_down_left_svq3_c(uint8_t *src, uint8_t *topright, int stride){ | |
2967 | 184 LOAD_TOP_EDGE |
185 LOAD_LEFT_EDGE | |
1234 | 186 const __attribute__((unused)) int unu0= t0; |
187 const __attribute__((unused)) int unu1= l0; | |
188 | |
189 src[0+0*stride]=(l1 + t1)>>1; | |
190 src[1+0*stride]= | |
191 src[0+1*stride]=(l2 + t2)>>1; | |
192 src[2+0*stride]= | |
193 src[1+1*stride]= | |
194 src[0+2*stride]= | |
195 src[3+0*stride]= | |
196 src[2+1*stride]= | |
197 src[1+2*stride]= | |
198 src[0+3*stride]= | |
199 src[3+1*stride]= | |
200 src[2+2*stride]= | |
201 src[1+3*stride]= | |
202 src[3+2*stride]= | |
203 src[2+3*stride]= | |
204 src[3+3*stride]=(l3 + t3)>>1; | |
1282 | 205 } |
1234 | 206 |
207 static void pred16x16_plane_svq3_c(uint8_t *src, int stride){ | |
208 pred16x16_plane_compat_c(src, stride, 1); | |
209 } | |
210 | |
211 static inline int svq3_decode_block (GetBitContext *gb, DCTELEM *block, | |
2979 | 212 int index, const int type) { |
1234 | 213 |
214 static const uint8_t *const scan_patterns[4] = | |
215 { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan }; | |
216 | |
217 int run, level, sign, vlc, limit; | |
218 const int intra = (3 * type) >> 2; | |
219 const uint8_t *const scan = scan_patterns[type]; | |
220 | |
221 for (limit=(16 >> intra); index < 16; index=limit, limit+=8) { | |
222 for (; (vlc = svq3_get_ue_golomb (gb)) != 0; index++) { | |
223 | |
224 if (vlc == INVALID_VLC) | |
2979 | 225 return -1; |
1234 | 226 |
227 sign = (vlc & 0x1) - 1; | |
228 vlc = (vlc + 1) >> 1; | |
229 | |
230 if (type == 3) { | |
2979 | 231 if (vlc < 3) { |
232 run = 0; | |
233 level = vlc; | |
234 } else if (vlc < 4) { | |
235 run = 1; | |
236 level = 1; | |
237 } else { | |
238 run = (vlc & 0x3); | |
239 level = ((vlc + 9) >> 2) - run; | |
240 } | |
1234 | 241 } else { |
2979 | 242 if (vlc < 16) { |
243 run = svq3_dct_tables[intra][vlc].run; | |
244 level = svq3_dct_tables[intra][vlc].level; | |
245 } else if (intra) { | |
246 run = (vlc & 0x7); | |
247 level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); | |
248 } else { | |
249 run = (vlc & 0xF); | |
250 level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); | |
251 } | |
1234 | 252 } |
253 | |
254 if ((index += run) >= limit) | |
2979 | 255 return -1; |
1234 | 256 |
257 block[scan[index]] = (level ^ sign) - sign; | |
258 } | |
259 | |
260 if (type != 2) { | |
261 break; | |
262 } | |
263 } | |
264 | |
265 return 0; | |
266 } | |
267 | |
1319 | 268 static inline void svq3_mc_dir_part (MpegEncContext *s, |
2979 | 269 int x, int y, int width, int height, |
270 int mx, int my, int dxy, | |
271 int thirdpel, int dir, int avg) { | |
1319 | 272 |
273 const Picture *pic = (dir == 0) ? &s->last_picture : &s->next_picture; | |
1234 | 274 uint8_t *src, *dest; |
275 int i, emu = 0; | |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
276 int blocksize= 2 - (width>>3); //16->0, 8->1, 4->2 |
1234 | 277 |
1265 | 278 mx += x; |
279 my += y; | |
2967 | 280 |
1268 | 281 if (mx < 0 || mx >= (s->h_edge_pos - width - 1) || |
282 my < 0 || my >= (s->v_edge_pos - height - 1)) { | |
1234 | 283 |
284 if ((s->flags & CODEC_FLAG_EMU_EDGE)) { | |
285 emu = 1; | |
286 } | |
287 | |
1268 | 288 mx = clip (mx, -16, (s->h_edge_pos - width + 15)); |
289 my = clip (my, -16, (s->v_edge_pos - height + 15)); | |
1234 | 290 } |
291 | |
292 /* form component predictions */ | |
293 dest = s->current_picture.data[0] + x + y*s->linesize; | |
1319 | 294 src = pic->data[0] + mx + my*s->linesize; |
1234 | 295 |
296 if (emu) { | |
1321 | 297 ff_emulated_edge_mc (s->edge_emu_buffer, src, s->linesize, (width + 1), (height + 1), |
2979 | 298 mx, my, s->h_edge_pos, s->v_edge_pos); |
1234 | 299 src = s->edge_emu_buffer; |
300 } | |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
301 if(thirdpel) |
1319 | 302 (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->linesize, width, height); |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
303 else |
1319 | 304 (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->linesize, height); |
1234 | 305 |
306 if (!(s->flags & CODEC_FLAG_GRAY)) { | |
2979 | 307 mx = (mx + (mx < (int) x)) >> 1; |
308 my = (my + (my < (int) y)) >> 1; | |
1234 | 309 width = (width >> 1); |
310 height = (height >> 1); | |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
311 blocksize++; |
1234 | 312 |
313 for (i=1; i < 3; i++) { | |
314 dest = s->current_picture.data[i] + (x >> 1) + (y >> 1)*s->uvlinesize; | |
1319 | 315 src = pic->data[i] + mx + my*s->uvlinesize; |
1234 | 316 |
317 if (emu) { | |
1321 | 318 ff_emulated_edge_mc (s->edge_emu_buffer, src, s->uvlinesize, (width + 1), (height + 1), |
2979 | 319 mx, my, (s->h_edge_pos >> 1), (s->v_edge_pos >> 1)); |
1321 | 320 src = s->edge_emu_buffer; |
1234 | 321 } |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
322 if(thirdpel) |
1319 | 323 (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->uvlinesize, width, height); |
1267
85b71f9f7450
moving the svq3 motion compensation stuff to dsputil (this also means that existing optimized halfpel code is used now ...)
michaelni
parents:
1265
diff
changeset
|
324 else |
1319 | 325 (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->uvlinesize, height); |
1234 | 326 } |
327 } | |
328 } | |
329 | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
330 static inline int svq3_mc_dir (H264Context *h, int size, int mode, int dir, int avg) { |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
331 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
332 int i, j, k, mx, my, dx, dy, x, y; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
333 MpegEncContext *const s = (MpegEncContext *) h; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
334 const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
335 const int part_height = 16 >> ((unsigned) (size + 1) / 3); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
336 const int extra_width = (mode == PREDICT_MODE) ? -16*6 : 0; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
337 const int h_edge_pos = 6*(s->h_edge_pos - part_width ) - extra_width; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
338 const int v_edge_pos = 6*(s->v_edge_pos - part_height) - extra_width; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
339 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
340 for (i=0; i < 16; i+=part_height) { |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
341 for (j=0; j < 16; j+=part_width) { |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
342 const int b_xy = (4*s->mb_x+(j>>2)) + (4*s->mb_y+(i>>2))*h->b_stride; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
343 int dxy; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
344 x = 16*s->mb_x + j; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
345 y = 16*s->mb_y + i; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
346 k = ((j>>2)&1) + ((i>>1)&2) + ((j>>1)&4) + (i&8); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
347 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
348 if (mode != PREDICT_MODE) { |
2979 | 349 pred_motion (h, k, (part_width >> 2), dir, 1, &mx, &my); |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
350 } else { |
2979 | 351 mx = s->next_picture.motion_val[0][b_xy][0]<<1; |
352 my = s->next_picture.motion_val[0][b_xy][1]<<1; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
353 |
2979 | 354 if (dir == 0) { |
355 mx = ((mx * h->frame_num_offset) / h->prev_frame_num_offset + 1)>>1; | |
356 my = ((my * h->frame_num_offset) / h->prev_frame_num_offset + 1)>>1; | |
357 } else { | |
358 mx = ((mx * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1)>>1; | |
359 my = ((my * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1)>>1; | |
360 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
361 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
362 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
363 /* clip motion vector prediction to frame border */ |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
364 mx = clip (mx, extra_width - 6*x, h_edge_pos - 6*x); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
365 my = clip (my, extra_width - 6*y, v_edge_pos - 6*y); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
366 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
367 /* get (optional) motion vector differential */ |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
368 if (mode == PREDICT_MODE) { |
2979 | 369 dx = dy = 0; |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
370 } else { |
2979 | 371 dy = svq3_get_se_golomb (&s->gb); |
372 dx = svq3_get_se_golomb (&s->gb); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
373 |
2979 | 374 if (dx == INVALID_VLC || dy == INVALID_VLC) { |
2452 | 375 av_log(h->s.avctx, AV_LOG_ERROR, "invalid MV vlc\n"); |
2979 | 376 return -1; |
377 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
378 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
379 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
380 /* compute motion vector */ |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
381 if (mode == THIRDPEL_MODE) { |
2979 | 382 int fx, fy; |
383 mx = ((mx + 1)>>1) + dx; | |
384 my = ((my + 1)>>1) + dy; | |
385 fx= ((unsigned)(mx + 0x3000))/3 - 0x1000; | |
386 fy= ((unsigned)(my + 0x3000))/3 - 0x1000; | |
387 dxy= (mx - 3*fx) + 4*(my - 3*fy); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
388 |
2979 | 389 svq3_mc_dir_part (s, x, y, part_width, part_height, fx, fy, dxy, 1, dir, avg); |
390 mx += mx; | |
391 my += my; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
392 } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) { |
2979 | 393 mx = ((unsigned)(mx + 1 + 0x3000))/3 + dx - 0x1000; |
394 my = ((unsigned)(my + 1 + 0x3000))/3 + dy - 0x1000; | |
395 dxy= (mx&1) + 2*(my&1); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
396 |
2979 | 397 svq3_mc_dir_part (s, x, y, part_width, part_height, mx>>1, my>>1, dxy, 0, dir, avg); |
398 mx *= 3; | |
399 my *= 3; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
400 } else { |
2979 | 401 mx = ((unsigned)(mx + 3 + 0x6000))/6 + dx - 0x1000; |
402 my = ((unsigned)(my + 3 + 0x6000))/6 + dy - 0x1000; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
403 |
2979 | 404 svq3_mc_dir_part (s, x, y, part_width, part_height, mx, my, 0, 0, dir, avg); |
405 mx *= 6; | |
406 my *= 6; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
407 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
408 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
409 /* update mv_cache */ |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
410 if (mode != PREDICT_MODE) { |
2979 | 411 int32_t mv = pack16to32(mx,my); |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
412 |
2979 | 413 if (part_height == 8 && i < 8) { |
414 *(int32_t *) h->mv_cache[dir][scan8[k] + 1*8] = mv; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
415 |
2979 | 416 if (part_width == 8 && j < 8) { |
417 *(int32_t *) h->mv_cache[dir][scan8[k] + 1 + 1*8] = mv; | |
418 } | |
419 } | |
420 if (part_width == 8 && j < 8) { | |
421 *(int32_t *) h->mv_cache[dir][scan8[k] + 1] = mv; | |
422 } | |
423 if (part_width == 4 || part_height == 4) { | |
424 *(int32_t *) h->mv_cache[dir][scan8[k]] = mv; | |
425 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
426 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
427 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
428 /* write back motion vectors */ |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
429 fill_rectangle(s->current_picture.motion_val[dir][b_xy], part_width>>2, part_height>>2, h->b_stride, pack16to32(mx,my), 4); |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
430 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
431 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
432 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
433 return 0; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
434 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
435 |
1234 | 436 static int svq3_decode_mb (H264Context *h, unsigned int mb_type) { |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
437 int i, j, k, m, dir, mode; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
438 int cbp = 0; |
1234 | 439 uint32_t vlc; |
440 int8_t *top, *left; | |
441 MpegEncContext *const s = (MpegEncContext *) h; | |
442 const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; | |
443 const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; | |
444 | |
2979 | 445 h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; |
446 h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; | |
447 h->topright_samples_available = 0xFFFF; | |
1234 | 448 |
2979 | 449 if (mb_type == 0) { /* SKIP */ |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
450 if (s->pict_type == P_TYPE || s->next_picture.mb_type[mb_xy] == -1) { |
1319 | 451 svq3_mc_dir_part (s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 0, 0); |
452 | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
453 if (s->pict_type == B_TYPE) { |
2979 | 454 svq3_mc_dir_part (s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 1, 1); |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
455 } |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
456 |
1319 | 457 mb_type = MB_TYPE_SKIP; |
458 } else { | |
2088
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
459 mb_type= FFMIN(s->next_picture.mb_type[mb_xy], 6); |
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
460 if(svq3_mc_dir (h, mb_type, PREDICT_MODE, 0, 0) < 0) |
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
461 return -1; |
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
462 if(svq3_mc_dir (h, mb_type, PREDICT_MODE, 1, 1) < 0) |
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
463 return -1; |
1319 | 464 |
465 mb_type = MB_TYPE_16x16; | |
466 } | |
2979 | 467 } else if (mb_type < 8) { /* INTER */ |
1234 | 468 if (h->thirdpel_flag && h->halfpel_flag == !get_bits (&s->gb, 1)) { |
1265 | 469 mode = THIRDPEL_MODE; |
1234 | 470 } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits (&s->gb, 1)) { |
1265 | 471 mode = HALFPEL_MODE; |
1234 | 472 } else { |
1265 | 473 mode = FULLPEL_MODE; |
1234 | 474 } |
475 | |
476 /* fill caches */ | |
1319 | 477 /* note ref_cache should contain here: |
1252 | 478 ???????? |
479 ???11111 | |
480 N??11111 | |
481 N??11111 | |
482 N??11111 | |
483 N | |
484 */ | |
2967 | 485 |
1319 | 486 for (m=0; m < 2; m++) { |
487 if (s->mb_x > 0 && h->intra4x4_pred_mode[mb_xy - 1][0] != -1) { | |
2979 | 488 for (i=0; i < 4; i++) { |
489 *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - 1 + i*h->b_stride]; | |
490 } | |
1319 | 491 } else { |
2979 | 492 for (i=0; i < 4; i++) { |
493 *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = 0; | |
494 } | |
1234 | 495 } |
1319 | 496 if (s->mb_y > 0) { |
2979 | 497 memcpy (h->mv_cache[m][scan8[0] - 1*8], s->current_picture.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t)); |
498 memset (&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[mb_xy - s->mb_stride][4] == -1) ? PART_NOT_AVAILABLE : 1, 4); | |
1234 | 499 |
2979 | 500 if (s->mb_x < (s->mb_width - 1)) { |
501 *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride + 4]; | |
502 h->ref_cache[m][scan8[0] + 4 - 1*8] = | |
503 (h->intra4x4_pred_mode[mb_xy - s->mb_stride + 1][0] == -1 || | |
504 h->intra4x4_pred_mode[mb_xy - s->mb_stride][4] == -1) ? PART_NOT_AVAILABLE : 1; | |
505 }else | |
506 h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; | |
507 if (s->mb_x > 0) { | |
508 *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride - 1]; | |
509 h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[mb_xy - s->mb_stride - 1][3] == -1) ? PART_NOT_AVAILABLE : 1; | |
510 }else | |
511 h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; | |
1252 | 512 }else |
2979 | 513 memset (&h->ref_cache[m][scan8[0] - 1*8 - 1], PART_NOT_AVAILABLE, 8); |
1319 | 514 |
515 if (s->pict_type != B_TYPE) | |
2979 | 516 break; |
1319 | 517 } |
1234 | 518 |
519 /* decode motion vector(s) and form prediction(s) */ | |
1319 | 520 if (s->pict_type == P_TYPE) { |
2088
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
521 if(svq3_mc_dir (h, (mb_type - 1), mode, 0, 0) < 0) |
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
522 return -1; |
2979 | 523 } else { /* B_TYPE */ |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
524 if (mb_type != 2) { |
2979 | 525 if(svq3_mc_dir (h, 0, mode, 0, 0) < 0) |
2088
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
526 return -1; |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
527 } else { |
2979 | 528 for (i=0; i < 4; i++) { |
529 memset (s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
530 } | |
1234 | 531 } |
1319 | 532 if (mb_type != 1) { |
2979 | 533 if(svq3_mc_dir (h, 0, mode, 1, (mb_type == 3)) < 0) |
2088
19d4d5c6a8f4
1000l to myself for FFMIN(...,0) instead of ...,6)
michael
parents:
2086
diff
changeset
|
534 return -1; |
1319 | 535 } else { |
2979 | 536 for (i=0; i < 4; i++) { |
537 memset (s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
538 } | |
1319 | 539 } |
1234 | 540 } |
541 | |
542 mb_type = MB_TYPE_16x16; | |
2979 | 543 } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */ |
1234 | 544 memset (h->intra4x4_pred_mode_cache, -1, 8*5*sizeof(int8_t)); |
545 | |
1319 | 546 if (mb_type == 8) { |
547 if (s->mb_x > 0) { | |
2979 | 548 for (i=0; i < 4; i++) { |
549 h->intra4x4_pred_mode_cache[scan8[0] - 1 + i*8] = h->intra4x4_pred_mode[mb_xy - 1][i]; | |
550 } | |
551 if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) { | |
552 h->left_samples_available = 0x5F5F; | |
553 } | |
1234 | 554 } |
1319 | 555 if (s->mb_y > 0) { |
2979 | 556 h->intra4x4_pred_mode_cache[4+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][4]; |
557 h->intra4x4_pred_mode_cache[5+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][5]; | |
558 h->intra4x4_pred_mode_cache[6+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][6]; | |
559 h->intra4x4_pred_mode_cache[7+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][3]; | |
1319 | 560 |
2979 | 561 if (h->intra4x4_pred_mode_cache[4+8*0] == -1) { |
562 h->top_samples_available = 0x33FF; | |
563 } | |
1319 | 564 } |
1234 | 565 |
1319 | 566 /* decode prediction codes for luma blocks */ |
567 for (i=0; i < 16; i+=2) { | |
2979 | 568 vlc = svq3_get_ue_golomb (&s->gb); |
1234 | 569 |
2979 | 570 if (vlc >= 25){ |
2452 | 571 av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc); |
2979 | 572 return -1; |
2452 | 573 } |
1319 | 574 |
2979 | 575 left = &h->intra4x4_pred_mode_cache[scan8[i] - 1]; |
576 top = &h->intra4x4_pred_mode_cache[scan8[i] - 8]; | |
1234 | 577 |
2979 | 578 left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]]; |
579 left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]]; | |
1234 | 580 |
2979 | 581 if (left[1] == -1 || left[2] == -1){ |
2452 | 582 av_log(h->s.avctx, AV_LOG_ERROR, "weird prediction\n"); |
2979 | 583 return -1; |
2452 | 584 } |
1319 | 585 } |
2979 | 586 } else { /* mb_type == 33, DC_128_PRED block type */ |
1319 | 587 for (i=0; i < 4; i++) { |
2979 | 588 memset (&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_PRED, 4); |
1319 | 589 } |
1234 | 590 } |
591 | |
592 write_back_intra_pred_mode (h); | |
1319 | 593 |
594 if (mb_type == 8) { | |
595 check_intra4x4_pred_mode (h); | |
596 | |
597 h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; | |
598 h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; | |
599 } else { | |
600 for (i=0; i < 4; i++) { | |
601 memset (&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_128_PRED, 4); | |
602 } | |
603 | |
604 h->top_samples_available = 0x33FF; | |
605 h->left_samples_available = 0x5F5F; | |
606 } | |
1234 | 607 |
608 mb_type = MB_TYPE_INTRA4x4; | |
2979 | 609 } else { /* INTRA16x16 */ |
1234 | 610 dir = i_mb_type_info[mb_type - 8].pred_mode; |
611 dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; | |
612 | |
2452 | 613 if ((h->intra16x16_pred_mode = check_intra_pred_mode (h, dir)) == -1){ |
614 av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); | |
1234 | 615 return -1; |
2452 | 616 } |
1234 | 617 |
618 cbp = i_mb_type_info[mb_type - 8].cbp; | |
619 mb_type = MB_TYPE_INTRA16x16; | |
620 } | |
621 | |
622 if (!IS_INTER(mb_type) && s->pict_type != I_TYPE) { | |
623 for (i=0; i < 4; i++) { | |
624 memset (s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
625 } | |
1319 | 626 if (s->pict_type == B_TYPE) { |
627 for (i=0; i < 4; i++) { | |
2979 | 628 memset (s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); |
1319 | 629 } |
630 } | |
1234 | 631 } |
632 if (!IS_INTRA4x4(mb_type)) { | |
633 memset (h->intra4x4_pred_mode[mb_xy], DC_PRED, 8); | |
634 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
635 if (!IS_SKIP(mb_type) || s->pict_type == B_TYPE) { |
1252 | 636 memset (h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t)); |
637 s->dsp.clear_blocks(h->mb); | |
1234 | 638 } |
639 | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
640 if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == B_TYPE)) { |
2452 | 641 if ((vlc = svq3_get_ue_golomb (&s->gb)) >= 48){ |
642 av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
643 return -1; |
2452 | 644 } |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
645 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
646 cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc] : golomb_to_inter_cbp[vlc]; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
647 } |
1234 | 648 if (IS_INTRA16x16(mb_type) || (s->pict_type != I_TYPE && s->adaptive_quant && cbp)) { |
649 s->qscale += svq3_get_se_golomb (&s->gb); | |
650 | |
2452 | 651 if (s->qscale > 31){ |
652 av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); | |
1234 | 653 return -1; |
2452 | 654 } |
1234 | 655 } |
656 if (IS_INTRA16x16(mb_type)) { | |
2452 | 657 if (svq3_decode_block (&s->gb, h->mb, 0, 0)){ |
658 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); | |
1234 | 659 return -1; |
2452 | 660 } |
1234 | 661 } |
662 | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
663 if (cbp) { |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
664 const int index = IS_INTRA16x16(mb_type) ? 1 : 0; |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
665 const int type = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1); |
1234 | 666 |
667 for (i=0; i < 4; i++) { | |
668 if ((cbp & (1 << i))) { | |
2979 | 669 for (j=0; j < 4; j++) { |
670 k = index ? ((j&1) + 2*(i&1) + 2*(j&2) + 4*(i&2)) : (4*i + j); | |
671 h->non_zero_count_cache[ scan8[k] ] = 1; | |
1234 | 672 |
2979 | 673 if (svq3_decode_block (&s->gb, &h->mb[16*k], index, type)){ |
2452 | 674 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding block\n"); |
2979 | 675 return -1; |
2452 | 676 } |
2979 | 677 } |
1234 | 678 } |
679 } | |
680 | |
681 if ((cbp & 0x30)) { | |
682 for (i=0; i < 2; ++i) { | |
2979 | 683 if (svq3_decode_block (&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)){ |
2452 | 684 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); |
2979 | 685 return -1; |
2452 | 686 } |
1234 | 687 } |
688 | |
689 if ((cbp & 0x20)) { | |
2979 | 690 for (i=0; i < 8; i++) { |
691 h->non_zero_count_cache[ scan8[16+i] ] = 1; | |
1234 | 692 |
2979 | 693 if (svq3_decode_block (&s->gb, &h->mb[16*(16 + i)], 1, 1)){ |
2452 | 694 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); |
2979 | 695 return -1; |
2452 | 696 } |
2979 | 697 } |
1234 | 698 } |
699 } | |
700 } | |
701 | |
702 s->current_picture.mb_type[mb_xy] = mb_type; | |
703 | |
704 if (IS_INTRA(mb_type)) { | |
705 h->chroma_pred_mode = check_intra_pred_mode (h, DC_PRED8x8); | |
706 } | |
707 | |
708 return 0; | |
709 } | |
710 | |
1319 | 711 static int svq3_decode_slice_header (H264Context *h) { |
712 MpegEncContext *const s = (MpegEncContext *) h; | |
713 const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; | |
714 int i, header; | |
715 | |
716 header = get_bits (&s->gb, 8); | |
717 | |
718 if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { | |
719 /* TODO: what? */ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1330
diff
changeset
|
720 av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); |
1319 | 721 return -1; |
722 } else { | |
723 int length = (header >> 5) & 3; | |
724 | |
2614
5e24800ab329
various fixes related to the non alt_bitstream_reader
michael
parents:
2453
diff
changeset
|
725 h->next_slice_index = get_bits_count(&s->gb) + 8*show_bits (&s->gb, 8*length) + 8*length; |
1319 | 726 |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
727 if (h->next_slice_index > s->gb.size_in_bits){ |
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
728 av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n"); |
1319 | 729 return -1; |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
730 } |
1319 | 731 |
732 s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); | |
2614
5e24800ab329
various fixes related to the non alt_bitstream_reader
michael
parents:
2453
diff
changeset
|
733 skip_bits(&s->gb, 8); |
1319 | 734 |
735 if (length > 0) { | |
2614
5e24800ab329
various fixes related to the non alt_bitstream_reader
michael
parents:
2453
diff
changeset
|
736 memcpy ((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3], |
1319 | 737 &s->gb.buffer[s->gb.size_in_bits >> 3], (length - 1)); |
738 } | |
739 } | |
740 | |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
741 if ((i = svq3_get_ue_golomb (&s->gb)) == INVALID_VLC || i >= 3){ |
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
742 av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); |
1319 | 743 return -1; |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
744 } |
1319 | 745 |
746 h->slice_type = golomb_to_pict_type[i]; | |
747 | |
748 if ((header & 0x9F) == 2) { | |
749 i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); | |
750 s->mb_skip_run = get_bits (&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); | |
751 } else { | |
752 get_bits1 (&s->gb); | |
753 s->mb_skip_run = 0; | |
754 } | |
755 | |
756 h->slice_num = get_bits (&s->gb, 8); | |
757 s->qscale = get_bits (&s->gb, 5); | |
758 s->adaptive_quant = get_bits1 (&s->gb); | |
759 | |
760 /* unknown fields */ | |
761 get_bits1 (&s->gb); | |
762 | |
763 if (h->unknown_svq3_flag) { | |
764 get_bits1 (&s->gb); | |
765 } | |
766 | |
767 get_bits1 (&s->gb); | |
768 get_bits (&s->gb, 2); | |
769 | |
770 while (get_bits1 (&s->gb)) { | |
771 get_bits (&s->gb, 8); | |
772 } | |
773 | |
774 /* reset intra predictors and invalidate motion vector references */ | |
775 if (s->mb_x > 0) { | |
776 memset (h->intra4x4_pred_mode[mb_xy - 1], -1, 4*sizeof(int8_t)); | |
777 memset (h->intra4x4_pred_mode[mb_xy - s->mb_x], -1, 8*sizeof(int8_t)*s->mb_x); | |
778 } | |
779 if (s->mb_y > 0) { | |
780 memset (h->intra4x4_pred_mode[mb_xy - s->mb_stride], -1, 8*sizeof(int8_t)*(s->mb_width - s->mb_x)); | |
781 | |
782 if (s->mb_x > 0) { | |
783 h->intra4x4_pred_mode[mb_xy - s->mb_stride - 1][3] = -1; | |
784 } | |
785 } | |
786 | |
787 return 0; | |
788 } | |
789 | |
1234 | 790 static int svq3_decode_frame (AVCodecContext *avctx, |
2979 | 791 void *data, int *data_size, |
792 uint8_t *buf, int buf_size) { | |
1234 | 793 MpegEncContext *const s = avctx->priv_data; |
794 H264Context *const h = avctx->priv_data; | |
1319 | 795 int m, mb_type; |
1877
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
796 unsigned char *extradata; |
1878
838c18d1e7fc
be smarter about the variable size of the extra SVQ3 data
melanson
parents:
1877
diff
changeset
|
797 unsigned int size; |
1319 | 798 |
1234 | 799 s->flags = avctx->flags; |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
800 s->flags2 = avctx->flags2; |
1699 | 801 s->unrestricted_mv = 1; |
802 | |
1234 | 803 if (!s->context_initialized) { |
1268 | 804 s->width = avctx->width; |
805 s->height = avctx->height; | |
1234 | 806 h->pred4x4[DIAG_DOWN_LEFT_PRED] = pred4x4_down_left_svq3_c; |
807 h->pred16x16[PLANE_PRED8x8] = pred16x16_plane_svq3_c; | |
808 h->halfpel_flag = 1; | |
809 h->thirdpel_flag = 1; | |
1319 | 810 h->unknown_svq3_flag = 0; |
1234 | 811 h->chroma_qp = 4; |
812 | |
813 if (MPV_common_init (s) < 0) | |
814 return -1; | |
815 | |
1268 | 816 h->b_stride = 4*s->mb_width; |
817 | |
1234 | 818 alloc_tables (h); |
1319 | 819 |
1877
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
820 /* prowl for the "SEQH" marker in the extradata */ |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
821 extradata = (unsigned char *)avctx->extradata; |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
822 for (m = 0; m < avctx->extradata_size; m++) { |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
823 if (!memcmp (extradata, "SEQH", 4)) |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
824 break; |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
825 extradata++; |
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
826 } |
1878
838c18d1e7fc
be smarter about the variable size of the extra SVQ3 data
melanson
parents:
1877
diff
changeset
|
827 |
1877
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
828 /* if a match was found, parse the extra data */ |
4392
e0c94f1b8f55
maybe fix segfault with missing extradata (unchecked)
michael
parents:
4364
diff
changeset
|
829 if (extradata && !memcmp (extradata, "SEQH", 4)) { |
1319 | 830 |
831 GetBitContext gb; | |
1234 | 832 |
4364 | 833 size = AV_RB32(&extradata[4]); |
2966
564788471dd4
bitstream related fixes from [PATCH] from DivX, Part 9: bitstream crashes by (Steve Lhomme | slhomme divxcorp com)
michael
parents:
2792
diff
changeset
|
834 init_get_bits (&gb, extradata + 8, size*8); |
1234 | 835 |
1319 | 836 /* 'frame size code' and optional 'width, height' */ |
837 if (get_bits (&gb, 3) == 7) { | |
2979 | 838 get_bits (&gb, 12); |
839 get_bits (&gb, 12); | |
1234 | 840 } |
841 | |
1319 | 842 h->halfpel_flag = get_bits1 (&gb); |
843 h->thirdpel_flag = get_bits1 (&gb); | |
844 | |
845 /* unknown fields */ | |
846 get_bits1 (&gb); | |
847 get_bits1 (&gb); | |
848 get_bits1 (&gb); | |
849 get_bits1 (&gb); | |
850 | |
851 s->low_delay = get_bits1 (&gb); | |
852 | |
853 /* unknown field */ | |
854 get_bits1 (&gb); | |
855 | |
856 while (get_bits1 (&gb)) { | |
2979 | 857 get_bits (&gb, 8); |
1319 | 858 } |
859 | |
860 h->unknown_svq3_flag = get_bits1 (&gb); | |
861 avctx->has_b_frames = !s->low_delay; | |
1234 | 862 } |
863 } | |
864 | |
1319 | 865 /* special case for last picture */ |
866 if (buf_size == 0) { | |
867 if (s->next_picture_ptr && !s->low_delay) { | |
868 *(AVFrame *) data = *(AVFrame *) &s->next_picture; | |
869 *data_size = sizeof(AVFrame); | |
1234 | 870 } |
1319 | 871 return 0; |
1234 | 872 } |
873 | |
1319 | 874 init_get_bits (&s->gb, buf, 8*buf_size); |
1234 | 875 |
1319 | 876 s->mb_x = s->mb_y = 0; |
877 | |
878 if (svq3_decode_slice_header (h)) | |
1234 | 879 return -1; |
880 | |
1319 | 881 s->pict_type = h->slice_type; |
882 s->picture_number = h->slice_num; | |
1234 | 883 |
1250 | 884 if(avctx->debug&FF_DEBUG_PICT_INFO){ |
2967 | 885 av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d\n", |
1264 | 886 av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, |
1250 | 887 s->adaptive_quant, s->qscale |
888 ); | |
889 } | |
1234 | 890 |
1319 | 891 /* for hurry_up==5 */ |
892 s->current_picture.pict_type = s->pict_type; | |
893 s->current_picture.key_frame = (s->pict_type == I_TYPE); | |
894 | |
895 /* skip b frames if we dont have reference frames */ | |
896 if (s->last_picture_ptr == NULL && s->pict_type == B_TYPE) return 0; | |
897 /* skip b frames if we are in a hurry */ | |
898 if (avctx->hurry_up && s->pict_type == B_TYPE) return 0; | |
899 /* skip everything if we are in a hurry >= 5 */ | |
900 if (avctx->hurry_up >= 5) return 0; | |
2792 | 901 if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) |
902 ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) | |
903 || avctx->skip_frame >= AVDISCARD_ALL) | |
904 return 0; | |
1319 | 905 |
906 if (s->next_p_frame_damaged) { | |
907 if (s->pict_type == B_TYPE) | |
908 return 0; | |
909 else | |
910 s->next_p_frame_damaged = 0; | |
911 } | |
1234 | 912 |
4395 | 913 if (frame_start (h) < 0) |
914 return -1; | |
1234 | 915 |
1319 | 916 if (s->pict_type == B_TYPE) { |
917 h->frame_num_offset = (h->slice_num - h->prev_frame_num); | |
918 | |
919 if (h->frame_num_offset < 0) { | |
920 h->frame_num_offset += 256; | |
921 } | |
922 if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1330
diff
changeset
|
923 av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n"); |
1319 | 924 return -1; |
925 } | |
926 } else { | |
927 h->prev_frame_num = h->frame_num; | |
928 h->frame_num = h->slice_num; | |
929 h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num); | |
930 | |
931 if (h->prev_frame_num_offset < 0) { | |
932 h->prev_frame_num_offset += 256; | |
933 } | |
934 } | |
935 | |
936 for(m=0; m<2; m++){ | |
937 int i; | |
938 for(i=0; i<4; i++){ | |
939 int j; | |
940 for(j=-1; j<4; j++) | |
2979 | 941 h->ref_cache[m][scan8[0] + 8*i + j]= 1; |
1319 | 942 h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; |
943 } | |
1252 | 944 } |
2967 | 945 |
1234 | 946 for (s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { |
947 for (s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { | |
1319 | 948 |
2614
5e24800ab329
various fixes related to the non alt_bitstream_reader
michael
parents:
2453
diff
changeset
|
949 if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits && |
2979 | 950 ((get_bits_count(&s->gb) & 7) == 0 || show_bits (&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) { |
1319 | 951 |
2979 | 952 skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb)); |
953 s->gb.size_in_bits = 8*buf_size; | |
1319 | 954 |
2979 | 955 if (svq3_decode_slice_header (h)) |
956 return -1; | |
1319 | 957 |
2979 | 958 /* TODO: support s->mb_skip_run */ |
1319 | 959 } |
960 | |
961 mb_type = svq3_get_ue_golomb (&s->gb); | |
1234 | 962 |
963 if (s->pict_type == I_TYPE) { | |
2979 | 964 mb_type += 8; |
1319 | 965 } else if (s->pict_type == B_TYPE && mb_type >= 4) { |
2979 | 966 mb_type += 4; |
1234 | 967 } |
1319 | 968 if (mb_type > 33 || svq3_decode_mb (h, mb_type)) { |
2979 | 969 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); |
970 return -1; | |
1234 | 971 } |
972 | |
973 if (mb_type != 0) { | |
2979 | 974 hl_decode_mb (h); |
1234 | 975 } |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
976 |
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
977 if (s->pict_type != B_TYPE && !s->low_delay) { |
2979 | 978 s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = |
979 (s->pict_type == P_TYPE && mb_type < 8) ? (mb_type - 1) : -1; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
980 } |
1234 | 981 } |
1268 | 982 |
983 ff_draw_horiz_band(s, 16*s->mb_y, 16); | |
1234 | 984 } |
985 | |
1319 | 986 MPV_frame_end(s); |
987 | |
988 if (s->pict_type == B_TYPE || s->low_delay) { | |
989 *(AVFrame *) data = *(AVFrame *) &s->current_picture; | |
990 } else { | |
991 *(AVFrame *) data = *(AVFrame *) &s->last_picture; | |
992 } | |
1234 | 993 |
1319 | 994 avctx->frame_number = s->picture_number - 1; |
995 | |
996 /* dont output the last pic after seeking */ | |
997 if (s->last_picture_ptr || s->low_delay) { | |
998 *data_size = sizeof(AVFrame); | |
999 } | |
1000 | |
1234 | 1001 return buf_size; |
1002 } | |
1003 | |
1004 | |
1005 AVCodec svq3_decoder = { | |
1006 "svq3", | |
1007 CODEC_TYPE_VIDEO, | |
1008 CODEC_ID_SVQ3, | |
1009 sizeof(H264Context), | |
1010 decode_init, | |
1011 NULL, | |
1012 decode_end, | |
1013 svq3_decode_frame, | |
2453 | 1014 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY, |
1234 | 1015 }; |