GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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 "libavutil/internal.h" |
||
32 |
#include "libavutil/mem_internal.h" |
||
33 |
|||
34 |
#include "avcodec.h" |
||
35 |
#include "get_bits.h" |
||
36 |
#include "idctdsp.h" |
||
37 |
#include "internal.h" |
||
38 |
#include "profiles.h" |
||
39 |
#include "simple_idct.h" |
||
40 |
#include "proresdec.h" |
||
41 |
#include "proresdata.h" |
||
42 |
#include "thread.h" |
||
43 |
|||
44 |
2254 |
static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) |
|
45 |
{ |
||
46 |
int i; |
||
47 |
✓✓ | 146510 |
for (i = 0; i < 64; i++) |
48 |
144256 |
dst[i] = permutation[src[i]]; |
|
49 |
2254 |
} |
|
50 |
|||
51 |
#define ALPHA_SHIFT_16_TO_10(alpha_val) (alpha_val >> 6) |
||
52 |
#define ALPHA_SHIFT_8_TO_10(alpha_val) ((alpha_val << 2) | (alpha_val >> 6)) |
||
53 |
#define ALPHA_SHIFT_16_TO_12(alpha_val) (alpha_val >> 4) |
||
54 |
#define ALPHA_SHIFT_8_TO_12(alpha_val) ((alpha_val << 4) | (alpha_val >> 4)) |
||
55 |
|||
56 |
5100 |
static void inline unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, |
|
57 |
const int num_bits, const int decode_precision) { |
||
58 |
5100 |
const int mask = (1 << num_bits) - 1; |
|
59 |
int i, idx, val, alpha_val; |
||
60 |
|||
61 |
5100 |
idx = 0; |
|
62 |
5100 |
alpha_val = mask; |
|
63 |
do { |
||
64 |
do { |
||
65 |
✓✓ | 58400 |
if (get_bits1(gb)) { |
66 |
43404 |
val = get_bits(gb, num_bits); |
|
67 |
} else { |
||
68 |
int sign; |
||
69 |
✓✗ | 14996 |
val = get_bits(gb, num_bits == 16 ? 7 : 4); |
70 |
14996 |
sign = val & 1; |
|
71 |
14996 |
val = (val + 2) >> 1; |
|
72 |
✗✓ | 14996 |
if (sign) |
73 |
val = -val; |
||
74 |
} |
||
75 |
58400 |
alpha_val = (alpha_val + val) & mask; |
|
76 |
✓✗ | 58400 |
if (num_bits == 16) { |
77 |
✗✓ | 58400 |
if (decode_precision == 10) { |
78 |
dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val); |
||
79 |
} else { /* 12b */ |
||
80 |
58400 |
dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val); |
|
81 |
} |
||
82 |
} else { |
||
83 |
if (decode_precision == 10) { |
||
84 |
dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val); |
||
85 |
} else { /* 12b */ |
||
86 |
dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val); |
||
87 |
} |
||
88 |
} |
||
89 |
✓✓ | 58400 |
if (idx >= num_coeffs) |
90 |
36 |
break; |
|
91 |
✓✓✓✓ |
58364 |
} while (get_bits_left(gb)>0 && get_bits1(gb)); |
92 |
37552 |
val = get_bits(gb, 4); |
|
93 |
✓✓ | 37552 |
if (!val) |
94 |
35779 |
val = get_bits(gb, 11); |
|
95 |
✓✓ | 37552 |
if (idx + val > num_coeffs) |
96 |
140 |
val = num_coeffs - idx; |
|
97 |
✓✗ | 37552 |
if (num_bits == 16) { |
98 |
✓✓ | 10423952 |
for (i = 0; i < val; i++) { |
99 |
✗✓ | 10386400 |
if (decode_precision == 10) { |
100 |
dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val); |
||
101 |
} else { /* 12b */ |
||
102 |
10386400 |
dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val); |
|
103 |
} |
||
104 |
} |
||
105 |
} else { |
||
106 |
for (i = 0; i < val; i++) { |
||
107 |
if (decode_precision == 10) { |
||
108 |
dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val); |
||
109 |
} else { /* 12b */ |
||
110 |
dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val); |
||
111 |
} |
||
112 |
} |
||
113 |
} |
||
114 |
✓✓ | 37552 |
} while (idx < num_coeffs); |
115 |
5100 |
} |
|
116 |
|||
117 |
static void unpack_alpha_10(GetBitContext *gb, uint16_t *dst, int num_coeffs, |
||
118 |
const int num_bits) |
||
119 |
{ |
||
120 |
if (num_bits == 16) { |
||
121 |
unpack_alpha(gb, dst, num_coeffs, 16, 10); |
||
122 |
} else { /* 8 bits alpha */ |
||
123 |
unpack_alpha(gb, dst, num_coeffs, 8, 10); |
||
124 |
} |
||
125 |
} |
||
126 |
|||
127 |
5100 |
static void unpack_alpha_12(GetBitContext *gb, uint16_t *dst, int num_coeffs, |
|
128 |
const int num_bits) |
||
129 |
{ |
||
130 |
✓✗ | 5100 |
if (num_bits == 16) { |
131 |
5100 |
unpack_alpha(gb, dst, num_coeffs, 16, 12); |
|
132 |
} else { /* 8 bits alpha */ |
||
133 |
unpack_alpha(gb, dst, num_coeffs, 8, 12); |
||
134 |
} |
||
135 |
5100 |
} |
|
136 |
|||
137 |
69 |
static av_cold int decode_init(AVCodecContext *avctx) |
|
138 |
{ |
||
139 |
69 |
int ret = 0; |
|
140 |
69 |
ProresContext *ctx = avctx->priv_data; |
|
141 |
uint8_t idct_permutation[64]; |
||
142 |
|||
143 |
69 |
avctx->bits_per_raw_sample = 10; |
|
144 |
|||
145 |
✓✓✓✓ ✓✗✗ |
69 |
switch (avctx->codec_tag) { |
146 |
10 |
case MKTAG('a','p','c','o'): |
|
147 |
10 |
avctx->profile = FF_PROFILE_PRORES_PROXY; |
|
148 |
10 |
break; |
|
149 |
2 |
case MKTAG('a','p','c','s'): |
|
150 |
2 |
avctx->profile = FF_PROFILE_PRORES_LT; |
|
151 |
2 |
break; |
|
152 |
21 |
case MKTAG('a','p','c','n'): |
|
153 |
21 |
avctx->profile = FF_PROFILE_PRORES_STANDARD; |
|
154 |
21 |
break; |
|
155 |
12 |
case MKTAG('a','p','c','h'): |
|
156 |
12 |
avctx->profile = FF_PROFILE_PRORES_HQ; |
|
157 |
12 |
break; |
|
158 |
24 |
case MKTAG('a','p','4','h'): |
|
159 |
24 |
avctx->profile = FF_PROFILE_PRORES_4444; |
|
160 |
24 |
avctx->bits_per_raw_sample = 12; |
|
161 |
24 |
break; |
|
162 |
case MKTAG('a','p','4','x'): |
||
163 |
avctx->profile = FF_PROFILE_PRORES_XQ; |
||
164 |
avctx->bits_per_raw_sample = 12; |
||
165 |
break; |
||
166 |
default: |
||
167 |
avctx->profile = FF_PROFILE_UNKNOWN; |
||
168 |
av_log(avctx, AV_LOG_WARNING, "Unknown prores profile %d\n", avctx->codec_tag); |
||
169 |
} |
||
170 |
|||
171 |
✓✓ | 69 |
if (avctx->bits_per_raw_sample == 10) { |
172 |
45 |
av_log(avctx, AV_LOG_DEBUG, "Auto bitdepth precision. Use 10b decoding based on codec tag.\n"); |
|
173 |
} else { /* 12b */ |
||
174 |
24 |
av_log(avctx, AV_LOG_DEBUG, "Auto bitdepth precision. Use 12b decoding based on codec tag.\n"); |
|
175 |
} |
||
176 |
|||
177 |
69 |
ff_blockdsp_init(&ctx->bdsp, avctx); |
|
178 |
69 |
ret = ff_proresdsp_init(&ctx->prodsp, avctx); |
|
179 |
✗✓ | 69 |
if (ret < 0) { |
180 |
av_log(avctx, AV_LOG_ERROR, "Fail to init proresdsp for bits per raw sample %d\n", avctx->bits_per_raw_sample); |
||
181 |
return ret; |
||
182 |
} |
||
183 |
|||
184 |
69 |
ff_init_scantable_permutation(idct_permutation, |
|
185 |
69 |
ctx->prodsp.idct_permutation_type); |
|
186 |
|||
187 |
69 |
permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation); |
|
188 |
69 |
permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation); |
|
189 |
|||
190 |
✓✓ | 69 |
if (avctx->bits_per_raw_sample == 10){ |
191 |
45 |
ctx->unpack_alpha = unpack_alpha_10; |
|
192 |
✓✗ | 24 |
} else if (avctx->bits_per_raw_sample == 12){ |
193 |
24 |
ctx->unpack_alpha = unpack_alpha_12; |
|
194 |
} else { |
||
195 |
av_log(avctx, AV_LOG_ERROR, "Fail to set unpack_alpha for bits per raw sample %d\n", avctx->bits_per_raw_sample); |
||
196 |
return AVERROR_BUG; |
||
197 |
} |
||
198 |
69 |
return ret; |
|
199 |
} |
||
200 |
|||
201 |
1058 |
static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, |
|
202 |
const int data_size, AVCodecContext *avctx) |
||
203 |
{ |
||
204 |
int hdr_size, width, height, flags; |
||
205 |
int version; |
||
206 |
const uint8_t *ptr; |
||
207 |
|||
208 |
1058 |
hdr_size = AV_RB16(buf); |
|
209 |
ff_dlog(avctx, "header size %d\n", hdr_size); |
||
210 |
✗✓ | 1058 |
if (hdr_size > data_size) { |
211 |
av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); |
||
212 |
return AVERROR_INVALIDDATA; |
||
213 |
} |
||
214 |
|||
215 |
1058 |
version = AV_RB16(buf + 2); |
|
216 |
ff_dlog(avctx, "%.4s version %d\n", buf+4, version); |
||
217 |
✗✓ | 1058 |
if (version > 1) { |
218 |
av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); |
||
219 |
return AVERROR_PATCHWELCOME; |
||
220 |
} |
||
221 |
|||
222 |
1058 |
width = AV_RB16(buf + 8); |
|
223 |
1058 |
height = AV_RB16(buf + 10); |
|
224 |
|||
225 |
✓✗✗✓ |
1058 |
if (width != avctx->width || height != avctx->height) { |
226 |
int ret; |
||
227 |
|||
228 |
av_log(avctx, AV_LOG_WARNING, "picture resolution change: %dx%d -> %dx%d\n", |
||
229 |
avctx->width, avctx->height, width, height); |
||
230 |
if ((ret = ff_set_dimensions(avctx, width, height)) < 0) |
||
231 |
return ret; |
||
232 |
} |
||
233 |
|||
234 |
1058 |
ctx->frame_type = (buf[12] >> 2) & 3; |
|
235 |
1058 |
ctx->alpha_info = buf[17] & 0xf; |
|
236 |
|||
237 |
✗✓ | 1058 |
if (ctx->alpha_info > 2) { |
238 |
av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); |
||
239 |
return AVERROR_INVALIDDATA; |
||
240 |
} |
||
241 |
✓✓ | 1058 |
if (avctx->skip_alpha) ctx->alpha_info = 0; |
242 |
|||
243 |
ff_dlog(avctx, "frame type %d\n", ctx->frame_type); |
||
244 |
|||
245 |
✓✓ | 1058 |
if (ctx->frame_type == 0) { |
246 |
630 |
ctx->scan = ctx->progressive_scan; // permuted |
|
247 |
} else { |
||
248 |
428 |
ctx->scan = ctx->interlaced_scan; // permuted |
|
249 |
428 |
ctx->frame->interlaced_frame = 1; |
|
250 |
428 |
ctx->frame->top_field_first = ctx->frame_type == 1; |
|
251 |
} |
||
252 |
|||
253 |
✓✓ | 1058 |
if (ctx->alpha_info) { |
254 |
✗✓ | 5 |
if (avctx->bits_per_raw_sample == 10) { |
255 |
avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; |
||
256 |
} else { /* 12b */ |
||
257 |
✓✗ | 5 |
avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P12 : AV_PIX_FMT_YUVA422P12; |
258 |
} |
||
259 |
} else { |
||
260 |
✓✓ | 1053 |
if (avctx->bits_per_raw_sample == 10) { |
261 |
✗✓ | 640 |
avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; |
262 |
} else { /* 12b */ |
||
263 |
✓✗ | 413 |
avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P12 : AV_PIX_FMT_YUV422P12; |
264 |
} |
||
265 |
} |
||
266 |
|||
267 |
1058 |
avctx->color_primaries = buf[14]; |
|
268 |
1058 |
avctx->color_trc = buf[15]; |
|
269 |
1058 |
avctx->colorspace = buf[16]; |
|
270 |
1058 |
avctx->color_range = AVCOL_RANGE_MPEG; |
|
271 |
|||
272 |
1058 |
ptr = buf + 20; |
|
273 |
1058 |
flags = buf[19]; |
|
274 |
ff_dlog(avctx, "flags %x\n", flags); |
||
275 |
|||
276 |
✓✗ | 1058 |
if (flags & 2) { |
277 |
✗✓ | 1058 |
if(buf + data_size - ptr < 64) { |
278 |
av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); |
||
279 |
return AVERROR_INVALIDDATA; |
||
280 |
} |
||
281 |
1058 |
permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); |
|
282 |
1058 |
ptr += 64; |
|
283 |
} else { |
||
284 |
memset(ctx->qmat_luma, 4, 64); |
||
285 |
} |
||
286 |
|||
287 |
✓✗ | 1058 |
if (flags & 1) { |
288 |
✗✓ | 1058 |
if(buf + data_size - ptr < 64) { |
289 |
av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); |
||
290 |
return AVERROR_INVALIDDATA; |
||
291 |
} |
||
292 |
1058 |
permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); |
|
293 |
} else { |
||
294 |
memcpy(ctx->qmat_chroma, ctx->qmat_luma, 64); |
||
295 |
} |
||
296 |
|||
297 |
1058 |
return hdr_size; |
|
298 |
} |
||
299 |
|||
300 |
1486 |
static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size) |
|
301 |
{ |
||
302 |
1486 |
ProresContext *ctx = avctx->priv_data; |
|
303 |
int i, hdr_size, slice_count; |
||
304 |
unsigned pic_data_size; |
||
305 |
int log2_slice_mb_width, log2_slice_mb_height; |
||
306 |
int slice_mb_count, mb_x, mb_y; |
||
307 |
const uint8_t *data_ptr, *index_ptr; |
||
308 |
|||
309 |
1486 |
hdr_size = buf[0] >> 3; |
|
310 |
✓✗✗✓ |
1486 |
if (hdr_size < 8 || hdr_size > buf_size) { |
311 |
av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); |
||
312 |
return AVERROR_INVALIDDATA; |
||
313 |
} |
||
314 |
|||
315 |
1486 |
pic_data_size = AV_RB32(buf + 1); |
|
316 |
✗✓ | 1486 |
if (pic_data_size > buf_size) { |
317 |
av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); |
||
318 |
return AVERROR_INVALIDDATA; |
||
319 |
} |
||
320 |
|||
321 |
1486 |
log2_slice_mb_width = buf[7] >> 4; |
|
322 |
1486 |
log2_slice_mb_height = buf[7] & 0xF; |
|
323 |
✓✗✗✓ |
1486 |
if (log2_slice_mb_width > 3 || log2_slice_mb_height) { |
324 |
av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", |
||
325 |
1 << log2_slice_mb_width, 1 << log2_slice_mb_height); |
||
326 |
return AVERROR_INVALIDDATA; |
||
327 |
} |
||
328 |
|||
329 |
1486 |
ctx->mb_width = (avctx->width + 15) >> 4; |
|
330 |
✓✓ | 1486 |
if (ctx->frame_type) |
331 |
856 |
ctx->mb_height = (avctx->height + 31) >> 5; |
|
332 |
else |
||
333 |
630 |
ctx->mb_height = (avctx->height + 15) >> 4; |
|
334 |
|||
335 |
// QT ignores the written value |
||
336 |
// slice_count = AV_RB16(buf + 5); |
||
337 |
1486 |
slice_count = ctx->mb_height * ((ctx->mb_width >> log2_slice_mb_width) + |
|
338 |
1486 |
av_popcount(ctx->mb_width & (1 << log2_slice_mb_width) - 1)); |
|
339 |
|||
340 |
✓✓✗✓ |
1486 |
if (ctx->slice_count != slice_count || !ctx->slices) { |
341 |
67 |
av_freep(&ctx->slices); |
|
342 |
67 |
ctx->slice_count = 0; |
|
343 |
67 |
ctx->slices = av_mallocz_array(slice_count, sizeof(*ctx->slices)); |
|
344 |
✗✓ | 67 |
if (!ctx->slices) |
345 |
return AVERROR(ENOMEM); |
||
346 |
67 |
ctx->slice_count = slice_count; |
|
347 |
} |
||
348 |
|||
349 |
✗✓ | 1486 |
if (!slice_count) |
350 |
return AVERROR(EINVAL); |
||
351 |
|||
352 |
✗✓ | 1486 |
if (hdr_size + slice_count*2 > buf_size) { |
353 |
av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); |
||
354 |
return AVERROR_INVALIDDATA; |
||
355 |
} |
||
356 |
|||
357 |
// parse slice information |
||
358 |
1486 |
index_ptr = buf + hdr_size; |
|
359 |
1486 |
data_ptr = index_ptr + slice_count*2; |
|
360 |
|||
361 |
1486 |
slice_mb_count = 1 << log2_slice_mb_width; |
|
362 |
1486 |
mb_x = 0; |
|
363 |
1486 |
mb_y = 0; |
|
364 |
|||
365 |
✓✓ | 88006 |
for (i = 0; i < slice_count; i++) { |
366 |
86520 |
SliceContext *slice = &ctx->slices[i]; |
|
367 |
|||
368 |
86520 |
slice->data = data_ptr; |
|
369 |
86520 |
data_ptr += AV_RB16(index_ptr + i*2); |
|
370 |
|||
371 |
✓✓ | 117165 |
while (ctx->mb_width - mb_x < slice_mb_count) |
372 |
30645 |
slice_mb_count >>= 1; |
|
373 |
|||
374 |
86520 |
slice->mb_x = mb_x; |
|
375 |
86520 |
slice->mb_y = mb_y; |
|
376 |
86520 |
slice->mb_count = slice_mb_count; |
|
377 |
86520 |
slice->data_size = data_ptr - slice->data; |
|
378 |
|||
379 |
✗✓ | 86520 |
if (slice->data_size < 6) { |
380 |
av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); |
||
381 |
return AVERROR_INVALIDDATA; |
||
382 |
} |
||
383 |
|||
384 |
86520 |
mb_x += slice_mb_count; |
|
385 |
✓✓ | 86520 |
if (mb_x == ctx->mb_width) { |
386 |
16842 |
slice_mb_count = 1 << log2_slice_mb_width; |
|
387 |
16842 |
mb_x = 0; |
|
388 |
16842 |
mb_y++; |
|
389 |
} |
||
390 |
✗✓ | 86520 |
if (data_ptr > buf + buf_size) { |
391 |
av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); |
||
392 |
return AVERROR_INVALIDDATA; |
||
393 |
} |
||
394 |
} |
||
395 |
|||
396 |
✓✗✗✓ |
1486 |
if (mb_x || mb_y != ctx->mb_height) { |
397 |
av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n", |
||
398 |
mb_y, ctx->mb_height); |
||
399 |
return AVERROR_INVALIDDATA; |
||
400 |
} |
||
401 |
|||
402 |
1486 |
return pic_data_size; |
|
403 |
} |
||
404 |
|||
405 |
#define DECODE_CODEWORD(val, codebook, SKIP) \ |
||
406 |
do { \ |
||
407 |
unsigned int rice_order, exp_order, switch_bits; \ |
||
408 |
unsigned int q, buf, bits; \ |
||
409 |
\ |
||
410 |
UPDATE_CACHE(re, gb); \ |
||
411 |
buf = GET_CACHE(re, gb); \ |
||
412 |
\ |
||
413 |
/* number of bits to switch between rice and exp golomb */ \ |
||
414 |
switch_bits = codebook & 3; \ |
||
415 |
rice_order = codebook >> 5; \ |
||
416 |
exp_order = (codebook >> 2) & 7; \ |
||
417 |
\ |
||
418 |
q = 31 - av_log2(buf); \ |
||
419 |
\ |
||
420 |
if (q > switch_bits) { /* exp golomb */ \ |
||
421 |
bits = exp_order - switch_bits + (q<<1); \ |
||
422 |
if (bits > FFMIN(MIN_CACHE_BITS, 31)) \ |
||
423 |
return AVERROR_INVALIDDATA; \ |
||
424 |
val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ |
||
425 |
((switch_bits + 1) << rice_order); \ |
||
426 |
SKIP(re, gb, bits); \ |
||
427 |
} else if (rice_order) { \ |
||
428 |
SKIP_BITS(re, gb, q+1); \ |
||
429 |
val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ |
||
430 |
SKIP(re, gb, rice_order); \ |
||
431 |
} else { \ |
||
432 |
val = q; \ |
||
433 |
SKIP(re, gb, q+1); \ |
||
434 |
} \ |
||
435 |
} while (0) |
||
436 |
|||
437 |
#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1))) |
||
438 |
|||
439 |
#define FIRST_DC_CB 0xB8 |
||
440 |
|||
441 |
static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; |
||
442 |
|||
443 |
258048 |
static av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, |
|
444 |
int blocks_per_slice) |
||
445 |
{ |
||
446 |
int16_t prev_dc; |
||
447 |
int code, i, sign; |
||
448 |
|||
449 |
258048 |
OPEN_READER(re, gb); |
|
450 |
|||
451 |
✓✓✗✓ ✓✗ |
258048 |
DECODE_CODEWORD(code, FIRST_DC_CB, LAST_SKIP_BITS); |
452 |
258048 |
prev_dc = TOSIGNED(code); |
|
453 |
258048 |
out[0] = prev_dc; |
|
454 |
|||
455 |
258048 |
out += 64; // dc coeff for the next block |
|
456 |
|||
457 |
258048 |
code = 5; |
|
458 |
258048 |
sign = 0; |
|
459 |
✓✓ | 5126676 |
for (i = 1; i < blocks_per_slice; i++, out += 64) { |
460 |
✓✓✗✓ ✓✓ |
4868628 |
DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)], LAST_SKIP_BITS); |
461 |
✓✓ | 4868628 |
if(code) sign ^= -(code & 1); |
462 |
1826581 |
else sign = 0; |
|
463 |
4868628 |
prev_dc += (((code + 1) >> 1) ^ sign) - sign; |
|
464 |
4868628 |
out[0] = prev_dc; |
|
465 |
} |
||
466 |
258048 |
CLOSE_READER(re, gb); |
|
467 |
258048 |
return 0; |
|
468 |
} |
||
469 |
|||
470 |
// adaptive codebook switching lut according to previous run/level values |
||
471 |
static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; |
||
472 |
static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; |
||
473 |
|||
474 |
258048 |
static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, |
|
475 |
int16_t *out, int blocks_per_slice) |
||
476 |
{ |
||
477 |
258048 |
ProresContext *ctx = avctx->priv_data; |
|
478 |
int block_mask, sign; |
||
479 |
unsigned pos, run, level; |
||
480 |
int max_coeffs, i, bits_left; |
||
481 |
258048 |
int log2_block_count = av_log2(blocks_per_slice); |
|
482 |
|||
483 |
258048 |
OPEN_READER(re, gb); |
|
484 |
258048 |
UPDATE_CACHE(re, gb); \ |
|
485 |
258048 |
run = 4; |
|
486 |
258048 |
level = 2; |
|
487 |
|||
488 |
258048 |
max_coeffs = 64 << log2_block_count; |
|
489 |
258048 |
block_mask = blocks_per_slice - 1; |
|
490 |
|||
491 |
258048 |
for (pos = block_mask;;) { |
|
492 |
84797339 |
bits_left = gb->size_in_bits - re_index; |
|
493 |
✓✓✓✓ ✓✓ |
84797339 |
if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) |
494 |
break; |
||
495 |
|||
496 |
✓✓✗✓ ✓✓ |
84539291 |
DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)], LAST_SKIP_BITS); |
497 |
84539291 |
pos += run + 1; |
|
498 |
✗✓ | 84539291 |
if (pos >= max_coeffs) { |
499 |
av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); |
||
500 |
return AVERROR_INVALIDDATA; |
||
501 |
} |
||
502 |
|||
503 |
✓✓✗✓ ✓✓ |
84539291 |
DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)], SKIP_BITS); |
504 |
84539291 |
level += 1; |
|
505 |
|||
506 |
84539291 |
i = pos >> log2_block_count; |
|
507 |
|||
508 |
84539291 |
sign = SHOW_SBITS(re, gb, 1); |
|
509 |
84539291 |
SKIP_BITS(re, gb, 1); |
|
510 |
84539291 |
out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign); |
|
511 |
} |
||
512 |
|||
513 |
258048 |
CLOSE_READER(re, gb); |
|
514 |
258048 |
return 0; |
|
515 |
} |
||
516 |
|||
517 |
86520 |
static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, |
|
518 |
uint16_t *dst, int dst_stride, |
||
519 |
const uint8_t *buf, unsigned buf_size, |
||
520 |
const int16_t *qmat) |
||
521 |
{ |
||
522 |
86520 |
ProresContext *ctx = avctx->priv_data; |
|
523 |
86520 |
LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); |
|
524 |
int16_t *block; |
||
525 |
GetBitContext gb; |
||
526 |
86520 |
int i, blocks_per_slice = slice->mb_count<<2; |
|
527 |
int ret; |
||
528 |
|||
529 |
✓✓ | 2251884 |
for (i = 0; i < blocks_per_slice; i++) |
530 |
2165364 |
ctx->bdsp.clear_block(blocks+(i<<6)); |
|
531 |
|||
532 |
86520 |
init_get_bits(&gb, buf, buf_size << 3); |
|
533 |
|||
534 |
✗✓ | 86520 |
if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) |
535 |
return ret; |
||
536 |
✗✓ | 86520 |
if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) |
537 |
return ret; |
||
538 |
|||
539 |
86520 |
block = blocks; |
|
540 |
✓✓ | 627861 |
for (i = 0; i < slice->mb_count; i++) { |
541 |
541341 |
ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); |
|
542 |
541341 |
ctx->prodsp.idct_put(dst +8, dst_stride, block+(1<<6), qmat); |
|
543 |
541341 |
ctx->prodsp.idct_put(dst+4*dst_stride , dst_stride, block+(2<<6), qmat); |
|
544 |
541341 |
ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat); |
|
545 |
541341 |
block += 4*64; |
|
546 |
541341 |
dst += 16; |
|
547 |
} |
||
548 |
86520 |
return 0; |
|
549 |
} |
||
550 |
|||
551 |
171528 |
static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, |
|
552 |
uint16_t *dst, int dst_stride, |
||
553 |
const uint8_t *buf, unsigned buf_size, |
||
554 |
const int16_t *qmat, int log2_blocks_per_mb) |
||
555 |
{ |
||
556 |
171528 |
ProresContext *ctx = avctx->priv_data; |
|
557 |
171528 |
LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); |
|
558 |
int16_t *block; |
||
559 |
GetBitContext gb; |
||
560 |
171528 |
int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; |
|
561 |
int ret; |
||
562 |
|||
563 |
✓✓ | 3132840 |
for (i = 0; i < blocks_per_slice; i++) |
564 |
2961312 |
ctx->bdsp.clear_block(blocks+(i<<6)); |
|
565 |
|||
566 |
171528 |
init_get_bits(&gb, buf, buf_size << 3); |
|
567 |
|||
568 |
✗✓ | 171528 |
if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) |
569 |
return ret; |
||
570 |
✗✓ | 171528 |
if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) |
571 |
return ret; |
||
572 |
|||
573 |
171528 |
block = blocks; |
|
574 |
✓✓ | 1244490 |
for (i = 0; i < slice->mb_count; i++) { |
575 |
✓✓ | 2553618 |
for (j = 0; j < log2_blocks_per_mb; j++) { |
576 |
1480656 |
ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); |
|
577 |
1480656 |
ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat); |
|
578 |
1480656 |
block += 2*64; |
|
579 |
1480656 |
dst += 8; |
|
580 |
} |
||
581 |
} |
||
582 |
171528 |
return 0; |
|
583 |
} |
||
584 |
|||
585 |
/** |
||
586 |
* Decode alpha slice plane. |
||
587 |
*/ |
||
588 |
5100 |
static void decode_slice_alpha(ProresContext *ctx, |
|
589 |
uint16_t *dst, int dst_stride, |
||
590 |
const uint8_t *buf, int buf_size, |
||
591 |
int blocks_per_slice) |
||
592 |
{ |
||
593 |
GetBitContext gb; |
||
594 |
int i; |
||
595 |
5100 |
LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); |
|
596 |
int16_t *block; |
||
597 |
|||
598 |
✓✓ | 168300 |
for (i = 0; i < blocks_per_slice<<2; i++) |
599 |
163200 |
ctx->bdsp.clear_block(blocks+(i<<6)); |
|
600 |
|||
601 |
5100 |
init_get_bits(&gb, buf, buf_size << 3); |
|
602 |
|||
603 |
✓✗ | 5100 |
if (ctx->alpha_info == 2) { |
604 |
5100 |
ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16); |
|
605 |
} else { |
||
606 |
ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8); |
||
607 |
} |
||
608 |
|||
609 |
5100 |
block = blocks; |
|
610 |
|||
611 |
✓✓ | 86700 |
for (i = 0; i < 16; i++) { |
612 |
81600 |
memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst)); |
|
613 |
81600 |
dst += dst_stride >> 1; |
|
614 |
81600 |
block += 16 * blocks_per_slice; |
|
615 |
} |
||
616 |
5100 |
} |
|
617 |
|||
618 |
86520 |
static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) |
|
619 |
{ |
||
620 |
86520 |
ProresContext *ctx = avctx->priv_data; |
|
621 |
86520 |
SliceContext *slice = &ctx->slices[jobnr]; |
|
622 |
86520 |
const uint8_t *buf = slice->data; |
|
623 |
86520 |
AVFrame *pic = ctx->frame; |
|
624 |
int i, hdr_size, qscale, log2_chroma_blocks_per_mb; |
||
625 |
int luma_stride, chroma_stride; |
||
626 |
int y_data_size, u_data_size, v_data_size, a_data_size; |
||
627 |
uint8_t *dest_y, *dest_u, *dest_v, *dest_a; |
||
628 |
86520 |
LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]); |
|
629 |
86520 |
LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]); |
|
630 |
int mb_x_shift; |
||
631 |
int ret; |
||
632 |
uint16_t val_no_chroma; |
||
633 |
|||
634 |
86520 |
slice->ret = -1; |
|
635 |
//av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", |
||
636 |
// jobnr, slice->mb_count, slice->mb_x, slice->mb_y); |
||
637 |
|||
638 |
// slice header |
||
639 |
86520 |
hdr_size = buf[0] >> 3; |
|
640 |
86520 |
qscale = av_clip(buf[1], 1, 224); |
|
641 |
✗✓ | 86520 |
qscale = qscale > 128 ? qscale - 96 << 2: qscale; |
642 |
86520 |
y_data_size = AV_RB16(buf + 2); |
|
643 |
86520 |
u_data_size = AV_RB16(buf + 4); |
|
644 |
86520 |
v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; |
|
645 |
✓✓ | 86520 |
if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); |
646 |
86520 |
a_data_size = slice->data_size - y_data_size - u_data_size - |
|
647 |
86520 |
v_data_size - hdr_size; |
|
648 |
|||
649 |
✓✗✓✗ ✓✗ |
86520 |
if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0 |
650 |
✗✓ | 86520 |
|| hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){ |
651 |
av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); |
||
652 |
return AVERROR_INVALIDDATA; |
||
653 |
} |
||
654 |
|||
655 |
86520 |
buf += hdr_size; |
|
656 |
|||
657 |
✓✓ | 5623800 |
for (i = 0; i < 64; i++) { |
658 |
5537280 |
qmat_luma_scaled [i] = ctx->qmat_luma [i] * qscale; |
|
659 |
5537280 |
qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; |
|
660 |
} |
||
661 |
|||
662 |
✓✓ | 86520 |
if (ctx->frame_type == 0) { |
663 |
43272 |
luma_stride = pic->linesize[0]; |
|
664 |
43272 |
chroma_stride = pic->linesize[1]; |
|
665 |
} else { |
||
666 |
43248 |
luma_stride = pic->linesize[0] << 1; |
|
667 |
43248 |
chroma_stride = pic->linesize[1] << 1; |
|
668 |
} |
||
669 |
|||
670 |
✓✗✓✗ |
86520 |
if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10 || |
671 |
✓✓✓✓ |
86520 |
avctx->pix_fmt == AV_PIX_FMT_YUV444P12 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P12) { |
672 |
32946 |
mb_x_shift = 5; |
|
673 |
32946 |
log2_chroma_blocks_per_mb = 2; |
|
674 |
} else { |
||
675 |
53574 |
mb_x_shift = 4; |
|
676 |
53574 |
log2_chroma_blocks_per_mb = 1; |
|
677 |
} |
||
678 |
|||
679 |
86520 |
dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); |
|
680 |
86520 |
dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); |
|
681 |
86520 |
dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); |
|
682 |
86520 |
dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); |
|
683 |
|||
684 |
✓✓✓✓ |
86520 |
if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { |
685 |
21624 |
dest_y += pic->linesize[0]; |
|
686 |
21624 |
dest_u += pic->linesize[1]; |
|
687 |
21624 |
dest_v += pic->linesize[2]; |
|
688 |
21624 |
dest_a += pic->linesize[3]; |
|
689 |
} |
||
690 |
|||
691 |
86520 |
ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, |
|
692 |
buf, y_data_size, qmat_luma_scaled); |
||
693 |
✗✓ | 86520 |
if (ret < 0) |
694 |
return ret; |
||
695 |
|||
696 |
✓✗✓✓ |
86520 |
if (!(avctx->flags & AV_CODEC_FLAG_GRAY) && (u_data_size + v_data_size) > 0) { |
697 |
85764 |
ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride, |
|
698 |
buf + y_data_size, u_data_size, |
||
699 |
qmat_chroma_scaled, log2_chroma_blocks_per_mb); |
||
700 |
✗✓ | 85764 |
if (ret < 0) |
701 |
return ret; |
||
702 |
|||
703 |
85764 |
ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride, |
|
704 |
85764 |
buf + y_data_size + u_data_size, v_data_size, |
|
705 |
qmat_chroma_scaled, log2_chroma_blocks_per_mb); |
||
706 |
✗✓ | 85764 |
if (ret < 0) |
707 |
return ret; |
||
708 |
} |
||
709 |
else { |
||
710 |
756 |
size_t mb_max_x = slice->mb_count << (mb_x_shift - 1); |
|
711 |
size_t i, j; |
||
712 |
✓✗ | 756 |
if (avctx->bits_per_raw_sample == 10) { |
713 |
756 |
val_no_chroma = 511; |
|
714 |
} else { /* 12b */ |
||
715 |
val_no_chroma = 511 * 4; |
||
716 |
} |
||
717 |
✓✓ | 12852 |
for (i = 0; i < 16; ++i) |
718 |
✓✓ | 634176 |
for (j = 0; j < mb_max_x; ++j) { |
719 |
622080 |
*(uint16_t*)(dest_u + (i * chroma_stride) + (j << 1)) = val_no_chroma; |
|
720 |
622080 |
*(uint16_t*)(dest_v + (i * chroma_stride) + (j << 1)) = val_no_chroma; |
|
721 |
} |
||
722 |
} |
||
723 |
|||
724 |
/* decode alpha plane if available */ |
||
725 |
✓✓✓✗ ✓✗ |
86520 |
if (ctx->alpha_info && pic->data[3] && a_data_size) |
726 |
5100 |
decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, |
|
727 |
5100 |
buf + y_data_size + u_data_size + v_data_size, |
|
728 |
5100 |
a_data_size, slice->mb_count); |
|
729 |
|||
730 |
86520 |
slice->ret = 0; |
|
731 |
86520 |
return 0; |
|
732 |
} |
||
733 |
|||
734 |
1486 |
static int decode_picture(AVCodecContext *avctx) |
|
735 |
{ |
||
736 |
1486 |
ProresContext *ctx = avctx->priv_data; |
|
737 |
int i; |
||
738 |
1486 |
int error = 0; |
|
739 |
|||
740 |
1486 |
avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count); |
|
741 |
|||
742 |
✓✓ | 88006 |
for (i = 0; i < ctx->slice_count; i++) |
743 |
86520 |
error += ctx->slices[i].ret < 0; |
|
744 |
|||
745 |
✗✓ | 1486 |
if (error) |
746 |
ctx->frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM; |
||
747 |
✓✗ | 1486 |
if (error < ctx->slice_count) |
748 |
1486 |
return 0; |
|
749 |
|||
750 |
return ctx->slices[0].ret; |
||
751 |
} |
||
752 |
|||
753 |
1058 |
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
754 |
AVPacket *avpkt) |
||
755 |
{ |
||
756 |
1058 |
ProresContext *ctx = avctx->priv_data; |
|
757 |
1058 |
ThreadFrame tframe = { .f = data }; |
|
758 |
1058 |
AVFrame *frame = data; |
|
759 |
1058 |
const uint8_t *buf = avpkt->data; |
|
760 |
1058 |
int buf_size = avpkt->size; |
|
761 |
int frame_hdr_size, pic_size, ret; |
||
762 |
|||
763 |
✓✗✗✓ |
1058 |
if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { |
764 |
av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); |
||
765 |
return AVERROR_INVALIDDATA; |
||
766 |
} |
||
767 |
|||
768 |
1058 |
ctx->frame = frame; |
|
769 |
1058 |
ctx->frame->pict_type = AV_PICTURE_TYPE_I; |
|
770 |
1058 |
ctx->frame->key_frame = 1; |
|
771 |
1058 |
ctx->first_field = 1; |
|
772 |
|||
773 |
1058 |
buf += 8; |
|
774 |
1058 |
buf_size -= 8; |
|
775 |
|||
776 |
1058 |
frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); |
|
777 |
✗✓ | 1058 |
if (frame_hdr_size < 0) |
778 |
return frame_hdr_size; |
||
779 |
|||
780 |
1058 |
buf += frame_hdr_size; |
|
781 |
1058 |
buf_size -= frame_hdr_size; |
|
782 |
|||
783 |
1486 |
decode_picture: |
|
784 |
1486 |
pic_size = decode_picture_header(avctx, buf, buf_size); |
|
785 |
✗✓ | 1486 |
if (pic_size < 0) { |
786 |
av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); |
||
787 |
return pic_size; |
||
788 |
} |
||
789 |
|||
790 |
✓✓ | 1486 |
if (ctx->first_field) |
791 |
✗✓ | 1058 |
if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) |
792 |
return ret; |
||
793 |
|||
794 |
✗✓ | 1486 |
if ((ret = decode_picture(avctx)) < 0) { |
795 |
av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); |
||
796 |
return ret; |
||
797 |
} |
||
798 |
|||
799 |
1486 |
buf += pic_size; |
|
800 |
1486 |
buf_size -= pic_size; |
|
801 |
|||
802 |
✓✓✓✓ ✓✓ |
1486 |
if (ctx->frame_type && buf_size > 0 && ctx->first_field) { |
803 |
428 |
ctx->first_field = 0; |
|
804 |
428 |
goto decode_picture; |
|
805 |
} |
||
806 |
|||
807 |
1058 |
*got_frame = 1; |
|
808 |
|||
809 |
1058 |
return avpkt->size; |
|
810 |
} |
||
811 |
|||
812 |
69 |
static av_cold int decode_close(AVCodecContext *avctx) |
|
813 |
{ |
||
814 |
69 |
ProresContext *ctx = avctx->priv_data; |
|
815 |
|||
816 |
69 |
av_freep(&ctx->slices); |
|
817 |
|||
818 |
69 |
return 0; |
|
819 |
} |
||
820 |
|||
821 |
AVCodec ff_prores_decoder = { |
||
822 |
.name = "prores", |
||
823 |
.long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), |
||
824 |
.type = AVMEDIA_TYPE_VIDEO, |
||
825 |
.id = AV_CODEC_ID_PRORES, |
||
826 |
.priv_data_size = sizeof(ProresContext), |
||
827 |
.init = decode_init, |
||
828 |
.close = decode_close, |
||
829 |
.decode = decode_frame, |
||
830 |
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, |
||
831 |
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), |
||
832 |
}; |
Generated by: GCOVR (Version 4.2) |