Mercurial > libavcodec.hg
annotate svq3.c @ 10852:86d7ab878805 libavcodec
Get rid of #include "svq3.c"
functions called more than per mb are moved into the header, scan8 is also
as it must be known at compiletime.
The code after this patch duplicates h264data.h, this has been done to minimize
the changes in this step and allow more fine grained benchmarking.
Speedwise this is 1% faster on my pentium dual core with diegos cursed cathedral
sample.
author | michael |
---|---|
date | Tue, 12 Jan 2010 05:30:31 +0000 |
parents | abf5c20eebf4 |
children | 974ac220c93a |
rev | line source |
---|---|
1234 | 1 /* |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8590
diff
changeset
|
2 * Copyright (c) 2003 The FFmpeg Project |
1234 | 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 |
5215 | 19 */ |
20 | |
21 /* | |
1234 | 22 * How to use this decoder: |
23 * 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
|
24 * 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
|
25 * 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
|
26 * 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
|
27 * 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
|
28 * 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
|
29 * the calling app must make the SVQ3 ImageDescription atom available |
1234 | 30 * via the AVCodecContext's extradata[_size] field: |
31 * | |
2967 | 32 * AVCodecContext.extradata = pointer to ImageDescription, first characters |
1235
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
33 * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length |
2967 | 34 * AVCodecContext.extradata_size = size of ImageDescription atom memory |
35 * 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
|
36 * 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
|
37 * |
8bb75c3c2f21
change the way the ImageDescription is passed to the decoder
tmmm
parents:
1234
diff
changeset
|
38 * 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
|
39 * correctly decodes this file: |
8459 | 40 * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov |
1234 | 41 */ |
10852 | 42 #include "internal.h" |
43 #include "dsputil.h" | |
44 #include "avcodec.h" | |
45 #include "mpegvideo.h" | |
46 #include "h264.h" | |
47 | |
48 #include "h264data.h" //FIXME FIXME FIXME | |
49 | |
50 #include "golomb.h" | |
51 #include "rectangle.h" | |
52 #include "vdpau_internal.h" | |
53 | |
54 #if ARCH_X86 | |
55 #include "x86/h264_i386.h" | |
56 #endif | |
2967 | 57 |
8590 | 58 #if CONFIG_ZLIB |
8067 | 59 #include <zlib.h> |
60 #endif | |
61 | |
8080
847bcb16028a
Add the function declaration of ff_svq1_packet_checksum to svq1.h and include
diego
parents:
8067
diff
changeset
|
62 #include "svq1.h" |
847bcb16028a
Add the function declaration of ff_svq1_packet_checksum to svq1.h and include
diego
parents:
8067
diff
changeset
|
63 |
1234 | 64 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8629
diff
changeset
|
65 * @file libavcodec/svq3.c |
1234 | 66 * svq3 decoder. |
67 */ | |
68 | |
2967 | 69 #define FULLPEL_MODE 1 |
70 #define HALFPEL_MODE 2 | |
1265 | 71 #define THIRDPEL_MODE 3 |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
72 #define PREDICT_MODE 4 |
2967 | 73 |
1252 | 74 /* dual scan (from some older h264 draft) |
75 o-->o-->o o | |
76 | /| | |
77 o o o / o | |
78 | / | |/ | | |
79 o o o o | |
2967 | 80 / |
1252 | 81 o-->o-->o-->o |
82 */ | |
8196 | 83 static const uint8_t svq3_scan[16] = { |
84 0+0*4, 1+0*4, 2+0*4, 2+1*4, | |
85 2+2*4, 3+0*4, 3+1*4, 3+2*4, | |
86 0+1*4, 0+2*4, 1+1*4, 1+2*4, | |
87 0+3*4, 1+3*4, 2+3*4, 3+3*4, | |
1234 | 88 }; |
89 | |
90 static const uint8_t svq3_pred_0[25][2] = { | |
8196 | 91 { 0, 0 }, |
92 { 1, 0 }, { 0, 1 }, | |
93 { 0, 2 }, { 1, 1 }, { 2, 0 }, | |
94 { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 }, | |
95 { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 }, | |
96 { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 }, | |
97 { 2, 4 }, { 3, 3 }, { 4, 2 }, | |
98 { 4, 3 }, { 3, 4 }, | |
99 { 4, 4 } | |
1234 | 100 }; |
101 | |
102 static const int8_t svq3_pred_1[6][6][5] = { | |
8196 | 103 { { 2,-1,-1,-1,-1 }, { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, |
104 { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, { 1, 2,-1,-1,-1 } }, | |
105 { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 }, | |
106 { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } }, | |
107 { { 2, 0,-1,-1,-1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 }, | |
108 { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } }, | |
109 { { 2, 0,-1,-1,-1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 }, | |
110 { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } }, | |
111 { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 }, | |
112 { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } }, | |
113 { { 0, 2,-1,-1,-1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 }, | |
114 { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } }, | |
1234 | 115 }; |
116 | |
117 static const struct { uint8_t run; uint8_t level; } svq3_dct_tables[2][16] = { | |
8196 | 118 { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, |
119 { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } }, | |
120 { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, | |
121 { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } } | |
1234 | 122 }; |
123 | |
124 static const uint32_t svq3_dequant_coeff[32] = { | |
8196 | 125 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718, |
126 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873, | |
127 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683, | |
128 61694, 68745, 77615, 89113,100253,109366,126635,141533 | |
1234 | 129 }; |
130 | |
131 | |
10852 | 132 void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp) |
8195 | 133 { |
8196 | 134 const int qmul = svq3_dequant_coeff[qp]; |
1234 | 135 #define stride 16 |
136 int i; | |
137 int temp[16]; | |
8196 | 138 static const int x_offset[4] = {0, 1*stride, 4* stride, 5*stride}; |
139 static const int y_offset[4] = {0, 2*stride, 8* stride, 10*stride}; | |
1234 | 140 |
8196 | 141 for (i = 0; i < 4; i++){ |
142 const int offset = y_offset[i]; | |
143 const int z0 = 13*(block[offset+stride*0] + block[offset+stride*4]); | |
144 const int z1 = 13*(block[offset+stride*0] - block[offset+stride*4]); | |
145 const int z2 = 7* block[offset+stride*1] - 17*block[offset+stride*5]; | |
146 const int z3 = 17* block[offset+stride*1] + 7*block[offset+stride*5]; | |
1234 | 147 |
8196 | 148 temp[4*i+0] = z0+z3; |
149 temp[4*i+1] = z1+z2; | |
150 temp[4*i+2] = z1-z2; | |
151 temp[4*i+3] = z0-z3; | |
1234 | 152 } |
153 | |
8196 | 154 for (i = 0; i < 4; i++){ |
155 const int offset = x_offset[i]; | |
156 const int z0 = 13*(temp[4*0+i] + temp[4*2+i]); | |
157 const int z1 = 13*(temp[4*0+i] - temp[4*2+i]); | |
158 const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; | |
159 const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; | |
1234 | 160 |
8196 | 161 block[stride*0 +offset] = ((z0 + z3)*qmul + 0x80000) >> 20; |
162 block[stride*2 +offset] = ((z1 + z2)*qmul + 0x80000) >> 20; | |
163 block[stride*8 +offset] = ((z1 - z2)*qmul + 0x80000) >> 20; | |
164 block[stride*10+offset] = ((z0 - z3)*qmul + 0x80000) >> 20; | |
1234 | 165 } |
166 } | |
167 #undef stride | |
168 | |
10852 | 169 void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, |
8196 | 170 int dc) |
8195 | 171 { |
8196 | 172 const int qmul = svq3_dequant_coeff[qp]; |
1234 | 173 int i; |
4176 | 174 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
1234 | 175 |
176 if (dc) { | |
177 dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2)); | |
178 block[0] = 0; | |
179 } | |
180 | |
8196 | 181 for (i = 0; i < 4; i++) { |
182 const int z0 = 13*(block[0 + 4*i] + block[2 + 4*i]); | |
183 const int z1 = 13*(block[0 + 4*i] - block[2 + 4*i]); | |
184 const int z2 = 7* block[1 + 4*i] - 17*block[3 + 4*i]; | |
185 const int z3 = 17* block[1 + 4*i] + 7*block[3 + 4*i]; | |
1234 | 186 |
8196 | 187 block[0 + 4*i] = z0 + z3; |
188 block[1 + 4*i] = z1 + z2; | |
189 block[2 + 4*i] = z1 - z2; | |
190 block[3 + 4*i] = z0 - z3; | |
1234 | 191 } |
192 | |
8196 | 193 for (i = 0; i < 4; i++) { |
194 const int z0 = 13*(block[i + 4*0] + block[i + 4*2]); | |
195 const int z1 = 13*(block[i + 4*0] - block[i + 4*2]); | |
196 const int z2 = 7* block[i + 4*1] - 17*block[i + 4*3]; | |
197 const int z3 = 17* block[i + 4*1] + 7*block[i + 4*3]; | |
198 const int rr = (dc + 0x80000); | |
1234 | 199 |
8196 | 200 dst[i + stride*0] = cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ]; |
201 dst[i + stride*1] = cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ]; | |
202 dst[i + stride*2] = cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ]; | |
203 dst[i + stride*3] = cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ]; | |
1234 | 204 } |
205 } | |
206 | |
8195 | 207 static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, |
208 int index, const int type) | |
209 { | |
8196 | 210 static const uint8_t *const scan_patterns[4] = |
211 { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan }; | |
1234 | 212 |
8196 | 213 int run, level, sign, vlc, limit; |
214 const int intra = (3 * type) >> 2; | |
215 const uint8_t *const scan = scan_patterns[type]; | |
1234 | 216 |
8196 | 217 for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { |
218 for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { | |
1234 | 219 |
8196 | 220 if (vlc == INVALID_VLC) |
221 return -1; | |
1234 | 222 |
8196 | 223 sign = (vlc & 0x1) - 1; |
224 vlc = (vlc + 1) >> 1; | |
1234 | 225 |
8196 | 226 if (type == 3) { |
227 if (vlc < 3) { | |
228 run = 0; | |
229 level = vlc; | |
230 } else if (vlc < 4) { | |
231 run = 1; | |
232 level = 1; | |
233 } else { | |
234 run = (vlc & 0x3); | |
235 level = ((vlc + 9) >> 2) - run; | |
236 } | |
237 } else { | |
238 if (vlc < 16) { | |
239 run = svq3_dct_tables[intra][vlc].run; | |
240 level = svq3_dct_tables[intra][vlc].level; | |
241 } else if (intra) { | |
242 run = (vlc & 0x7); | |
243 level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); | |
244 } else { | |
245 run = (vlc & 0xF); | |
246 level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); | |
247 } | |
248 } | |
249 | |
250 if ((index += run) >= limit) | |
251 return -1; | |
252 | |
253 block[scan[index]] = (level ^ sign) - sign; | |
2979 | 254 } |
8196 | 255 |
256 if (type != 2) { | |
257 break; | |
2979 | 258 } |
1234 | 259 } |
260 | |
8196 | 261 return 0; |
1234 | 262 } |
263 | |
8195 | 264 static inline void svq3_mc_dir_part(MpegEncContext *s, |
265 int x, int y, int width, int height, | |
266 int mx, int my, int dxy, | |
267 int thirdpel, int dir, int avg) | |
268 { | |
8196 | 269 const Picture *pic = (dir == 0) ? &s->last_picture : &s->next_picture; |
270 uint8_t *src, *dest; | |
271 int i, emu = 0; | |
272 int blocksize = 2 - (width>>3); //16->0, 8->1, 4->2 | |
273 | |
274 mx += x; | |
275 my += y; | |
1234 | 276 |
8196 | 277 if (mx < 0 || mx >= (s->h_edge_pos - width - 1) || |
278 my < 0 || my >= (s->v_edge_pos - height - 1)) { | |
2967 | 279 |
8196 | 280 if ((s->flags & CODEC_FLAG_EMU_EDGE)) { |
281 emu = 1; | |
282 } | |
1234 | 283 |
8196 | 284 mx = av_clip (mx, -16, (s->h_edge_pos - width + 15)); |
285 my = av_clip (my, -16, (s->v_edge_pos - height + 15)); | |
1234 | 286 } |
287 | |
8196 | 288 /* form component predictions */ |
289 dest = s->current_picture.data[0] + x + y*s->linesize; | |
290 src = pic->data[0] + mx + my*s->linesize; | |
1234 | 291 |
8196 | 292 if (emu) { |
293 ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, (width + 1), (height + 1), | |
294 mx, my, s->h_edge_pos, s->v_edge_pos); | |
295 src = s->edge_emu_buffer; | |
296 } | |
297 if (thirdpel) | |
298 (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->linesize, width, height); | |
299 else | |
300 (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->linesize, height); | |
1234 | 301 |
8196 | 302 if (!(s->flags & CODEC_FLAG_GRAY)) { |
303 mx = (mx + (mx < (int) x)) >> 1; | |
304 my = (my + (my < (int) y)) >> 1; | |
305 width = (width >> 1); | |
306 height = (height >> 1); | |
307 blocksize++; | |
1234 | 308 |
8196 | 309 for (i = 1; i < 3; i++) { |
310 dest = s->current_picture.data[i] + (x >> 1) + (y >> 1)*s->uvlinesize; | |
311 src = pic->data[i] + mx + my*s->uvlinesize; | |
1234 | 312 |
8196 | 313 if (emu) { |
314 ff_emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize, (width + 1), (height + 1), | |
315 mx, my, (s->h_edge_pos >> 1), (s->v_edge_pos >> 1)); | |
316 src = s->edge_emu_buffer; | |
317 } | |
318 if (thirdpel) | |
319 (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->uvlinesize, width, height); | |
320 else | |
321 (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->uvlinesize, height); | |
322 } | |
1234 | 323 } |
324 } | |
325 | |
8195 | 326 static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir, |
327 int avg) | |
328 { | |
8196 | 329 int i, j, k, mx, my, dx, dy, x, y; |
330 MpegEncContext *const s = (MpegEncContext *) h; | |
331 const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1); | |
332 const int part_height = 16 >> ((unsigned) (size + 1) / 3); | |
333 const int extra_width = (mode == PREDICT_MODE) ? -16*6 : 0; | |
334 const int h_edge_pos = 6*(s->h_edge_pos - part_width ) - extra_width; | |
335 const int v_edge_pos = 6*(s->v_edge_pos - part_height) - extra_width; | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
336 |
8196 | 337 for (i = 0; i < 16; i += part_height) { |
338 for (j = 0; j < 16; j += part_width) { | |
339 const int b_xy = (4*s->mb_x + (j >> 2)) + (4*s->mb_y + (i >> 2))*h->b_stride; | |
340 int dxy; | |
341 x = 16*s->mb_x + j; | |
342 y = 16*s->mb_y + i; | |
343 k = ((j >> 2) & 1) + ((i >> 1) & 2) + ((j >> 1) & 4) + (i & 8); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
344 |
8196 | 345 if (mode != PREDICT_MODE) { |
346 pred_motion(h, k, (part_width >> 2), dir, 1, &mx, &my); | |
347 } else { | |
348 mx = s->next_picture.motion_val[0][b_xy][0]<<1; | |
349 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
|
350 |
8196 | 351 if (dir == 0) { |
352 mx = ((mx * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1; | |
353 my = ((my * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1; | |
354 } else { | |
355 mx = ((mx * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1) >> 1; | |
356 my = ((my * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1) >> 1; | |
357 } | |
358 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
359 |
8196 | 360 /* clip motion vector prediction to frame border */ |
361 mx = av_clip(mx, extra_width - 6*x, h_edge_pos - 6*x); | |
362 my = av_clip(my, extra_width - 6*y, v_edge_pos - 6*y); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
363 |
8196 | 364 /* get (optional) motion vector differential */ |
365 if (mode == PREDICT_MODE) { | |
366 dx = dy = 0; | |
367 } else { | |
368 dy = svq3_get_se_golomb(&s->gb); | |
369 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
|
370 |
8196 | 371 if (dx == INVALID_VLC || dy == INVALID_VLC) { |
372 av_log(h->s.avctx, AV_LOG_ERROR, "invalid MV vlc\n"); | |
373 return -1; | |
374 } | |
375 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
376 |
8196 | 377 /* compute motion vector */ |
378 if (mode == THIRDPEL_MODE) { | |
379 int fx, fy; | |
380 mx = ((mx + 1)>>1) + dx; | |
381 my = ((my + 1)>>1) + dy; | |
382 fx = ((unsigned)(mx + 0x3000))/3 - 0x1000; | |
383 fy = ((unsigned)(my + 0x3000))/3 - 0x1000; | |
384 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
|
385 |
8196 | 386 svq3_mc_dir_part(s, x, y, part_width, part_height, fx, fy, dxy, 1, dir, avg); |
387 mx += mx; | |
388 my += my; | |
389 } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) { | |
390 mx = ((unsigned)(mx + 1 + 0x3000))/3 + dx - 0x1000; | |
391 my = ((unsigned)(my + 1 + 0x3000))/3 + dy - 0x1000; | |
392 dxy = (mx&1) + 2*(my&1); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
393 |
8196 | 394 svq3_mc_dir_part(s, x, y, part_width, part_height, mx>>1, my>>1, dxy, 0, dir, avg); |
395 mx *= 3; | |
396 my *= 3; | |
397 } else { | |
398 mx = ((unsigned)(mx + 3 + 0x6000))/6 + dx - 0x1000; | |
399 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
|
400 |
8196 | 401 svq3_mc_dir_part(s, x, y, part_width, part_height, mx, my, 0, 0, dir, avg); |
402 mx *= 6; | |
403 my *= 6; | |
404 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
405 |
8196 | 406 /* update mv_cache */ |
407 if (mode != PREDICT_MODE) { | |
408 int32_t mv = pack16to32(mx,my); | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
409 |
8196 | 410 if (part_height == 8 && i < 8) { |
411 *(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
|
412 |
8196 | 413 if (part_width == 8 && j < 8) { |
414 *(int32_t *) h->mv_cache[dir][scan8[k] + 1 + 1*8] = mv; | |
415 } | |
416 } | |
417 if (part_width == 8 && j < 8) { | |
418 *(int32_t *) h->mv_cache[dir][scan8[k] + 1] = mv; | |
419 } | |
420 if (part_width == 4 || part_height == 4) { | |
421 *(int32_t *) h->mv_cache[dir][scan8[k]] = mv; | |
422 } | |
423 } | |
424 | |
425 /* write back motion vectors */ | |
426 fill_rectangle(s->current_picture.motion_val[dir][b_xy], part_width>>2, part_height>>2, h->b_stride, pack16to32(mx,my), 4); | |
2979 | 427 } |
8196 | 428 } |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
429 |
8196 | 430 return 0; |
1330
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 |
8195 | 433 static int svq3_decode_mb(H264Context *h, unsigned int mb_type) |
434 { | |
8196 | 435 int i, j, k, m, dir, mode; |
436 int cbp = 0; | |
437 uint32_t vlc; | |
438 int8_t *top, *left; | |
439 MpegEncContext *const s = (MpegEncContext *) h; | |
440 const int mb_xy = h->mb_xy; | |
441 const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; | |
442 | |
443 h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; | |
444 h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; | |
445 h->topright_samples_available = 0xFFFF; | |
446 | |
447 if (mb_type == 0) { /* SKIP */ | |
448 if (s->pict_type == FF_P_TYPE || s->next_picture.mb_type[mb_xy] == -1) { | |
449 svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 0, 0); | |
1234 | 450 |
8196 | 451 if (s->pict_type == FF_B_TYPE) { |
452 svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 1, 1); | |
453 } | |
1234 | 454 |
8196 | 455 mb_type = MB_TYPE_SKIP; |
456 } else { | |
457 mb_type = FFMIN(s->next_picture.mb_type[mb_xy], 6); | |
458 if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0) | |
459 return -1; | |
460 if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0) | |
461 return -1; | |
1319 | 462 |
8196 | 463 mb_type = MB_TYPE_16x16; |
464 } | |
465 } else if (mb_type < 8) { /* INTER */ | |
466 if (h->thirdpel_flag && h->halfpel_flag == !get_bits1 (&s->gb)) { | |
467 mode = THIRDPEL_MODE; | |
468 } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits1 (&s->gb)) { | |
469 mode = HALFPEL_MODE; | |
470 } else { | |
471 mode = FULLPEL_MODE; | |
472 } | |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
473 |
8196 | 474 /* fill caches */ |
475 /* note ref_cache should contain here: | |
476 ???????? | |
477 ???11111 | |
478 N??11111 | |
479 N??11111 | |
480 N??11111 | |
481 */ | |
1319 | 482 |
8196 | 483 for (m = 0; m < 2; m++) { |
484 if (s->mb_x > 0 && h->intra4x4_pred_mode[mb_xy - 1][0] != -1) { | |
485 for (i = 0; i < 4; i++) { | |
486 *(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]; | |
487 } | |
488 } else { | |
489 for (i = 0; i < 4; i++) { | |
490 *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = 0; | |
491 } | |
492 } | |
493 if (s->mb_y > 0) { | |
494 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)); | |
495 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 | 496 |
8196 | 497 if (s->mb_x < (s->mb_width - 1)) { |
498 *(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]; | |
499 h->ref_cache[m][scan8[0] + 4 - 1*8] = | |
500 (h->intra4x4_pred_mode[mb_xy - s->mb_stride + 1][0] == -1 || | |
501 h->intra4x4_pred_mode[mb_xy - s->mb_stride ][4] == -1) ? PART_NOT_AVAILABLE : 1; | |
502 }else | |
503 h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; | |
504 if (s->mb_x > 0) { | |
505 *(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]; | |
506 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; | |
507 }else | |
508 h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; | |
509 }else | |
510 memset(&h->ref_cache[m][scan8[0] - 1*8 - 1], PART_NOT_AVAILABLE, 8); | |
511 | |
512 if (s->pict_type != FF_B_TYPE) | |
513 break; | |
514 } | |
2967 | 515 |
8196 | 516 /* decode motion vector(s) and form prediction(s) */ |
517 if (s->pict_type == FF_P_TYPE) { | |
518 if (svq3_mc_dir(h, (mb_type - 1), mode, 0, 0) < 0) | |
519 return -1; | |
520 } else { /* FF_B_TYPE */ | |
521 if (mb_type != 2) { | |
522 if (svq3_mc_dir(h, 0, mode, 0, 0) < 0) | |
523 return -1; | |
524 } else { | |
525 for (i = 0; i < 4; i++) { | |
526 memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
527 } | |
528 } | |
529 if (mb_type != 1) { | |
530 if (svq3_mc_dir(h, 0, mode, 1, (mb_type == 3)) < 0) | |
531 return -1; | |
532 } else { | |
533 for (i = 0; i < 4; i++) { | |
534 memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
535 } | |
536 } | |
2979 | 537 } |
8196 | 538 |
539 mb_type = MB_TYPE_16x16; | |
540 } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */ | |
541 memset(h->intra4x4_pred_mode_cache, -1, 8*5*sizeof(int8_t)); | |
542 | |
543 if (mb_type == 8) { | |
544 if (s->mb_x > 0) { | |
545 for (i = 0; i < 4; i++) { | |
546 h->intra4x4_pred_mode_cache[scan8[0] - 1 + i*8] = h->intra4x4_pred_mode[mb_xy - 1][i]; | |
547 } | |
548 if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) { | |
549 h->left_samples_available = 0x5F5F; | |
550 } | |
551 } | |
552 if (s->mb_y > 0) { | |
553 h->intra4x4_pred_mode_cache[4+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][4]; | |
554 h->intra4x4_pred_mode_cache[5+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][5]; | |
555 h->intra4x4_pred_mode_cache[6+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][6]; | |
556 h->intra4x4_pred_mode_cache[7+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][3]; | |
557 | |
558 if (h->intra4x4_pred_mode_cache[4+8*0] == -1) { | |
559 h->top_samples_available = 0x33FF; | |
560 } | |
561 } | |
562 | |
563 /* decode prediction codes for luma blocks */ | |
564 for (i = 0; i < 16; i+=2) { | |
565 vlc = svq3_get_ue_golomb(&s->gb); | |
1234 | 566 |
8196 | 567 if (vlc >= 25){ |
568 av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc); | |
569 return -1; | |
570 } | |
571 | |
572 left = &h->intra4x4_pred_mode_cache[scan8[i] - 1]; | |
573 top = &h->intra4x4_pred_mode_cache[scan8[i] - 8]; | |
574 | |
575 left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]]; | |
576 left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]]; | |
1319 | 577 |
8196 | 578 if (left[1] == -1 || left[2] == -1){ |
579 av_log(h->s.avctx, AV_LOG_ERROR, "weird prediction\n"); | |
580 return -1; | |
581 } | |
582 } | |
583 } else { /* mb_type == 33, DC_128_PRED block type */ | |
584 for (i = 0; i < 4; i++) { | |
585 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_PRED, 4); | |
586 } | |
587 } | |
588 | |
10852 | 589 ff_h264_write_back_intra_pred_mode(h); |
1234 | 590 |
8196 | 591 if (mb_type == 8) { |
592 check_intra4x4_pred_mode(h); | |
593 | |
594 h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; | |
595 h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; | |
596 } else { | |
597 for (i = 0; i < 4; i++) { | |
598 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_128_PRED, 4); | |
599 } | |
600 | |
601 h->top_samples_available = 0x33FF; | |
602 h->left_samples_available = 0x5F5F; | |
2979 | 603 } |
8196 | 604 |
605 mb_type = MB_TYPE_INTRA4x4; | |
606 } else { /* INTRA16x16 */ | |
607 dir = i_mb_type_info[mb_type - 8].pred_mode; | |
608 dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; | |
609 | |
10852 | 610 if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir)) == -1){ |
8196 | 611 av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); |
612 return -1; | |
2979 | 613 } |
8196 | 614 |
615 cbp = i_mb_type_info[mb_type - 8].cbp; | |
616 mb_type = MB_TYPE_INTRA16x16; | |
1234 | 617 } |
618 | |
8196 | 619 if (!IS_INTER(mb_type) && s->pict_type != FF_I_TYPE) { |
620 for (i = 0; i < 4; i++) { | |
621 memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
2979 | 622 } |
8196 | 623 if (s->pict_type == FF_B_TYPE) { |
624 for (i = 0; i < 4; i++) { | |
625 memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); | |
626 } | |
2979 | 627 } |
8196 | 628 } |
629 if (!IS_INTRA4x4(mb_type)) { | |
630 memset(h->intra4x4_pred_mode[mb_xy], DC_PRED, 8); | |
631 } | |
632 if (!IS_SKIP(mb_type) || s->pict_type == FF_B_TYPE) { | |
633 memset(h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t)); | |
634 s->dsp.clear_blocks(h->mb); | |
635 } | |
1319 | 636 |
8196 | 637 if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == FF_B_TYPE)) { |
638 if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48){ | |
639 av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); | |
640 return -1; | |
2452 | 641 } |
1319 | 642 |
8196 | 643 cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc] : golomb_to_inter_cbp[vlc]; |
1234 | 644 } |
8196 | 645 if (IS_INTRA16x16(mb_type) || (s->pict_type != FF_I_TYPE && s->adaptive_quant && cbp)) { |
646 s->qscale += svq3_get_se_golomb(&s->gb); | |
1319 | 647 |
8196 | 648 if (s->qscale > 31){ |
649 av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); | |
650 return -1; | |
651 } | |
1319 | 652 } |
8196 | 653 if (IS_INTRA16x16(mb_type)) { |
654 if (svq3_decode_block(&s->gb, h->mb, 0, 0)){ | |
655 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); | |
656 return -1; | |
657 } | |
2452 | 658 } |
1234 | 659 |
8196 | 660 if (cbp) { |
661 const int index = IS_INTRA16x16(mb_type) ? 1 : 0; | |
662 const int type = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1); | |
663 | |
664 for (i = 0; i < 4; i++) { | |
665 if ((cbp & (1 << i))) { | |
666 for (j = 0; j < 4; j++) { | |
667 k = index ? ((j&1) + 2*(i&1) + 2*(j&2) + 4*(i&2)) : (4*i + j); | |
668 h->non_zero_count_cache[ scan8[k] ] = 1; | |
669 | |
670 if (svq3_decode_block(&s->gb, &h->mb[16*k], index, type)){ | |
671 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding block\n"); | |
672 return -1; | |
673 } | |
674 } | |
675 } | |
676 } | |
1234 | 677 |
8196 | 678 if ((cbp & 0x30)) { |
679 for (i = 0; i < 2; ++i) { | |
680 if (svq3_decode_block(&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)){ | |
681 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); | |
682 return -1; | |
683 } | |
684 } | |
1234 | 685 |
8196 | 686 if ((cbp & 0x20)) { |
687 for (i = 0; i < 8; i++) { | |
688 h->non_zero_count_cache[ scan8[16+i] ] = 1; | |
689 | |
690 if (svq3_decode_block(&s->gb, &h->mb[16*(16 + i)], 1, 1)){ | |
691 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); | |
692 return -1; | |
693 } | |
694 } | |
695 } | |
696 } | |
2452 | 697 } |
1330
c05c381a9c47
- fix PLANE_PRED8x8 prediction (H/V are swapped, this is correct!)
tmmm
parents:
1321
diff
changeset
|
698 |
8381
10aed1a9444b
10l, svq3 didnt set h->cbp, this broke decoding a little.
michael
parents:
8364
diff
changeset
|
699 h->cbp= cbp; |
8196 | 700 s->current_picture.mb_type[mb_xy] = mb_type; |
1234 | 701 |
8196 | 702 if (IS_INTRA(mb_type)) { |
10852 | 703 h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); |
1234 | 704 } |
705 | |
8196 | 706 return 0; |
1234 | 707 } |
708 | |
8195 | 709 static int svq3_decode_slice_header(H264Context *h) |
710 { | |
8196 | 711 MpegEncContext *const s = (MpegEncContext *) h; |
712 const int mb_xy = h->mb_xy; | |
713 int i, header; | |
714 | |
715 header = get_bits(&s->gb, 8); | |
1319 | 716 |
8196 | 717 if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { |
718 /* TODO: what? */ | |
719 av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); | |
720 return -1; | |
721 } else { | |
722 int length = (header >> 5) & 3; | |
723 | |
724 h->next_slice_index = get_bits_count(&s->gb) + 8*show_bits(&s->gb, 8*length) + 8*length; | |
1319 | 725 |
8196 | 726 if (h->next_slice_index > s->gb.size_in_bits) { |
727 av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n"); | |
728 return -1; | |
729 } | |
730 | |
731 s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); | |
732 skip_bits(&s->gb, 8); | |
1319 | 733 |
8196 | 734 if (h->svq3_watermark_key) { |
735 uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1]); | |
736 AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1], header ^ h->svq3_watermark_key); | |
737 } | |
738 if (length > 0) { | |
739 memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3], | |
740 &s->gb.buffer[s->gb.size_in_bits >> 3], (length - 1)); | |
741 } | |
9080 | 742 skip_bits_long(&s->gb, 0); |
8196 | 743 } |
1319 | 744 |
8196 | 745 if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){ |
746 av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); | |
747 return -1; | |
1754
bdf3927bf8c5
closed gop support & flags2 as all bits in flags are used
michael
parents:
1699
diff
changeset
|
748 } |
1319 | 749 |
8196 | 750 h->slice_type = golomb_to_pict_type[i]; |
1319 | 751 |
8196 | 752 if ((header & 0x9F) == 2) { |
753 i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); | |
754 s->mb_skip_run = get_bits(&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); | |
755 } else { | |
756 skip_bits1(&s->gb); | |
757 s->mb_skip_run = 0; | |
8066
94fa05bc0390
svq3 watermark decoding support, based on reverse engineering work by chrono
bcoudurier
parents:
8059
diff
changeset
|
758 } |
1319 | 759 |
8196 | 760 h->slice_num = get_bits(&s->gb, 8); |
761 s->qscale = get_bits(&s->gb, 5); | |
762 s->adaptive_quant = get_bits1(&s->gb); | |
1319 | 763 |
8196 | 764 /* unknown fields */ |
765 skip_bits1(&s->gb); | |
766 | |
767 if (h->unknown_svq3_flag) { | |
768 skip_bits1(&s->gb); | |
769 } | |
1319 | 770 |
8196 | 771 skip_bits1(&s->gb); |
772 skip_bits(&s->gb, 2); | |
1319 | 773 |
8196 | 774 while (get_bits1(&s->gb)) { |
775 skip_bits(&s->gb, 8); | |
776 } | |
1319 | 777 |
8196 | 778 /* reset intra predictors and invalidate motion vector references */ |
779 if (s->mb_x > 0) { | |
780 memset(h->intra4x4_pred_mode[mb_xy - 1], -1, 4*sizeof(int8_t)); | |
781 memset(h->intra4x4_pred_mode[mb_xy - s->mb_x], -1, 8*sizeof(int8_t)*s->mb_x); | |
782 } | |
783 if (s->mb_y > 0) { | |
784 memset(h->intra4x4_pred_mode[mb_xy - s->mb_stride], -1, 8*sizeof(int8_t)*(s->mb_width - s->mb_x)); | |
1319 | 785 |
8196 | 786 if (s->mb_x > 0) { |
787 h->intra4x4_pred_mode[mb_xy - s->mb_stride - 1][3] = -1; | |
788 } | |
789 } | |
1319 | 790 |
8196 | 791 return 0; |
1319 | 792 } |
793 | |
9007
043574c5c153
Add missing av_cold in static init/close functions.
stefano
parents:
8718
diff
changeset
|
794 static av_cold int svq3_decode_init(AVCodecContext *avctx) |
8195 | 795 { |
8196 | 796 MpegEncContext *const s = avctx->priv_data; |
797 H264Context *const h = avctx->priv_data; | |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
798 int m; |
8196 | 799 unsigned char *extradata; |
800 unsigned int size; | |
801 | |
10151
6cd8b6fd5f0f
Check thread count as multithreaded decoding is not supported.
michael
parents:
10146
diff
changeset
|
802 if(avctx->thread_count > 1){ |
6cd8b6fd5f0f
Check thread count as multithreaded decoding is not supported.
michael
parents:
10146
diff
changeset
|
803 av_log(avctx, AV_LOG_ERROR, "SVQ3 does not support multithreaded decoding, patch welcome! (check latest SVN too)\n"); |
6cd8b6fd5f0f
Check thread count as multithreaded decoding is not supported.
michael
parents:
10146
diff
changeset
|
804 return -1; |
6cd8b6fd5f0f
Check thread count as multithreaded decoding is not supported.
michael
parents:
10146
diff
changeset
|
805 } |
6cd8b6fd5f0f
Check thread count as multithreaded decoding is not supported.
michael
parents:
10146
diff
changeset
|
806 |
10852 | 807 if (ff_h264_decode_init(avctx) < 0) |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
808 return -1; |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
809 |
8196 | 810 s->flags = avctx->flags; |
811 s->flags2 = avctx->flags2; | |
812 s->unrestricted_mv = 1; | |
8364
4a01f7144da5
Fix svq3 decoding, is_complex was not initialized.
michael
parents:
8209
diff
changeset
|
813 h->is_complex=1; |
10677
abf5c20eebf4
SVQ3 : Set avctx->pix_fmt correctly during decoder initialisation.
jai_menon
parents:
10442
diff
changeset
|
814 avctx->pix_fmt = avctx->codec->pix_fmts[0]; |
8196 | 815 |
816 if (!s->context_initialized) { | |
817 s->width = avctx->width; | |
818 s->height = avctx->height; | |
819 h->halfpel_flag = 1; | |
820 h->thirdpel_flag = 1; | |
821 h->unknown_svq3_flag = 0; | |
822 h->chroma_qp[0] = h->chroma_qp[1] = 4; | |
823 | |
824 if (MPV_common_init(s) < 0) | |
825 return -1; | |
826 | |
827 h->b_stride = 4*s->mb_width; | |
828 | |
10852 | 829 ff_h264_alloc_tables(h); |
1319 | 830 |
8196 | 831 /* prowl for the "SEQH" marker in the extradata */ |
832 extradata = (unsigned char *)avctx->extradata; | |
833 for (m = 0; m < avctx->extradata_size; m++) { | |
834 if (!memcmp(extradata, "SEQH", 4)) | |
835 break; | |
836 extradata++; | |
837 } | |
838 | |
839 /* if a match was found, parse the extra data */ | |
840 if (extradata && !memcmp(extradata, "SEQH", 4)) { | |
841 | |
842 GetBitContext gb; | |
10020
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
843 int frame_size_code; |
8196 | 844 |
845 size = AV_RB32(&extradata[4]); | |
846 init_get_bits(&gb, extradata + 8, size*8); | |
847 | |
848 /* 'frame size code' and optional 'width, height' */ | |
10020
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
849 frame_size_code = get_bits(&gb, 3); |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
850 switch (frame_size_code) { |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
851 case 0: avctx->width = 160; avctx->height = 120; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
852 case 1: avctx->width = 128; avctx->height = 96; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
853 case 2: avctx->width = 176; avctx->height = 144; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
854 case 3: avctx->width = 352; avctx->height = 288; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
855 case 4: avctx->width = 704; avctx->height = 576; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
856 case 5: avctx->width = 240; avctx->height = 180; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
857 case 6: avctx->width = 320; avctx->height = 240; break; |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
858 case 7: |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
859 avctx->width = get_bits(&gb, 12); |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
860 avctx->height = get_bits(&gb, 12); |
617166c76faf
Parse frame size code, see "svq3.c: parse frame size" thread on ML.
rbultje
parents:
9733
diff
changeset
|
861 break; |
8196 | 862 } |
863 | |
864 h->halfpel_flag = get_bits1(&gb); | |
865 h->thirdpel_flag = get_bits1(&gb); | |
1699 | 866 |
8196 | 867 /* unknown fields */ |
868 skip_bits1(&gb); | |
869 skip_bits1(&gb); | |
870 skip_bits1(&gb); | |
871 skip_bits1(&gb); | |
872 | |
873 s->low_delay = get_bits1(&gb); | |
874 | |
875 /* unknown field */ | |
876 skip_bits1(&gb); | |
1234 | 877 |
8196 | 878 while (get_bits1(&gb)) { |
879 skip_bits(&gb, 8); | |
880 } | |
881 | |
882 h->unknown_svq3_flag = get_bits1(&gb); | |
883 avctx->has_b_frames = !s->low_delay; | |
884 if (h->unknown_svq3_flag) { | |
8590 | 885 #if CONFIG_ZLIB |
8196 | 886 unsigned watermark_width = svq3_get_ue_golomb(&gb); |
887 unsigned watermark_height = svq3_get_ue_golomb(&gb); | |
888 int u1 = svq3_get_ue_golomb(&gb); | |
889 int u2 = get_bits(&gb, 8); | |
890 int u3 = get_bits(&gb, 2); | |
891 int u4 = svq3_get_ue_golomb(&gb); | |
892 unsigned buf_len = watermark_width*watermark_height*4; | |
893 int offset = (get_bits_count(&gb)+7)>>3; | |
894 uint8_t *buf; | |
1234 | 895 |
8196 | 896 if ((uint64_t)watermark_width*4 > UINT_MAX/watermark_height) |
897 return -1; | |
1319 | 898 |
8196 | 899 buf = av_malloc(buf_len); |
900 av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n", watermark_width, watermark_height); | |
901 av_log(avctx, AV_LOG_DEBUG, "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n", u1, u2, u3, u4, offset); | |
902 if (uncompress(buf, (uLong*)&buf_len, extradata + 8 + offset, size - offset) != Z_OK) { | |
903 av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n"); | |
904 av_free(buf); | |
905 return -1; | |
906 } | |
907 h->svq3_watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); | |
908 h->svq3_watermark_key = h->svq3_watermark_key << 16 | h->svq3_watermark_key; | |
909 av_log(avctx, AV_LOG_DEBUG, "watermark key %#x\n", h->svq3_watermark_key); | |
910 av_free(buf); | |
911 #else | |
912 av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n"); | |
913 return -1; | |
914 #endif | |
915 } | |
916 } | |
917 } | |
918 | |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
919 return 0; |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
920 } |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
921 |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
922 static int svq3_decode_frame(AVCodecContext *avctx, |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
923 void *data, int *data_size, |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9080
diff
changeset
|
924 AVPacket *avpkt) |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
925 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9080
diff
changeset
|
926 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9080
diff
changeset
|
927 int buf_size = avpkt->size; |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
928 MpegEncContext *const s = avctx->priv_data; |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
929 H264Context *const h = avctx->priv_data; |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
930 int m, mb_type; |
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
931 |
8196 | 932 /* special case for last picture */ |
933 if (buf_size == 0) { | |
934 if (s->next_picture_ptr && !s->low_delay) { | |
935 *(AVFrame *) data = *(AVFrame *) &s->next_picture; | |
936 s->next_picture_ptr = NULL; | |
937 *data_size = sizeof(AVFrame); | |
938 } | |
939 return 0; | |
1877
869256817a91
smarten up the SVQ3 extradata decoder without changing the external API
melanson
parents:
1754
diff
changeset
|
940 } |
1878
838c18d1e7fc
be smarter about the variable size of the extra SVQ3 data
melanson
parents:
1877
diff
changeset
|
941 |
8196 | 942 init_get_bits (&s->gb, buf, 8*buf_size); |
1234 | 943 |
8196 | 944 s->mb_x = s->mb_y = h->mb_xy = 0; |
1319 | 945 |
8196 | 946 if (svq3_decode_slice_header(h)) |
947 return -1; | |
1319 | 948 |
8196 | 949 s->pict_type = h->slice_type; |
950 s->picture_number = h->slice_num; | |
8066
94fa05bc0390
svq3 watermark decoding support, based on reverse engineering work by chrono
bcoudurier
parents:
8059
diff
changeset
|
951 |
8196 | 952 if (avctx->debug&FF_DEBUG_PICT_INFO){ |
953 av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n", | |
954 av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, | |
955 s->adaptive_quant, s->qscale, h->slice_num); | |
1234 | 956 } |
957 | |
8196 | 958 /* for hurry_up == 5 */ |
959 s->current_picture.pict_type = s->pict_type; | |
960 s->current_picture.key_frame = (s->pict_type == FF_I_TYPE); | |
1234 | 961 |
8196 | 962 /* Skip B-frames if we do not have reference frames. */ |
963 if (s->last_picture_ptr == NULL && s->pict_type == FF_B_TYPE) | |
964 return 0; | |
965 /* Skip B-frames if we are in a hurry. */ | |
966 if (avctx->hurry_up && s->pict_type == FF_B_TYPE) | |
967 return 0; | |
968 /* Skip everything if we are in a hurry >= 5. */ | |
969 if (avctx->hurry_up >= 5) | |
970 return 0; | |
971 if ( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == FF_B_TYPE) | |
972 ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != FF_I_TYPE) | |
973 || avctx->skip_frame >= AVDISCARD_ALL) | |
974 return 0; | |
1319 | 975 |
8196 | 976 if (s->next_p_frame_damaged) { |
977 if (s->pict_type == FF_B_TYPE) | |
978 return 0; | |
979 else | |
980 s->next_p_frame_damaged = 0; | |
1319 | 981 } |
982 | |
10852 | 983 if (ff_h264_frame_start(h) < 0) |
8196 | 984 return -1; |
2967 | 985 |
8196 | 986 if (s->pict_type == FF_B_TYPE) { |
987 h->frame_num_offset = (h->slice_num - h->prev_frame_num); | |
1319 | 988 |
8196 | 989 if (h->frame_num_offset < 0) { |
990 h->frame_num_offset += 256; | |
991 } | |
992 if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) { | |
993 av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n"); | |
994 return -1; | |
995 } | |
996 } else { | |
997 h->prev_frame_num = h->frame_num; | |
998 h->frame_num = h->slice_num; | |
999 h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num); | |
1234 | 1000 |
8196 | 1001 if (h->prev_frame_num_offset < 0) { |
1002 h->prev_frame_num_offset += 256; | |
1003 } | |
1234 | 1004 } |
1268 | 1005 |
8196 | 1006 for (m = 0; m < 2; m++){ |
1007 int i; | |
1008 for (i = 0; i < 4; i++){ | |
1009 int j; | |
1010 for (j = -1; j < 4; j++) | |
1011 h->ref_cache[m][scan8[0] + 8*i + j]= 1; | |
1012 if (i < 3) | |
1013 h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; | |
1014 } | |
1015 } | |
1234 | 1016 |
8196 | 1017 for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { |
1018 for (s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { | |
1019 h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; | |
1020 | |
1021 if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits && | |
1022 ((get_bits_count(&s->gb) & 7) == 0 || show_bits(&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) { | |
1023 | |
1024 skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb)); | |
1025 s->gb.size_in_bits = 8*buf_size; | |
1026 | |
1027 if (svq3_decode_slice_header(h)) | |
1028 return -1; | |
1029 | |
1030 /* TODO: support s->mb_skip_run */ | |
1031 } | |
1032 | |
1033 mb_type = svq3_get_ue_golomb(&s->gb); | |
1319 | 1034 |
8196 | 1035 if (s->pict_type == FF_I_TYPE) { |
1036 mb_type += 8; | |
1037 } else if (s->pict_type == FF_B_TYPE && mb_type >= 4) { | |
1038 mb_type += 4; | |
1039 } | |
1040 if (mb_type > 33 || svq3_decode_mb(h, mb_type)) { | |
1041 av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); | |
1042 return -1; | |
1043 } | |
1044 | |
1045 if (mb_type != 0) { | |
10852 | 1046 ff_h264_hl_decode_mb (h); |
8196 | 1047 } |
1048 | |
1049 if (s->pict_type != FF_B_TYPE && !s->low_delay) { | |
1050 s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = | |
1051 (s->pict_type == FF_P_TYPE && mb_type < 8) ? (mb_type - 1) : -1; | |
1052 } | |
1053 } | |
1234 | 1054 |
8196 | 1055 ff_draw_horiz_band(s, 16*s->mb_y, 16); |
1056 } | |
1057 | |
1058 MPV_frame_end(s); | |
1319 | 1059 |
8196 | 1060 if (s->pict_type == FF_B_TYPE || s->low_delay) { |
1061 *(AVFrame *) data = *(AVFrame *) &s->current_picture; | |
1062 } else { | |
1063 *(AVFrame *) data = *(AVFrame *) &s->last_picture; | |
1064 } | |
1319 | 1065 |
8196 | 1066 /* Do not output the last pic after seeking. */ |
1067 if (s->last_picture_ptr || s->low_delay) { | |
1068 *data_size = sizeof(AVFrame); | |
1069 } | |
1070 | |
1071 return buf_size; | |
1234 | 1072 } |
1073 | |
1074 | |
1075 AVCodec svq3_decoder = { | |
1076 "svq3", | |
1077 CODEC_TYPE_VIDEO, | |
1078 CODEC_ID_SVQ3, | |
1079 sizeof(H264Context), | |
8209
65e05fda5280
move decoder initialization in separate function, earlier failure detection
bcoudurier
parents:
8196
diff
changeset
|
1080 svq3_decode_init, |
1234 | 1081 NULL, |
10852 | 1082 ff_h264_decode_end, |
1234 | 1083 svq3_decode_frame, |
2453 | 1084 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY, |
10442
fc06fc944c6d
Add additional long names for the Sorenson Vector Quantizer 3 decoder.
stefano
parents:
10151
diff
changeset
|
1085 .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), |
10146
38cfe222e1a4
Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents:
10020
diff
changeset
|
1086 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_NONE}, |
1234 | 1087 }; |