Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * Apple ProRes compatible decoder | |
3 | * | |
4 | * Copyright (c) 2010-2011 Maxim Poliakovski | |
5 | * | |
6 | * This file is part of FFmpeg. | |
7 | * | |
8 | * FFmpeg is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * FFmpeg is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with FFmpeg; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 | */ | |
22 | ||
23 | /** | |
24 | * @file | |
25 | * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444. | |
26 | * It is used for storing and editing high definition video data in Apple's Final Cut Pro. | |
27 | * | |
28 | * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes | |
29 | */ | |
30 | ||
31 | #define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once | |
32 | ||
33 | #include <stdint.h> | |
34 | ||
35 | #include "libavutil/intmath.h" | |
36 | #include "avcodec.h" | |
37 | #include "idctdsp.h" | |
38 | #include "internal.h" | |
39 | #include "proresdata.h" | |
40 | #include "proresdsp.h" | |
41 | #include "get_bits.h" | |
42 | ||
43 | typedef struct { | |
44 | const uint8_t *index; ///< pointers to the data of this slice | |
45 | int slice_num; | |
46 | int x_pos, y_pos; | |
47 | int slice_width; | |
48 | int prev_slice_sf; ///< scalefactor of the previous decoded slice | |
49 | DECLARE_ALIGNED(16, int16_t, blocks)[8 * 4 * 64]; | |
50 | DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64]; | |
51 | DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64]; | |
52 | } ProresThreadData; | |
53 | ||
54 | typedef struct { | |
55 | ProresDSPContext dsp; | |
56 | AVFrame *frame; | |
57 | ScanTable scantable; | |
58 | int scantable_type; ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced | |
59 | ||
60 | int frame_type; ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first | |
61 | int pic_format; ///< 2 = 422, 3 = 444 | |
62 | uint8_t qmat_luma[64]; ///< dequantization matrix for luma | |
63 | uint8_t qmat_chroma[64]; ///< dequantization matrix for chroma | |
64 | int qmat_changed; ///< 1 - global quantization matrices changed | |
65 | int total_slices; ///< total number of slices in a picture | |
66 | ProresThreadData *slice_data; | |
67 | int pic_num; | |
68 | int chroma_factor; | |
69 | int mb_chroma_factor; | |
70 | int num_chroma_blocks; ///< number of chrominance blocks in a macroblock | |
71 | int num_x_slices; | |
72 | int num_y_slices; | |
73 | int slice_width_factor; | |
74 | int slice_height_factor; | |
75 | int num_x_mbs; | |
76 | int num_y_mbs; | |
77 | int alpha_info; | |
78 | } ProresContext; | |
79 | ||
80 | ||
81 | static av_cold int decode_init(AVCodecContext *avctx) | |
82 | { | |
83 | ProresContext *ctx = avctx->priv_data; | |
84 | ||
85 | ctx->total_slices = 0; | |
86 | ctx->slice_data = NULL; | |
87 | ||
88 | avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE; | |
89 | ff_proresdsp_init(&ctx->dsp, avctx); | |
90 | ||
91 | ctx->scantable_type = -1; // set scantable type to uninitialized | |
92 | memset(ctx->qmat_luma, 4, 64); | |
93 | memset(ctx->qmat_chroma, 4, 64); | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
98 | ||
99 | static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, | |
100 | const int data_size, AVCodecContext *avctx) | |
101 | { | |
102 | int hdr_size, version, width, height, flags; | |
103 | const uint8_t *ptr; | |
104 | ||
105 | hdr_size = AV_RB16(buf); | |
106 | if (hdr_size > data_size) { | |
107 | av_log(avctx, AV_LOG_ERROR, "frame data too small\n"); | |
108 | return AVERROR_INVALIDDATA; | |
109 | } | |
110 | ||
111 | version = AV_RB16(buf + 2); | |
112 | if (version >= 2) { | |
113 | av_log(avctx, AV_LOG_ERROR, | |
114 | "unsupported header version: %d\n", version); | |
115 | return AVERROR_INVALIDDATA; | |
116 | } | |
117 | ||
118 | width = AV_RB16(buf + 8); | |
119 | height = AV_RB16(buf + 10); | |
120 | if (width != avctx->width || height != avctx->height) { | |
121 | av_log(avctx, AV_LOG_ERROR, | |
122 | "picture dimension changed: old: %d x %d, new: %d x %d\n", | |
123 | avctx->width, avctx->height, width, height); | |
124 | return AVERROR_INVALIDDATA; | |
125 | } | |
126 | ||
127 | ctx->frame_type = (buf[12] >> 2) & 3; | |
128 | if (ctx->frame_type > 2) { | |
129 | av_log(avctx, AV_LOG_ERROR, | |
130 | "unsupported frame type: %d\n", ctx->frame_type); | |
131 | return AVERROR_INVALIDDATA; | |
132 | } | |
133 | ||
134 | ctx->chroma_factor = (buf[12] >> 6) & 3; | |
135 | ctx->mb_chroma_factor = ctx->chroma_factor + 2; | |
136 | ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1; | |
137 | ctx->alpha_info = buf[17] & 0xf; | |
138 | ||
139 | if (ctx->alpha_info > 2) { | |
140 | av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); | |
141 | return AVERROR_INVALIDDATA; | |
142 | } | |
143 | if (avctx->skip_alpha) ctx->alpha_info = 0; | |
144 | ||
145 | switch (ctx->chroma_factor) { | |
146 | case 2: | |
147 | avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA422P10 | |
148 | : AV_PIX_FMT_YUV422P10; | |
149 | break; | |
150 | case 3: | |
151 | avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA444P10 | |
152 | : AV_PIX_FMT_YUV444P10; | |
153 | break; | |
154 | default: | |
155 | av_log(avctx, AV_LOG_ERROR, | |
156 | "unsupported picture format: %d\n", ctx->pic_format); | |
157 | return AVERROR_INVALIDDATA; | |
158 | } | |
159 | ||
160 | if (ctx->scantable_type != ctx->frame_type) { | |
161 | if (!ctx->frame_type) | |
162 | ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, | |
163 | ff_prores_progressive_scan); | |
164 | else | |
165 | ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, | |
166 | ff_prores_interlaced_scan); | |
167 | ctx->scantable_type = ctx->frame_type; | |
168 | } | |
169 | ||
170 | if (ctx->frame_type) { /* if interlaced */ | |
171 | ctx->frame->interlaced_frame = 1; | |
172 | ctx->frame->top_field_first = ctx->frame_type & 1; | |
173 | } else { | |
174 | ctx->frame->interlaced_frame = 0; | |
175 | } | |
176 | ||
177 | avctx->color_primaries = buf[14]; | |
178 | avctx->color_trc = buf[15]; | |
179 | avctx->colorspace = buf[16]; | |
180 | ||
181 | ctx->qmat_changed = 0; | |
182 | ptr = buf + 20; | |
183 | flags = buf[19]; | |
184 | if (flags & 2) { | |
185 | if (ptr - buf > hdr_size - 64) { | |
186 | av_log(avctx, AV_LOG_ERROR, "header data too small\n"); | |
187 | return AVERROR_INVALIDDATA; | |
188 | } | |
189 | if (memcmp(ctx->qmat_luma, ptr, 64)) { | |
190 | memcpy(ctx->qmat_luma, ptr, 64); | |
191 | ctx->qmat_changed = 1; | |
192 | } | |
193 | ptr += 64; | |
194 | } else { | |
195 | memset(ctx->qmat_luma, 4, 64); | |
196 | ctx->qmat_changed = 1; | |
197 | } | |
198 | ||
199 | if (flags & 1) { | |
200 | if (ptr - buf > hdr_size - 64) { | |
201 | av_log(avctx, AV_LOG_ERROR, "header data too small\n"); | |
202 | return -1; | |
203 | } | |
204 | if (memcmp(ctx->qmat_chroma, ptr, 64)) { | |
205 | memcpy(ctx->qmat_chroma, ptr, 64); | |
206 | ctx->qmat_changed = 1; | |
207 | } | |
208 | } else { | |
209 | memset(ctx->qmat_chroma, 4, 64); | |
210 | ctx->qmat_changed = 1; | |
211 | } | |
212 | ||
213 | return hdr_size; | |
214 | } | |
215 | ||
216 | ||
217 | static int decode_picture_header(ProresContext *ctx, const uint8_t *buf, | |
218 | const int data_size, AVCodecContext *avctx) | |
219 | { | |
220 | int i, hdr_size, pic_data_size, num_slices; | |
221 | int slice_width_factor, slice_height_factor; | |
222 | int remainder, num_x_slices; | |
223 | const uint8_t *data_ptr, *index_ptr; | |
224 | ||
225 | hdr_size = data_size > 0 ? buf[0] >> 3 : 0; | |
226 | if (hdr_size < 8 || hdr_size > data_size) { | |
227 | av_log(avctx, AV_LOG_ERROR, "picture header too small\n"); | |
228 | return AVERROR_INVALIDDATA; | |
229 | } | |
230 | ||
231 | pic_data_size = AV_RB32(buf + 1); | |
232 | if (pic_data_size > data_size) { | |
233 | av_log(avctx, AV_LOG_ERROR, "picture data too small\n"); | |
234 | return AVERROR_INVALIDDATA; | |
235 | } | |
236 | ||
237 | slice_width_factor = buf[7] >> 4; | |
238 | slice_height_factor = buf[7] & 0xF; | |
239 | if (slice_width_factor > 3 || slice_height_factor) { | |
240 | av_log(avctx, AV_LOG_ERROR, | |
241 | "unsupported slice dimension: %d x %d\n", | |
242 | 1 << slice_width_factor, 1 << slice_height_factor); | |
243 | return AVERROR_INVALIDDATA; | |
244 | } | |
245 | ||
246 | ctx->slice_width_factor = slice_width_factor; | |
247 | ctx->slice_height_factor = slice_height_factor; | |
248 | ||
249 | ctx->num_x_mbs = (avctx->width + 15) >> 4; | |
250 | ctx->num_y_mbs = (avctx->height + | |
251 | (1 << (4 + ctx->frame->interlaced_frame)) - 1) >> | |
252 | (4 + ctx->frame->interlaced_frame); | |
253 | ||
254 | remainder = ctx->num_x_mbs & ((1 << slice_width_factor) - 1); | |
255 | num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) + | |
256 | ((remainder >> 1) & 1) + ((remainder >> 2) & 1); | |
257 | ||
258 | num_slices = num_x_slices * ctx->num_y_mbs; | |
259 | if (num_slices != AV_RB16(buf + 5)) { | |
260 | av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n"); | |
261 | return AVERROR_INVALIDDATA; | |
262 | } | |
263 | ||
264 | if (ctx->total_slices != num_slices) { | |
265 | av_freep(&ctx->slice_data); | |
266 | ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0])); | |
267 | if (!ctx->slice_data) | |
268 | return AVERROR(ENOMEM); | |
269 | ctx->total_slices = num_slices; | |
270 | } | |
271 | ||
272 | if (hdr_size + num_slices * 2 > data_size) { | |
273 | av_log(avctx, AV_LOG_ERROR, "slice table too small\n"); | |
274 | return AVERROR_INVALIDDATA; | |
275 | } | |
276 | ||
277 | /* parse slice table allowing quick access to the slice data */ | |
278 | index_ptr = buf + hdr_size; | |
279 | data_ptr = index_ptr + num_slices * 2; | |
280 | ||
281 | for (i = 0; i < num_slices; i++) { | |
282 | ctx->slice_data[i].index = data_ptr; | |
283 | ctx->slice_data[i].prev_slice_sf = 0; | |
284 | data_ptr += AV_RB16(index_ptr + i * 2); | |
285 | } | |
286 | ctx->slice_data[i].index = data_ptr; | |
287 | ctx->slice_data[i].prev_slice_sf = 0; | |
288 | ||
289 | if (data_ptr > buf + data_size) { | |
290 | av_log(avctx, AV_LOG_ERROR, "out of slice data\n"); | |
291 | return -1; | |
292 | } | |
293 | ||
294 | return pic_data_size; | |
295 | } | |
296 | ||
297 | ||
298 | /** | |
299 | * Read an unsigned rice/exp golomb codeword. | |
300 | */ | |
301 | static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook) | |
302 | { | |
303 | unsigned int rice_order, exp_order, switch_bits; | |
304 | unsigned int buf, code; | |
305 | int log, prefix_len, len; | |
306 | ||
307 | OPEN_READER(re, gb); | |
308 | UPDATE_CACHE(re, gb); | |
309 | buf = GET_CACHE(re, gb); | |
310 | ||
311 | /* number of prefix bits to switch between Rice and expGolomb */ | |
312 | switch_bits = (codebook & 3) + 1; | |
313 | rice_order = codebook >> 5; /* rice code order */ | |
314 | exp_order = (codebook >> 2) & 7; /* exp golomb code order */ | |
315 | ||
316 | log = 31 - av_log2(buf); /* count prefix bits (zeroes) */ | |
317 | ||
318 | if (log < switch_bits) { /* ok, we got a rice code */ | |
319 | if (!rice_order) { | |
320 | /* shortcut for faster decoding of rice codes without remainder */ | |
321 | code = log; | |
322 | LAST_SKIP_BITS(re, gb, log + 1); | |
323 | } else { | |
324 | prefix_len = log + 1; | |
325 | code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order); | |
326 | LAST_SKIP_BITS(re, gb, prefix_len + rice_order); | |
327 | } | |
328 | } else { /* otherwise we got a exp golomb code */ | |
329 | len = (log << 1) - switch_bits + exp_order + 1; | |
330 | code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order); | |
331 | LAST_SKIP_BITS(re, gb, len); | |
332 | } | |
333 | ||
334 | CLOSE_READER(re, gb); | |
335 | ||
336 | return code; | |
337 | } | |
338 | ||
339 | #define LSB2SIGN(x) (-((x) & 1)) | |
340 | #define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x)) | |
341 | ||
342 | /** | |
343 | * Decode DC coefficients for all blocks in a slice. | |
344 | */ | |
345 | static inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, | |
346 | int nblocks) | |
347 | { | |
348 | int16_t prev_dc; | |
349 | int i, sign; | |
350 | int16_t delta; | |
351 | unsigned int code; | |
352 | ||
353 | code = decode_vlc_codeword(gb, FIRST_DC_CB); | |
354 | out[0] = prev_dc = TOSIGNED(code); | |
355 | ||
356 | out += 64; /* move to the DC coeff of the next block */ | |
357 | delta = 3; | |
358 | ||
359 | for (i = 1; i < nblocks; i++, out += 64) { | |
360 | code = decode_vlc_codeword(gb, ff_prores_dc_codebook[FFMIN(FFABS(delta), 3)]); | |
361 | ||
362 | sign = -(((delta >> 15) & 1) ^ (code & 1)); | |
363 | delta = (((code + 1) >> 1) ^ sign) - sign; | |
364 | prev_dc += delta; | |
365 | out[0] = prev_dc; | |
366 | } | |
367 | } | |
368 | ||
369 | ||
370 | /** | |
371 | * Decode AC coefficients for all blocks in a slice. | |
372 | */ | |
373 | static inline int decode_ac_coeffs(GetBitContext *gb, int16_t *out, | |
374 | int blocks_per_slice, | |
375 | int plane_size_factor, | |
376 | const uint8_t *scan) | |
377 | { | |
378 | int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index; | |
379 | int max_coeffs, bits_left; | |
380 | ||
381 | /* set initial prediction values */ | |
382 | run = 4; | |
383 | level = 2; | |
384 | ||
385 | max_coeffs = blocks_per_slice << 6; | |
386 | block_mask = blocks_per_slice - 1; | |
387 | ||
388 | for (pos = blocks_per_slice - 1; pos < max_coeffs;) { | |
389 | run_cb_index = ff_prores_run_to_cb_index[FFMIN(run, 15)]; | |
390 | lev_cb_index = ff_prores_lev_to_cb_index[FFMIN(level, 9)]; | |
391 | ||
392 | bits_left = get_bits_left(gb); | |
393 | if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) | |
394 | return 0; | |
395 | ||
396 | run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]); | |
397 | if (run < 0) | |
398 | return AVERROR_INVALIDDATA; | |
399 | ||
400 | bits_left = get_bits_left(gb); | |
401 | if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) | |
402 | return AVERROR_INVALIDDATA; | |
403 | ||
404 | level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1; | |
405 | if (level < 0) | |
406 | return AVERROR_INVALIDDATA; | |
407 | ||
408 | pos += run + 1; | |
409 | if (pos >= max_coeffs) | |
410 | break; | |
411 | ||
412 | sign = get_sbits(gb, 1); | |
413 | out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] = | |
414 | (level ^ sign) - sign; | |
415 | } | |
416 | ||
417 | return 0; | |
418 | } | |
419 | ||
420 | ||
421 | /** | |
422 | * Decode a slice plane (luma or chroma). | |
423 | */ | |
424 | static int decode_slice_plane(ProresContext *ctx, ProresThreadData *td, | |
425 | const uint8_t *buf, | |
426 | int data_size, uint16_t *out_ptr, | |
427 | int linesize, int mbs_per_slice, | |
428 | int blocks_per_mb, int plane_size_factor, | |
429 | const int16_t *qmat, int is_chroma) | |
430 | { | |
431 | GetBitContext gb; | |
432 | int16_t *block_ptr; | |
433 | int mb_num, blocks_per_slice, ret; | |
434 | ||
435 | blocks_per_slice = mbs_per_slice * blocks_per_mb; | |
436 | ||
437 | memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks)); | |
438 | ||
439 | init_get_bits(&gb, buf, data_size << 3); | |
440 | ||
441 | decode_dc_coeffs(&gb, td->blocks, blocks_per_slice); | |
442 | ||
443 | ret = decode_ac_coeffs(&gb, td->blocks, blocks_per_slice, | |
444 | plane_size_factor, ctx->scantable.permutated); | |
445 | if (ret < 0) | |
446 | return ret; | |
447 | ||
448 | /* inverse quantization, inverse transform and output */ | |
449 | block_ptr = td->blocks; | |
450 | ||
451 | if (!is_chroma) { | |
452 | for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) { | |
453 | ctx->dsp.idct_put(out_ptr, linesize, block_ptr, qmat); | |
454 | block_ptr += 64; | |
455 | if (blocks_per_mb > 2) { | |
456 | ctx->dsp.idct_put(out_ptr + 8, linesize, block_ptr, qmat); | |
457 | block_ptr += 64; | |
458 | } | |
459 | ctx->dsp.idct_put(out_ptr + linesize * 4, linesize, block_ptr, qmat); | |
460 | block_ptr += 64; | |
461 | if (blocks_per_mb > 2) { | |
462 | ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat); | |
463 | block_ptr += 64; | |
464 | } | |
465 | } | |
466 | } else { | |
467 | for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) { | |
468 | ctx->dsp.idct_put(out_ptr, linesize, block_ptr, qmat); | |
469 | block_ptr += 64; | |
470 | ctx->dsp.idct_put(out_ptr + linesize * 4, linesize, block_ptr, qmat); | |
471 | block_ptr += 64; | |
472 | if (blocks_per_mb > 2) { | |
473 | ctx->dsp.idct_put(out_ptr + 8, linesize, block_ptr, qmat); | |
474 | block_ptr += 64; | |
475 | ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat); | |
476 | block_ptr += 64; | |
477 | } | |
478 | } | |
479 | } | |
480 | return 0; | |
481 | } | |
482 | ||
483 | ||
484 | static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, | |
485 | const int num_bits) | |
486 | { | |
487 | const int mask = (1 << num_bits) - 1; | |
488 | int i, idx, val, alpha_val; | |
489 | ||
490 | idx = 0; | |
491 | alpha_val = mask; | |
492 | do { | |
493 | do { | |
494 | if (get_bits1(gb)) | |
495 | val = get_bits(gb, num_bits); | |
496 | else { | |
497 | int sign; | |
498 | val = get_bits(gb, num_bits == 16 ? 7 : 4); | |
499 | sign = val & 1; | |
500 | val = (val + 2) >> 1; | |
501 | if (sign) | |
502 | val = -val; | |
503 | } | |
504 | alpha_val = (alpha_val + val) & mask; | |
505 | if (num_bits == 16) | |
506 | dst[idx++] = alpha_val >> 6; | |
507 | else | |
508 | dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); | |
509 | if (idx >= num_coeffs) { | |
510 | break; | |
511 | } | |
512 | } while (get_bits1(gb)); | |
513 | val = get_bits(gb, 4); | |
514 | if (!val) | |
515 | val = get_bits(gb, 11); | |
516 | if (idx + val > num_coeffs) | |
517 | val = num_coeffs - idx; | |
518 | if (num_bits == 16) | |
519 | for (i = 0; i < val; i++) | |
520 | dst[idx++] = alpha_val >> 6; | |
521 | else | |
522 | for (i = 0; i < val; i++) | |
523 | dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); | |
524 | } while (idx < num_coeffs); | |
525 | } | |
526 | ||
527 | /** | |
528 | * Decode alpha slice plane. | |
529 | */ | |
530 | static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td, | |
531 | const uint8_t *buf, int data_size, | |
532 | uint16_t *out_ptr, int linesize, | |
533 | int mbs_per_slice) | |
534 | { | |
535 | GetBitContext gb; | |
536 | int i; | |
537 | uint16_t *block_ptr; | |
538 | ||
539 | memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks)); | |
540 | ||
541 | init_get_bits(&gb, buf, data_size << 3); | |
542 | ||
543 | if (ctx->alpha_info == 2) | |
544 | unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16); | |
545 | else | |
546 | unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8); | |
547 | ||
548 | block_ptr = td->blocks; | |
549 | ||
550 | for (i = 0; i < 16; i++) { | |
551 | memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr)); | |
552 | out_ptr += linesize >> 1; | |
553 | block_ptr += 16 * mbs_per_slice; | |
554 | } | |
555 | } | |
556 | ||
557 | static int decode_slice(AVCodecContext *avctx, void *tdata) | |
558 | { | |
559 | ProresThreadData *td = tdata; | |
560 | ProresContext *ctx = avctx->priv_data; | |
561 | int mb_x_pos = td->x_pos; | |
562 | int mb_y_pos = td->y_pos; | |
563 | int pic_num = ctx->pic_num; | |
564 | int slice_num = td->slice_num; | |
565 | int mbs_per_slice = td->slice_width; | |
566 | const uint8_t *buf; | |
567 | uint8_t *y_data, *u_data, *v_data, *a_data; | |
568 | AVFrame *pic = ctx->frame; | |
569 | int i, sf, slice_width_factor; | |
570 | int slice_data_size, hdr_size; | |
571 | int y_data_size, u_data_size, v_data_size, a_data_size; | |
572 | int y_linesize, u_linesize, v_linesize, a_linesize; | |
573 | int coff[4]; | |
574 | int ret; | |
575 | ||
576 | buf = ctx->slice_data[slice_num].index; | |
577 | slice_data_size = ctx->slice_data[slice_num + 1].index - buf; | |
578 | ||
579 | slice_width_factor = av_log2(mbs_per_slice); | |
580 | ||
581 | y_data = pic->data[0]; | |
582 | u_data = pic->data[1]; | |
583 | v_data = pic->data[2]; | |
584 | a_data = pic->data[3]; | |
585 | y_linesize = pic->linesize[0]; | |
586 | u_linesize = pic->linesize[1]; | |
587 | v_linesize = pic->linesize[2]; | |
588 | a_linesize = pic->linesize[3]; | |
589 | ||
590 | if (pic->interlaced_frame) { | |
591 | if (!(pic_num ^ pic->top_field_first)) { | |
592 | y_data += y_linesize; | |
593 | u_data += u_linesize; | |
594 | v_data += v_linesize; | |
595 | if (a_data) | |
596 | a_data += a_linesize; | |
597 | } | |
598 | y_linesize <<= 1; | |
599 | u_linesize <<= 1; | |
600 | v_linesize <<= 1; | |
601 | a_linesize <<= 1; | |
602 | } | |
603 | y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5); | |
604 | u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor); | |
605 | v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor); | |
606 | if (a_data) | |
607 | a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5); | |
608 | ||
609 | if (slice_data_size < 6) { | |
610 | av_log(avctx, AV_LOG_ERROR, "slice data too small\n"); | |
611 | return AVERROR_INVALIDDATA; | |
612 | } | |
613 | ||
614 | /* parse slice header */ | |
615 | hdr_size = buf[0] >> 3; | |
616 | coff[0] = hdr_size; | |
617 | y_data_size = AV_RB16(buf + 2); | |
618 | coff[1] = coff[0] + y_data_size; | |
619 | u_data_size = AV_RB16(buf + 4); | |
620 | coff[2] = coff[1] + u_data_size; | |
621 | v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2]; | |
622 | coff[3] = coff[2] + v_data_size; | |
623 | a_data_size = ctx->alpha_info ? slice_data_size - coff[3] : 0; | |
624 | ||
625 | /* if V or alpha component size is negative that means that previous | |
626 | component sizes are too large */ | |
627 | if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) { | |
628 | av_log(avctx, AV_LOG_ERROR, "invalid data size\n"); | |
629 | return AVERROR_INVALIDDATA; | |
630 | } | |
631 | ||
632 | sf = av_clip(buf[1], 1, 224); | |
633 | sf = sf > 128 ? (sf - 96) << 2 : sf; | |
634 | ||
635 | /* scale quantization matrixes according with slice's scale factor */ | |
636 | /* TODO: this can be SIMD-optimized a lot */ | |
637 | if (ctx->qmat_changed || sf != td->prev_slice_sf) { | |
638 | td->prev_slice_sf = sf; | |
639 | for (i = 0; i < 64; i++) { | |
640 | td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_luma[i] * sf; | |
641 | td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf; | |
642 | } | |
643 | } | |
644 | ||
645 | /* decode luma plane */ | |
646 | ret = decode_slice_plane(ctx, td, buf + coff[0], y_data_size, | |
647 | (uint16_t*) y_data, y_linesize, | |
648 | mbs_per_slice, 4, slice_width_factor + 2, | |
649 | td->qmat_luma_scaled, 0); | |
650 | ||
651 | if (ret < 0) | |
652 | return ret; | |
653 | ||
654 | /* decode U chroma plane */ | |
655 | ret = decode_slice_plane(ctx, td, buf + coff[1], u_data_size, | |
656 | (uint16_t*) u_data, u_linesize, | |
657 | mbs_per_slice, ctx->num_chroma_blocks, | |
658 | slice_width_factor + ctx->chroma_factor - 1, | |
659 | td->qmat_chroma_scaled, 1); | |
660 | if (ret < 0) | |
661 | return ret; | |
662 | ||
663 | /* decode V chroma plane */ | |
664 | ret = decode_slice_plane(ctx, td, buf + coff[2], v_data_size, | |
665 | (uint16_t*) v_data, v_linesize, | |
666 | mbs_per_slice, ctx->num_chroma_blocks, | |
667 | slice_width_factor + ctx->chroma_factor - 1, | |
668 | td->qmat_chroma_scaled, 1); | |
669 | if (ret < 0) | |
670 | return ret; | |
671 | ||
672 | /* decode alpha plane if available */ | |
673 | if (a_data && a_data_size) | |
674 | decode_alpha_plane(ctx, td, buf + coff[3], a_data_size, | |
675 | (uint16_t*) a_data, a_linesize, | |
676 | mbs_per_slice); | |
677 | ||
678 | return 0; | |
679 | } | |
680 | ||
681 | ||
682 | static int decode_picture(ProresContext *ctx, int pic_num, | |
683 | AVCodecContext *avctx) | |
684 | { | |
685 | int slice_num, slice_width, x_pos, y_pos; | |
686 | ||
687 | slice_num = 0; | |
688 | ||
689 | ctx->pic_num = pic_num; | |
690 | for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) { | |
691 | slice_width = 1 << ctx->slice_width_factor; | |
692 | ||
693 | for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width; | |
694 | x_pos += slice_width) { | |
695 | while (ctx->num_x_mbs - x_pos < slice_width) | |
696 | slice_width >>= 1; | |
697 | ||
698 | ctx->slice_data[slice_num].slice_num = slice_num; | |
699 | ctx->slice_data[slice_num].x_pos = x_pos; | |
700 | ctx->slice_data[slice_num].y_pos = y_pos; | |
701 | ctx->slice_data[slice_num].slice_width = slice_width; | |
702 | ||
703 | slice_num++; | |
704 | } | |
705 | } | |
706 | ||
707 | return avctx->execute(avctx, decode_slice, | |
708 | ctx->slice_data, NULL, slice_num, | |
709 | sizeof(ctx->slice_data[0])); | |
710 | } | |
711 | ||
712 | ||
713 | #define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes) | |
714 | ||
715 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, | |
716 | AVPacket *avpkt) | |
717 | { | |
718 | ProresContext *ctx = avctx->priv_data; | |
719 | const uint8_t *buf = avpkt->data; | |
720 | int buf_size = avpkt->size; | |
721 | int frame_hdr_size, pic_num, pic_data_size; | |
722 | ||
723 | ctx->frame = data; | |
724 | ctx->frame->pict_type = AV_PICTURE_TYPE_I; | |
725 | ctx->frame->key_frame = 1; | |
726 | ||
727 | /* check frame atom container */ | |
728 | if (buf_size < 28 || buf_size < AV_RB32(buf) || | |
729 | AV_RB32(buf + 4) != FRAME_ID) { | |
730 | av_log(avctx, AV_LOG_ERROR, "invalid frame\n"); | |
731 | return AVERROR_INVALIDDATA; | |
732 | } | |
733 | ||
734 | MOVE_DATA_PTR(8); | |
735 | ||
736 | frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); | |
737 | if (frame_hdr_size < 0) | |
738 | return AVERROR_INVALIDDATA; | |
739 | ||
740 | MOVE_DATA_PTR(frame_hdr_size); | |
741 | ||
742 | if (ff_get_buffer(avctx, ctx->frame, 0) < 0) | |
743 | return -1; | |
744 | ||
745 | for (pic_num = 0; ctx->frame->interlaced_frame - pic_num + 1; pic_num++) { | |
746 | pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx); | |
747 | if (pic_data_size < 0) | |
748 | return AVERROR_INVALIDDATA; | |
749 | ||
750 | if (decode_picture(ctx, pic_num, avctx)) | |
751 | return -1; | |
752 | ||
753 | MOVE_DATA_PTR(pic_data_size); | |
754 | } | |
755 | ||
756 | ctx->frame = NULL; | |
757 | *got_frame = 1; | |
758 | ||
759 | return avpkt->size; | |
760 | } | |
761 | ||
762 | ||
763 | static av_cold int decode_close(AVCodecContext *avctx) | |
764 | { | |
765 | ProresContext *ctx = avctx->priv_data; | |
766 | ||
767 | av_freep(&ctx->slice_data); | |
768 | ||
769 | return 0; | |
770 | } | |
771 | ||
772 | ||
773 | AVCodec ff_prores_lgpl_decoder = { | |
774 | .name = "prores_lgpl", | |
775 | .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), | |
776 | .type = AVMEDIA_TYPE_VIDEO, | |
777 | .id = AV_CODEC_ID_PRORES, | |
778 | .priv_data_size = sizeof(ProresContext), | |
779 | .init = decode_init, | |
780 | .close = decode_close, | |
781 | .decode = decode_frame, | |
782 | .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, | |
783 | }; |