Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * Copyright (c) 2010-2011 Maxim Poliakovski |
||
3 | * Copyright (c) 2010-2011 Elvis Presley |
||
4 | * |
||
5 | * This file is part of FFmpeg. |
||
6 | * |
||
7 | * FFmpeg is free software; you can redistribute it and/or |
||
8 | * modify it under the terms of the GNU Lesser General Public |
||
9 | * License as published by the Free Software Foundation; either |
||
10 | * version 2.1 of the License, or (at your option) any later version. |
||
11 | * |
||
12 | * FFmpeg is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
15 | * Lesser General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU Lesser General Public |
||
18 | * License along with FFmpeg; if not, write to the Free Software |
||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
20 | */ |
||
21 | |||
22 | /** |
||
23 | * @file |
||
24 | * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy), 'ap4h' (4444) |
||
25 | */ |
||
26 | |||
27 | //#define DEBUG |
||
28 | |||
29 | #define LONG_BITSTREAM_READER |
||
30 | |||
31 | #include "avcodec.h" |
||
32 | #include "get_bits.h" |
||
33 | #include "internal.h" |
||
34 | #include "simple_idct.h" |
||
35 | #include "proresdec.h" |
||
36 | #include "proresdata.h" |
||
37 | |||
38 | static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) |
||
39 | { |
||
40 | int i; |
||
41 | for (i = 0; i < 64; i++) |
||
42 | dst[i] = permutation[src[i]]; |
||
43 | } |
||
44 | |||
45 | static av_cold int decode_init(AVCodecContext *avctx) |
||
46 | { |
||
47 | ProresContext *ctx = avctx->priv_data; |
||
48 | uint8_t idct_permutation[64]; |
||
49 | |||
50 | avctx->bits_per_raw_sample = 10; |
||
51 | |||
52 | ff_dsputil_init(&ctx->dsp, avctx); |
||
53 | ff_proresdsp_init(&ctx->prodsp, avctx); |
||
54 | |||
55 | ff_init_scantable_permutation(idct_permutation, |
||
56 | ctx->prodsp.idct_permutation_type); |
||
57 | |||
58 | permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation); |
||
59 | permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation); |
||
60 | |||
61 | return 0; |
||
62 | } |
||
63 | |||
64 | static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, |
||
65 | const int data_size, AVCodecContext *avctx) |
||
66 | { |
||
67 | int hdr_size, width, height, flags; |
||
68 | int version; |
||
69 | const uint8_t *ptr; |
||
70 | |||
71 | hdr_size = AV_RB16(buf); |
||
72 | av_dlog(avctx, "header size %d\n", hdr_size); |
||
73 | if (hdr_size > data_size) { |
||
74 | av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); |
||
75 | return AVERROR_INVALIDDATA; |
||
76 | } |
||
77 | |||
78 | version = AV_RB16(buf + 2); |
||
79 | av_dlog(avctx, "%.4s version %d\n", buf+4, version); |
||
80 | if (version > 1) { |
||
81 | av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); |
||
82 | return AVERROR_PATCHWELCOME; |
||
83 | } |
||
84 | |||
85 | width = AV_RB16(buf + 8); |
||
86 | height = AV_RB16(buf + 10); |
||
87 | if (width != avctx->width || height != avctx->height) { |
||
88 | av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n", |
||
89 | avctx->width, avctx->height, width, height); |
||
90 | return AVERROR_PATCHWELCOME; |
||
91 | } |
||
92 | |||
93 | ctx->frame_type = (buf[12] >> 2) & 3; |
||
94 | ctx->alpha_info = buf[17] & 0xf; |
||
95 | |||
96 | if (ctx->alpha_info > 2) { |
||
97 | av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); |
||
98 | return AVERROR_INVALIDDATA; |
||
99 | } |
||
100 | if (avctx->skip_alpha) ctx->alpha_info = 0; |
||
101 | |||
102 | av_dlog(avctx, "frame type %d\n", ctx->frame_type); |
||
103 | |||
104 | if (ctx->frame_type == 0) { |
||
105 | ctx->scan = ctx->progressive_scan; // permuted |
||
106 | } else { |
||
107 | ctx->scan = ctx->interlaced_scan; // permuted |
||
108 | ctx->frame->interlaced_frame = 1; |
||
109 | ctx->frame->top_field_first = ctx->frame_type == 1; |
||
110 | } |
||
111 | |||
112 | if (ctx->alpha_info) { |
||
113 | avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; |
||
114 | } else { |
||
115 | avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; |
||
116 | } |
||
117 | |||
118 | ptr = buf + 20; |
||
119 | flags = buf[19]; |
||
120 | av_dlog(avctx, "flags %x\n", flags); |
||
121 | |||
122 | if (flags & 2) { |
||
123 | if(buf + data_size - ptr < 64) { |
||
124 | av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); |
||
125 | return AVERROR_INVALIDDATA; |
||
126 | } |
||
127 | permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); |
||
128 | ptr += 64; |
||
129 | } else { |
||
130 | memset(ctx->qmat_luma, 4, 64); |
||
131 | } |
||
132 | |||
133 | if (flags & 1) { |
||
134 | if(buf + data_size - ptr < 64) { |
||
135 | av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); |
||
136 | return AVERROR_INVALIDDATA; |
||
137 | } |
||
138 | permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); |
||
139 | } else { |
||
140 | memset(ctx->qmat_chroma, 4, 64); |
||
141 | } |
||
142 | |||
143 | return hdr_size; |
||
144 | } |
||
145 | |||
146 | static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size) |
||
147 | { |
||
148 | ProresContext *ctx = avctx->priv_data; |
||
149 | int i, hdr_size, slice_count; |
||
150 | unsigned pic_data_size; |
||
151 | int log2_slice_mb_width, log2_slice_mb_height; |
||
152 | int slice_mb_count, mb_x, mb_y; |
||
153 | const uint8_t *data_ptr, *index_ptr; |
||
154 | |||
155 | hdr_size = buf[0] >> 3; |
||
156 | if (hdr_size < 8 || hdr_size > buf_size) { |
||
157 | av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); |
||
158 | return AVERROR_INVALIDDATA; |
||
159 | } |
||
160 | |||
161 | pic_data_size = AV_RB32(buf + 1); |
||
162 | if (pic_data_size > buf_size) { |
||
163 | av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); |
||
164 | return AVERROR_INVALIDDATA; |
||
165 | } |
||
166 | |||
167 | log2_slice_mb_width = buf[7] >> 4; |
||
168 | log2_slice_mb_height = buf[7] & 0xF; |
||
169 | if (log2_slice_mb_width > 3 || log2_slice_mb_height) { |
||
170 | av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", |
||
171 | 1 << log2_slice_mb_width, 1 << log2_slice_mb_height); |
||
172 | return AVERROR_INVALIDDATA; |
||
173 | } |
||
174 | |||
175 | ctx->mb_width = (avctx->width + 15) >> 4; |
||
176 | if (ctx->frame_type) |
||
177 | ctx->mb_height = (avctx->height + 31) >> 5; |
||
178 | else |
||
179 | ctx->mb_height = (avctx->height + 15) >> 4; |
||
180 | |||
181 | slice_count = AV_RB16(buf + 5); |
||
182 | |||
183 | if (ctx->slice_count != slice_count || !ctx->slices) { |
||
184 | av_freep(&ctx->slices); |
||
185 | ctx->slices = av_mallocz(slice_count * sizeof(*ctx->slices)); |
||
186 | if (!ctx->slices) |
||
187 | return AVERROR(ENOMEM); |
||
188 | ctx->slice_count = slice_count; |
||
189 | } |
||
190 | |||
191 | if (!slice_count) |
||
192 | return AVERROR(EINVAL); |
||
193 | |||
194 | if (hdr_size + slice_count*2 > buf_size) { |
||
195 | av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); |
||
196 | return AVERROR_INVALIDDATA; |
||
197 | } |
||
198 | |||
199 | // parse slice information |
||
200 | index_ptr = buf + hdr_size; |
||
201 | data_ptr = index_ptr + slice_count*2; |
||
202 | |||
203 | slice_mb_count = 1 << log2_slice_mb_width; |
||
204 | mb_x = 0; |
||
205 | mb_y = 0; |
||
206 | |||
207 | for (i = 0; i < slice_count; i++) { |
||
208 | SliceContext *slice = &ctx->slices[i]; |
||
209 | |||
210 | slice->data = data_ptr; |
||
211 | data_ptr += AV_RB16(index_ptr + i*2); |
||
212 | |||
213 | while (ctx->mb_width - mb_x < slice_mb_count) |
||
214 | slice_mb_count >>= 1; |
||
215 | |||
216 | slice->mb_x = mb_x; |
||
217 | slice->mb_y = mb_y; |
||
218 | slice->mb_count = slice_mb_count; |
||
219 | slice->data_size = data_ptr - slice->data; |
||
220 | |||
221 | if (slice->data_size < 6) { |
||
222 | av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); |
||
223 | return AVERROR_INVALIDDATA; |
||
224 | } |
||
225 | |||
226 | mb_x += slice_mb_count; |
||
227 | if (mb_x == ctx->mb_width) { |
||
228 | slice_mb_count = 1 << log2_slice_mb_width; |
||
229 | mb_x = 0; |
||
230 | mb_y++; |
||
231 | } |
||
232 | if (data_ptr > buf + buf_size) { |
||
233 | av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); |
||
234 | return AVERROR_INVALIDDATA; |
||
235 | } |
||
236 | } |
||
237 | |||
238 | if (mb_x || mb_y != ctx->mb_height) { |
||
239 | av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n", |
||
240 | mb_y, ctx->mb_height); |
||
241 | return AVERROR_INVALIDDATA; |
||
242 | } |
||
243 | |||
244 | return pic_data_size; |
||
245 | } |
||
246 | |||
247 | #define DECODE_CODEWORD(val, codebook) \ |
||
248 | do { \ |
||
249 | unsigned int rice_order, exp_order, switch_bits; \ |
||
250 | unsigned int q, buf, bits; \ |
||
251 | \ |
||
252 | UPDATE_CACHE(re, gb); \ |
||
253 | buf = GET_CACHE(re, gb); \ |
||
254 | \ |
||
255 | /* number of bits to switch between rice and exp golomb */ \ |
||
256 | switch_bits = codebook & 3; \ |
||
257 | rice_order = codebook >> 5; \ |
||
258 | exp_order = (codebook >> 2) & 7; \ |
||
259 | \ |
||
260 | q = 31 - av_log2(buf); \ |
||
261 | \ |
||
262 | if (q > switch_bits) { /* exp golomb */ \ |
||
263 | bits = exp_order - switch_bits + (q<<1); \ |
||
264 | val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ |
||
265 | ((switch_bits + 1) << rice_order); \ |
||
266 | SKIP_BITS(re, gb, bits); \ |
||
267 | } else if (rice_order) { \ |
||
268 | SKIP_BITS(re, gb, q+1); \ |
||
269 | val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ |
||
270 | SKIP_BITS(re, gb, rice_order); \ |
||
271 | } else { \ |
||
272 | val = q; \ |
||
273 | SKIP_BITS(re, gb, q+1); \ |
||
274 | } \ |
||
275 | } while (0) |
||
276 | |||
277 | #define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1))) |
||
278 | |||
279 | #define FIRST_DC_CB 0xB8 |
||
280 | |||
281 | static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; |
||
282 | |||
283 | static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, |
||
284 | int blocks_per_slice) |
||
285 | { |
||
286 | int16_t prev_dc; |
||
287 | int code, i, sign; |
||
288 | |||
289 | OPEN_READER(re, gb); |
||
290 | |||
291 | DECODE_CODEWORD(code, FIRST_DC_CB); |
||
292 | prev_dc = TOSIGNED(code); |
||
293 | out[0] = prev_dc; |
||
294 | |||
295 | out += 64; // dc coeff for the next block |
||
296 | |||
297 | code = 5; |
||
298 | sign = 0; |
||
299 | for (i = 1; i < blocks_per_slice; i++, out += 64) { |
||
300 | DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]); |
||
301 | if(code) sign ^= -(code & 1); |
||
302 | else sign = 0; |
||
303 | prev_dc += (((code + 1) >> 1) ^ sign) - sign; |
||
304 | out[0] = prev_dc; |
||
305 | } |
||
306 | CLOSE_READER(re, gb); |
||
307 | } |
||
308 | |||
309 | // adaptive codebook switching lut according to previous run/level values |
||
310 | static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; |
||
311 | static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; |
||
312 | |||
313 | static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, |
||
314 | int16_t *out, int blocks_per_slice) |
||
315 | { |
||
316 | ProresContext *ctx = avctx->priv_data; |
||
317 | int block_mask, sign; |
||
318 | unsigned pos, run, level; |
||
319 | int max_coeffs, i, bits_left; |
||
320 | int log2_block_count = av_log2(blocks_per_slice); |
||
321 | |||
322 | OPEN_READER(re, gb); |
||
323 | UPDATE_CACHE(re, gb); \ |
||
324 | run = 4; |
||
325 | level = 2; |
||
326 | |||
327 | max_coeffs = 64 << log2_block_count; |
||
328 | block_mask = blocks_per_slice - 1; |
||
329 | |||
330 | for (pos = block_mask;;) { |
||
331 | bits_left = gb->size_in_bits - re_index; |
||
332 | if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) |
||
333 | break; |
||
334 | |||
335 | DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)]); |
||
336 | pos += run + 1; |
||
337 | if (pos >= max_coeffs) { |
||
338 | av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); |
||
339 | return AVERROR_INVALIDDATA; |
||
340 | } |
||
341 | |||
342 | DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]); |
||
343 | level += 1; |
||
344 | |||
345 | i = pos >> log2_block_count; |
||
346 | |||
347 | sign = SHOW_SBITS(re, gb, 1); |
||
348 | SKIP_BITS(re, gb, 1); |
||
349 | out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign); |
||
350 | } |
||
351 | |||
352 | CLOSE_READER(re, gb); |
||
353 | return 0; |
||
354 | } |
||
355 | |||
356 | static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, |
||
357 | uint16_t *dst, int dst_stride, |
||
358 | const uint8_t *buf, unsigned buf_size, |
||
359 | const int16_t *qmat) |
||
360 | { |
||
361 | ProresContext *ctx = avctx->priv_data; |
||
362 | LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); |
||
363 | int16_t *block; |
||
364 | GetBitContext gb; |
||
365 | int i, blocks_per_slice = slice->mb_count<<2; |
||
366 | int ret; |
||
367 | |||
368 | for (i = 0; i < blocks_per_slice; i++) |
||
369 | ctx->dsp.clear_block(blocks+(i<<6)); |
||
370 | |||
371 | init_get_bits(&gb, buf, buf_size << 3); |
||
372 | |||
373 | decode_dc_coeffs(&gb, blocks, blocks_per_slice); |
||
374 | if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) |
||
375 | return ret; |
||
376 | |||
377 | block = blocks; |
||
378 | for (i = 0; i < slice->mb_count; i++) { |
||
379 | ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); |
||
380 | ctx->prodsp.idct_put(dst +8, dst_stride, block+(1<<6), qmat); |
||
381 | ctx->prodsp.idct_put(dst+4*dst_stride , dst_stride, block+(2<<6), qmat); |
||
382 | ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat); |
||
383 | block += 4*64; |
||
384 | dst += 16; |
||
385 | } |
||
386 | return 0; |
||
387 | } |
||
388 | |||
389 | static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, |
||
390 | uint16_t *dst, int dst_stride, |
||
391 | const uint8_t *buf, unsigned buf_size, |
||
392 | const int16_t *qmat, int log2_blocks_per_mb) |
||
393 | { |
||
394 | ProresContext *ctx = avctx->priv_data; |
||
395 | LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); |
||
396 | int16_t *block; |
||
397 | GetBitContext gb; |
||
398 | int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; |
||
399 | int ret; |
||
400 | |||
401 | for (i = 0; i < blocks_per_slice; i++) |
||
402 | ctx->dsp.clear_block(blocks+(i<<6)); |
||
403 | |||
404 | init_get_bits(&gb, buf, buf_size << 3); |
||
405 | |||
406 | decode_dc_coeffs(&gb, blocks, blocks_per_slice); |
||
407 | if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) |
||
408 | return ret; |
||
409 | |||
410 | block = blocks; |
||
411 | for (i = 0; i < slice->mb_count; i++) { |
||
412 | for (j = 0; j < log2_blocks_per_mb; j++) { |
||
413 | ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); |
||
414 | ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat); |
||
415 | block += 2*64; |
||
416 | dst += 8; |
||
417 | } |
||
418 | } |
||
419 | return 0; |
||
420 | } |
||
421 | |||
422 | static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, |
||
423 | const int num_bits) |
||
424 | { |
||
425 | const int mask = (1 << num_bits) - 1; |
||
426 | int i, idx, val, alpha_val; |
||
427 | |||
428 | idx = 0; |
||
429 | alpha_val = mask; |
||
430 | do { |
||
431 | do { |
||
432 | if (get_bits1(gb)) { |
||
433 | val = get_bits(gb, num_bits); |
||
434 | } else { |
||
435 | int sign; |
||
436 | val = get_bits(gb, num_bits == 16 ? 7 : 4); |
||
437 | sign = val & 1; |
||
438 | val = (val + 2) >> 1; |
||
439 | if (sign) |
||
440 | val = -val; |
||
441 | } |
||
442 | alpha_val = (alpha_val + val) & mask; |
||
443 | if (num_bits == 16) { |
||
444 | dst[idx++] = alpha_val >> 6; |
||
445 | } else { |
||
446 | dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); |
||
447 | } |
||
448 | if (idx >= num_coeffs) |
||
449 | break; |
||
450 | } while (get_bits_left(gb)>0 && get_bits1(gb)); |
||
451 | val = get_bits(gb, 4); |
||
452 | if (!val) |
||
453 | val = get_bits(gb, 11); |
||
454 | if (idx + val > num_coeffs) |
||
455 | val = num_coeffs - idx; |
||
456 | if (num_bits == 16) { |
||
457 | for (i = 0; i < val; i++) |
||
458 | dst[idx++] = alpha_val >> 6; |
||
459 | } else { |
||
460 | for (i = 0; i < val; i++) |
||
461 | dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); |
||
462 | |||
463 | } |
||
464 | } while (idx < num_coeffs); |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Decode alpha slice plane. |
||
469 | */ |
||
470 | static void decode_slice_alpha(ProresContext *ctx, |
||
471 | uint16_t *dst, int dst_stride, |
||
472 | const uint8_t *buf, int buf_size, |
||
473 | int blocks_per_slice) |
||
474 | { |
||
475 | GetBitContext gb; |
||
476 | int i; |
||
477 | LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); |
||
478 | int16_t *block; |
||
479 | |||
480 | for (i = 0; i < blocks_per_slice<<2; i++) |
||
481 | ctx->dsp.clear_block(blocks+(i<<6)); |
||
482 | |||
483 | init_get_bits(&gb, buf, buf_size << 3); |
||
484 | |||
485 | if (ctx->alpha_info == 2) { |
||
486 | unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16); |
||
487 | } else { |
||
488 | unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8); |
||
489 | } |
||
490 | |||
491 | block = blocks; |
||
492 | for (i = 0; i < 16; i++) { |
||
493 | memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst)); |
||
494 | dst += dst_stride >> 1; |
||
495 | block += 16 * blocks_per_slice; |
||
496 | } |
||
497 | } |
||
498 | |||
499 | static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) |
||
500 | { |
||
501 | ProresContext *ctx = avctx->priv_data; |
||
502 | SliceContext *slice = &ctx->slices[jobnr]; |
||
503 | const uint8_t *buf = slice->data; |
||
504 | AVFrame *pic = ctx->frame; |
||
505 | int i, hdr_size, qscale, log2_chroma_blocks_per_mb; |
||
506 | int luma_stride, chroma_stride; |
||
507 | int y_data_size, u_data_size, v_data_size, a_data_size; |
||
508 | uint8_t *dest_y, *dest_u, *dest_v, *dest_a; |
||
509 | int16_t qmat_luma_scaled[64]; |
||
510 | int16_t qmat_chroma_scaled[64]; |
||
511 | int mb_x_shift; |
||
512 | int ret; |
||
513 | |||
514 | slice->ret = -1; |
||
515 | //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", |
||
516 | // jobnr, slice->mb_count, slice->mb_x, slice->mb_y); |
||
517 | |||
518 | // slice header |
||
519 | hdr_size = buf[0] >> 3; |
||
520 | qscale = av_clip(buf[1], 1, 224); |
||
521 | qscale = qscale > 128 ? qscale - 96 << 2: qscale; |
||
522 | y_data_size = AV_RB16(buf + 2); |
||
523 | u_data_size = AV_RB16(buf + 4); |
||
524 | v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; |
||
525 | if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); |
||
526 | a_data_size = slice->data_size - y_data_size - u_data_size - |
||
527 | v_data_size - hdr_size; |
||
528 | |||
529 | if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0 |
||
530 | || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){ |
||
531 | av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); |
||
532 | return AVERROR_INVALIDDATA; |
||
533 | } |
||
534 | |||
535 | buf += hdr_size; |
||
536 | |||
537 | for (i = 0; i < 64; i++) { |
||
538 | qmat_luma_scaled [i] = ctx->qmat_luma [i] * qscale; |
||
539 | qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; |
||
540 | } |
||
541 | |||
542 | if (ctx->frame_type == 0) { |
||
543 | luma_stride = pic->linesize[0]; |
||
544 | chroma_stride = pic->linesize[1]; |
||
545 | } else { |
||
546 | luma_stride = pic->linesize[0] << 1; |
||
547 | chroma_stride = pic->linesize[1] << 1; |
||
548 | } |
||
549 | |||
550 | if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) { |
||
551 | mb_x_shift = 5; |
||
552 | log2_chroma_blocks_per_mb = 2; |
||
553 | } else { |
||
554 | mb_x_shift = 4; |
||
555 | log2_chroma_blocks_per_mb = 1; |
||
556 | } |
||
557 | |||
558 | dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); |
||
559 | dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); |
||
560 | dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); |
||
561 | dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); |
||
562 | |||
563 | if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { |
||
564 | dest_y += pic->linesize[0]; |
||
565 | dest_u += pic->linesize[1]; |
||
566 | dest_v += pic->linesize[2]; |
||
567 | dest_a += pic->linesize[3]; |
||
568 | } |
||
569 | |||
570 | ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, |
||
571 | buf, y_data_size, qmat_luma_scaled); |
||
572 | if (ret < 0) |
||
573 | return ret; |
||
574 | |||
575 | if (!(avctx->flags & CODEC_FLAG_GRAY)) { |
||
576 | ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride, |
||
577 | buf + y_data_size, u_data_size, |
||
578 | qmat_chroma_scaled, log2_chroma_blocks_per_mb); |
||
579 | if (ret < 0) |
||
580 | return ret; |
||
581 | |||
582 | ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride, |
||
583 | buf + y_data_size + u_data_size, v_data_size, |
||
584 | qmat_chroma_scaled, log2_chroma_blocks_per_mb); |
||
585 | if (ret < 0) |
||
586 | return ret; |
||
587 | } |
||
588 | /* decode alpha plane if available */ |
||
589 | if (ctx->alpha_info && pic->data[3] && a_data_size) |
||
590 | decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, |
||
591 | buf + y_data_size + u_data_size + v_data_size, |
||
592 | a_data_size, slice->mb_count); |
||
593 | |||
594 | slice->ret = 0; |
||
595 | return 0; |
||
596 | } |
||
597 | |||
598 | static int decode_picture(AVCodecContext *avctx) |
||
599 | { |
||
600 | ProresContext *ctx = avctx->priv_data; |
||
601 | int i; |
||
602 | |||
603 | avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count); |
||
604 | |||
605 | for (i = 0; i < ctx->slice_count; i++) |
||
606 | if (ctx->slices[i].ret < 0) |
||
607 | return ctx->slices[i].ret; |
||
608 | |||
609 | return 0; |
||
610 | } |
||
611 | |||
612 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
||
613 | AVPacket *avpkt) |
||
614 | { |
||
615 | ProresContext *ctx = avctx->priv_data; |
||
616 | AVFrame *frame = data; |
||
617 | const uint8_t *buf = avpkt->data; |
||
618 | int buf_size = avpkt->size; |
||
619 | int frame_hdr_size, pic_size, ret; |
||
620 | |||
621 | if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { |
||
622 | av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); |
||
623 | return AVERROR_INVALIDDATA; |
||
624 | } |
||
625 | |||
626 | ctx->frame = frame; |
||
627 | ctx->frame->pict_type = AV_PICTURE_TYPE_I; |
||
628 | ctx->frame->key_frame = 1; |
||
629 | ctx->first_field = 1; |
||
630 | |||
631 | buf += 8; |
||
632 | buf_size -= 8; |
||
633 | |||
634 | frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); |
||
635 | if (frame_hdr_size < 0) |
||
636 | return frame_hdr_size; |
||
637 | |||
638 | buf += frame_hdr_size; |
||
639 | buf_size -= frame_hdr_size; |
||
640 | |||
641 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
||
642 | return ret; |
||
643 | |||
644 | decode_picture: |
||
645 | pic_size = decode_picture_header(avctx, buf, buf_size); |
||
646 | if (pic_size < 0) { |
||
647 | av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); |
||
648 | return pic_size; |
||
649 | } |
||
650 | |||
651 | if ((ret = decode_picture(avctx)) < 0) { |
||
652 | av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); |
||
653 | return ret; |
||
654 | } |
||
655 | |||
656 | buf += pic_size; |
||
657 | buf_size -= pic_size; |
||
658 | |||
659 | if (ctx->frame_type && buf_size > 0 && ctx->first_field) { |
||
660 | ctx->first_field = 0; |
||
661 | goto decode_picture; |
||
662 | } |
||
663 | |||
664 | *got_frame = 1; |
||
665 | |||
666 | return avpkt->size; |
||
667 | } |
||
668 | |||
669 | static av_cold int decode_close(AVCodecContext *avctx) |
||
670 | { |
||
671 | ProresContext *ctx = avctx->priv_data; |
||
672 | |||
673 | av_freep(&ctx->slices); |
||
674 | |||
675 | return 0; |
||
676 | } |
||
677 | |||
678 | AVCodec ff_prores_decoder = { |
||
679 | .name = "prores", |
||
680 | .long_name = NULL_IF_CONFIG_SMALL("ProRes"), |
||
681 | .type = AVMEDIA_TYPE_VIDEO, |
||
682 | .id = AV_CODEC_ID_PRORES, |
||
683 | .priv_data_size = sizeof(ProresContext), |
||
684 | .init = decode_init, |
||
685 | .close = decode_close, |
||
686 | .decode = decode_frame, |
||
687 | .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, |
||
688 | };>>>>>>>>>>><>><>><>><>><>><>><>><>><>><>>>>>><>>><>6)); |