blob: 6250536da6168f1514902dfd0e38d066a8b9888f
1 | /* |
2 | * MagicYUV decoder |
3 | * Copyright (c) 2016 Paul B Mahol |
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 | #include <stdlib.h> |
23 | #include <string.h> |
24 | |
25 | #include "libavutil/pixdesc.h" |
26 | #include "libavutil/qsort.h" |
27 | |
28 | #include "avcodec.h" |
29 | #include "bytestream.h" |
30 | #include "get_bits.h" |
31 | #include "huffyuvdsp.h" |
32 | #include "internal.h" |
33 | #include "lossless_videodsp.h" |
34 | #include "thread.h" |
35 | |
36 | typedef struct Slice { |
37 | uint32_t start; |
38 | uint32_t size; |
39 | } Slice; |
40 | |
41 | typedef enum Prediction { |
42 | LEFT = 1, |
43 | GRADIENT, |
44 | MEDIAN, |
45 | } Prediction; |
46 | |
47 | typedef struct HuffEntry { |
48 | uint16_t sym; |
49 | uint8_t len; |
50 | uint32_t code; |
51 | } HuffEntry; |
52 | |
53 | typedef struct MagicYUVContext { |
54 | AVFrame *p; |
55 | int max; |
56 | int slice_height; |
57 | int nb_slices; |
58 | int planes; // number of encoded planes in bitstream |
59 | int decorrelate; // postprocessing work |
60 | int color_matrix; // video color matrix |
61 | int flags; |
62 | int interlaced; // video is interlaced |
63 | uint8_t *buf; // pointer to AVPacket->data |
64 | int hshift[4]; |
65 | int vshift[4]; |
66 | Slice *slices[4]; // slice bitstream positions for each plane |
67 | unsigned int slices_size[4]; // slice sizes for each plane |
68 | uint8_t len[4][1024]; // table of code lengths for each plane |
69 | VLC vlc[4]; // VLC for each plane |
70 | int (*huff_build)(VLC *vlc, uint8_t *len); |
71 | int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, |
72 | int j, int threadnr); |
73 | LLVidDSPContext llviddsp; |
74 | } MagicYUVContext; |
75 | |
76 | static int huff_cmp_len(const void *a, const void *b) |
77 | { |
78 | const HuffEntry *aa = a, *bb = b; |
79 | return (aa->len - bb->len) * 256 + aa->sym - bb->sym; |
80 | } |
81 | |
82 | static int huff_cmp_len10(const void *a, const void *b) |
83 | { |
84 | const HuffEntry *aa = a, *bb = b; |
85 | return (aa->len - bb->len) * 1024 + aa->sym - bb->sym; |
86 | } |
87 | |
88 | static int huff_build10(VLC *vlc, uint8_t *len) |
89 | { |
90 | HuffEntry he[1024]; |
91 | uint32_t codes[1024]; |
92 | uint8_t bits[1024]; |
93 | uint16_t syms[1024]; |
94 | uint32_t code; |
95 | int i; |
96 | |
97 | for (i = 0; i < 1024; i++) { |
98 | he[i].sym = 1023 - i; |
99 | he[i].len = len[i]; |
100 | } |
101 | AV_QSORT(he, 1024, HuffEntry, huff_cmp_len10); |
102 | |
103 | code = 1; |
104 | for (i = 1023; i >= 0; i--) { |
105 | codes[i] = code >> (32 - he[i].len); |
106 | bits[i] = he[i].len; |
107 | syms[i] = he[i].sym; |
108 | code += 0x80000000u >> (he[i].len - 1); |
109 | } |
110 | |
111 | ff_free_vlc(vlc); |
112 | return ff_init_vlc_sparse(vlc, FFMIN(he[1023].len, 12), 1024, |
113 | bits, sizeof(*bits), sizeof(*bits), |
114 | codes, sizeof(*codes), sizeof(*codes), |
115 | syms, sizeof(*syms), sizeof(*syms), 0); |
116 | } |
117 | |
118 | static int huff_build(VLC *vlc, uint8_t *len) |
119 | { |
120 | HuffEntry he[256]; |
121 | uint32_t codes[256]; |
122 | uint8_t bits[256]; |
123 | uint8_t syms[256]; |
124 | uint32_t code; |
125 | int i; |
126 | |
127 | for (i = 0; i < 256; i++) { |
128 | he[i].sym = 255 - i; |
129 | he[i].len = len[i]; |
130 | } |
131 | AV_QSORT(he, 256, HuffEntry, huff_cmp_len); |
132 | |
133 | code = 1; |
134 | for (i = 255; i >= 0; i--) { |
135 | codes[i] = code >> (32 - he[i].len); |
136 | bits[i] = he[i].len; |
137 | syms[i] = he[i].sym; |
138 | code += 0x80000000u >> (he[i].len - 1); |
139 | } |
140 | |
141 | ff_free_vlc(vlc); |
142 | return ff_init_vlc_sparse(vlc, FFMIN(he[255].len, 12), 256, |
143 | bits, sizeof(*bits), sizeof(*bits), |
144 | codes, sizeof(*codes), sizeof(*codes), |
145 | syms, sizeof(*syms), sizeof(*syms), 0); |
146 | } |
147 | |
148 | static void magicyuv_median_pred10(uint16_t *dst, const uint16_t *src1, |
149 | const uint16_t *diff, intptr_t w, |
150 | int *left, int *left_top) |
151 | { |
152 | int i; |
153 | uint16_t l, lt; |
154 | |
155 | l = *left; |
156 | lt = *left_top; |
157 | |
158 | for (i = 0; i < w; i++) { |
159 | l = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i]; |
160 | l &= 0x3FF; |
161 | lt = src1[i]; |
162 | dst[i] = l; |
163 | } |
164 | |
165 | *left = l; |
166 | *left_top = lt; |
167 | } |
168 | |
169 | static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, |
170 | int j, int threadnr) |
171 | { |
172 | MagicYUVContext *s = avctx->priv_data; |
173 | int interlaced = s->interlaced; |
174 | AVFrame *p = s->p; |
175 | int i, k, x; |
176 | GetBitContext gb; |
177 | uint16_t *dst; |
178 | |
179 | for (i = 0; i < s->planes; i++) { |
180 | int left, lefttop, top; |
181 | int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); |
182 | int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); |
183 | int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); |
184 | ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced); |
185 | ptrdiff_t stride = p->linesize[i] / 2; |
186 | int flags, pred; |
187 | int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, |
188 | s->slices[i][j].size); |
189 | |
190 | if (ret < 0) |
191 | return ret; |
192 | |
193 | flags = get_bits(&gb, 8); |
194 | pred = get_bits(&gb, 8); |
195 | |
196 | dst = (uint16_t *)p->data[i] + j * sheight * stride; |
197 | if (flags & 1) { |
198 | for (k = 0; k < height; k++) { |
199 | for (x = 0; x < width; x++) |
200 | dst[x] = get_bits(&gb, 10); |
201 | |
202 | dst += stride; |
203 | } |
204 | } else { |
205 | for (k = 0; k < height; k++) { |
206 | for (x = 0; x < width; x++) { |
207 | int pix; |
208 | if (get_bits_left(&gb) <= 0) |
209 | return AVERROR_INVALIDDATA; |
210 | |
211 | pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); |
212 | if (pix < 0) |
213 | return AVERROR_INVALIDDATA; |
214 | |
215 | dst[x] = 1023 - pix; |
216 | } |
217 | dst += stride; |
218 | } |
219 | } |
220 | |
221 | switch (pred) { |
222 | case LEFT: |
223 | dst = (uint16_t *)p->data[i] + j * sheight * stride; |
224 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
225 | dst += stride; |
226 | if (interlaced) { |
227 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
228 | dst += stride; |
229 | } |
230 | for (k = 1 + interlaced; k < height; k++) { |
231 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, dst[-fake_stride]); |
232 | dst += stride; |
233 | } |
234 | break; |
235 | case GRADIENT: |
236 | dst = (uint16_t *)p->data[i] + j * sheight * stride; |
237 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
238 | left = lefttop = 0; |
239 | dst += stride; |
240 | if (interlaced) { |
241 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
242 | left = lefttop = 0; |
243 | dst += stride; |
244 | } |
245 | for (k = 1 + interlaced; k < height; k++) { |
246 | top = dst[-fake_stride]; |
247 | left = top + dst[0]; |
248 | dst[0] = left & 0x3FF; |
249 | for (x = 1; x < width; x++) { |
250 | top = dst[x - fake_stride]; |
251 | lefttop = dst[x - (fake_stride + 1)]; |
252 | left += top - lefttop + dst[x]; |
253 | dst[x] = left & 0x3FF; |
254 | } |
255 | dst += stride; |
256 | } |
257 | break; |
258 | case MEDIAN: |
259 | dst = (uint16_t *)p->data[i] + j * sheight * stride; |
260 | lefttop = left = dst[0]; |
261 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
262 | dst += stride; |
263 | if (interlaced) { |
264 | lefttop = left = dst[0]; |
265 | s->llviddsp.add_left_pred_int16(dst, dst, 1023, width, 0); |
266 | dst += stride; |
267 | } |
268 | for (k = 1 + interlaced; k < height; k++) { |
269 | magicyuv_median_pred10(dst, dst - fake_stride, dst, width, &left, &lefttop); |
270 | lefttop = left = dst[0]; |
271 | dst += stride; |
272 | } |
273 | break; |
274 | default: |
275 | avpriv_request_sample(avctx, "Unknown prediction: %d", pred); |
276 | } |
277 | } |
278 | |
279 | if (s->decorrelate) { |
280 | int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); |
281 | int width = avctx->coded_width; |
282 | uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2; |
283 | uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2; |
284 | uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2; |
285 | |
286 | for (i = 0; i < height; i++) { |
287 | for (k = 0; k < width; k++) { |
288 | b[k] = (b[k] + g[k]) & 0x3FF; |
289 | r[k] = (r[k] + g[k]) & 0x3FF; |
290 | } |
291 | b += p->linesize[0] / 2; |
292 | g += p->linesize[1] / 2; |
293 | r += p->linesize[2] / 2; |
294 | } |
295 | } |
296 | |
297 | return 0; |
298 | } |
299 | |
300 | static int magy_decode_slice(AVCodecContext *avctx, void *tdata, |
301 | int j, int threadnr) |
302 | { |
303 | MagicYUVContext *s = avctx->priv_data; |
304 | int interlaced = s->interlaced; |
305 | AVFrame *p = s->p; |
306 | int i, k, x; |
307 | GetBitContext gb; |
308 | uint8_t *dst; |
309 | |
310 | for (i = 0; i < s->planes; i++) { |
311 | int left, lefttop, top; |
312 | int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); |
313 | int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); |
314 | int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); |
315 | ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); |
316 | ptrdiff_t stride = p->linesize[i]; |
317 | int flags, pred; |
318 | int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, |
319 | s->slices[i][j].size); |
320 | |
321 | if (ret < 0) |
322 | return ret; |
323 | |
324 | flags = get_bits(&gb, 8); |
325 | pred = get_bits(&gb, 8); |
326 | |
327 | dst = p->data[i] + j * sheight * stride; |
328 | if (flags & 1) { |
329 | for (k = 0; k < height; k++) { |
330 | for (x = 0; x < width; x++) |
331 | dst[x] = get_bits(&gb, 8); |
332 | |
333 | dst += stride; |
334 | } |
335 | } else { |
336 | for (k = 0; k < height; k++) { |
337 | for (x = 0; x < width; x++) { |
338 | int pix; |
339 | if (get_bits_left(&gb) <= 0) |
340 | return AVERROR_INVALIDDATA; |
341 | |
342 | pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); |
343 | if (pix < 0) |
344 | return AVERROR_INVALIDDATA; |
345 | |
346 | dst[x] = 255 - pix; |
347 | } |
348 | dst += stride; |
349 | } |
350 | } |
351 | |
352 | switch (pred) { |
353 | case LEFT: |
354 | dst = p->data[i] + j * sheight * stride; |
355 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
356 | dst += stride; |
357 | if (interlaced) { |
358 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
359 | dst += stride; |
360 | } |
361 | for (k = 1 + interlaced; k < height; k++) { |
362 | s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]); |
363 | dst += stride; |
364 | } |
365 | break; |
366 | case GRADIENT: |
367 | dst = p->data[i] + j * sheight * stride; |
368 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
369 | left = lefttop = 0; |
370 | dst += stride; |
371 | if (interlaced) { |
372 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
373 | left = lefttop = 0; |
374 | dst += stride; |
375 | } |
376 | for (k = 1 + interlaced; k < height; k++) { |
377 | top = dst[-fake_stride]; |
378 | left = top + dst[0]; |
379 | dst[0] = left; |
380 | for (x = 1; x < width; x++) { |
381 | top = dst[x - fake_stride]; |
382 | lefttop = dst[x - (fake_stride + 1)]; |
383 | left += top - lefttop + dst[x]; |
384 | dst[x] = left; |
385 | } |
386 | dst += stride; |
387 | } |
388 | break; |
389 | case MEDIAN: |
390 | dst = p->data[i] + j * sheight * stride; |
391 | lefttop = left = dst[0]; |
392 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
393 | dst += stride; |
394 | if (interlaced) { |
395 | lefttop = left = dst[0]; |
396 | s->llviddsp.add_left_pred(dst, dst, width, 0); |
397 | dst += stride; |
398 | } |
399 | for (k = 1 + interlaced; k < height; k++) { |
400 | s->llviddsp.add_median_pred(dst, dst - fake_stride, |
401 | dst, width, &left, &lefttop); |
402 | lefttop = left = dst[0]; |
403 | dst += stride; |
404 | } |
405 | break; |
406 | default: |
407 | avpriv_request_sample(avctx, "Unknown prediction: %d", pred); |
408 | } |
409 | } |
410 | |
411 | if (s->decorrelate) { |
412 | int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); |
413 | int width = avctx->coded_width; |
414 | uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0]; |
415 | uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1]; |
416 | uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2]; |
417 | |
418 | for (i = 0; i < height; i++) { |
419 | s->llviddsp.add_bytes(b, g, width); |
420 | s->llviddsp.add_bytes(r, g, width); |
421 | b += p->linesize[0]; |
422 | g += p->linesize[1]; |
423 | r += p->linesize[2]; |
424 | } |
425 | } |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max) |
431 | { |
432 | MagicYUVContext *s = avctx->priv_data; |
433 | int i = 0, j = 0, k; |
434 | |
435 | memset(s->len, 0, sizeof(s->len)); |
436 | while (get_bits_left(gbit) >= 8) { |
437 | int b = get_bits(gbit, 4); |
438 | int x = get_bits(gbit, 4); |
439 | int l = get_bitsz(gbit, b) + 1; |
440 | |
441 | for (k = 0; k < l; k++) |
442 | if (j + k < max) |
443 | s->len[i][j + k] = x; |
444 | |
445 | j += l; |
446 | if (j == max) { |
447 | j = 0; |
448 | if (s->huff_build(&s->vlc[i], s->len[i])) { |
449 | av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); |
450 | return AVERROR_INVALIDDATA; |
451 | } |
452 | i++; |
453 | if (i == s->planes) { |
454 | break; |
455 | } |
456 | } else if (j > max) { |
457 | return AVERROR_INVALIDDATA; |
458 | } |
459 | } |
460 | |
461 | if (i != s->planes) { |
462 | av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n"); |
463 | return AVERROR_INVALIDDATA; |
464 | } |
465 | |
466 | return 0; |
467 | } |
468 | |
469 | static int magy_decode_frame(AVCodecContext *avctx, void *data, |
470 | int *got_frame, AVPacket *avpkt) |
471 | { |
472 | MagicYUVContext *s = avctx->priv_data; |
473 | ThreadFrame frame = { .f = data }; |
474 | AVFrame *p = data; |
475 | GetByteContext gbyte; |
476 | GetBitContext gbit; |
477 | uint32_t first_offset, offset, next_offset, header_size, slice_width; |
478 | int width, height, format, version, table_size; |
479 | int ret, i, j; |
480 | |
481 | bytestream2_init(&gbyte, avpkt->data, avpkt->size); |
482 | if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y')) |
483 | return AVERROR_INVALIDDATA; |
484 | |
485 | header_size = bytestream2_get_le32(&gbyte); |
486 | if (header_size < 32 || header_size >= avpkt->size) { |
487 | av_log(avctx, AV_LOG_ERROR, |
488 | "header or packet too small %"PRIu32"\n", header_size); |
489 | return AVERROR_INVALIDDATA; |
490 | } |
491 | |
492 | version = bytestream2_get_byte(&gbyte); |
493 | if (version != 7) { |
494 | avpriv_request_sample(avctx, "Version %d", version); |
495 | return AVERROR_PATCHWELCOME; |
496 | } |
497 | |
498 | s->hshift[1] = |
499 | s->vshift[1] = |
500 | s->hshift[2] = |
501 | s->vshift[2] = 0; |
502 | s->decorrelate = 0; |
503 | s->max = 256; |
504 | s->huff_build = huff_build; |
505 | s->magy_decode_slice = magy_decode_slice; |
506 | |
507 | format = bytestream2_get_byte(&gbyte); |
508 | switch (format) { |
509 | case 0x65: |
510 | avctx->pix_fmt = AV_PIX_FMT_GBRP; |
511 | s->decorrelate = 1; |
512 | break; |
513 | case 0x66: |
514 | avctx->pix_fmt = AV_PIX_FMT_GBRAP; |
515 | s->decorrelate = 1; |
516 | break; |
517 | case 0x67: |
518 | avctx->pix_fmt = AV_PIX_FMT_YUV444P; |
519 | break; |
520 | case 0x68: |
521 | avctx->pix_fmt = AV_PIX_FMT_YUV422P; |
522 | s->hshift[1] = |
523 | s->hshift[2] = 1; |
524 | break; |
525 | case 0x69: |
526 | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
527 | s->hshift[1] = |
528 | s->vshift[1] = |
529 | s->hshift[2] = |
530 | s->vshift[2] = 1; |
531 | break; |
532 | case 0x6a: |
533 | avctx->pix_fmt = AV_PIX_FMT_YUVA444P; |
534 | break; |
535 | case 0x6b: |
536 | avctx->pix_fmt = AV_PIX_FMT_GRAY8; |
537 | break; |
538 | case 0x6c: |
539 | avctx->pix_fmt = AV_PIX_FMT_YUV422P10; |
540 | s->hshift[1] = |
541 | s->hshift[2] = 1; |
542 | s->max = 1024; |
543 | s->huff_build = huff_build10; |
544 | s->magy_decode_slice = magy_decode_slice10; |
545 | break; |
546 | case 0x6d: |
547 | avctx->pix_fmt = AV_PIX_FMT_GBRP10; |
548 | s->decorrelate = 1; |
549 | s->max = 1024; |
550 | s->huff_build = huff_build10; |
551 | s->magy_decode_slice = magy_decode_slice10; |
552 | break; |
553 | case 0x6e: |
554 | avctx->pix_fmt = AV_PIX_FMT_GBRAP10; |
555 | s->decorrelate = 1; |
556 | s->max = 1024; |
557 | s->huff_build = huff_build10; |
558 | s->magy_decode_slice = magy_decode_slice10; |
559 | break; |
560 | case 0x73: |
561 | avctx->pix_fmt = AV_PIX_FMT_GRAY10; |
562 | s->max = 1024; |
563 | s->huff_build = huff_build10; |
564 | s->magy_decode_slice = magy_decode_slice10; |
565 | break; |
566 | default: |
567 | avpriv_request_sample(avctx, "Format 0x%X", format); |
568 | return AVERROR_PATCHWELCOME; |
569 | } |
570 | s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); |
571 | |
572 | bytestream2_skip(&gbyte, 1); |
573 | s->color_matrix = bytestream2_get_byte(&gbyte); |
574 | s->flags = bytestream2_get_byte(&gbyte); |
575 | s->interlaced = !!(s->flags & 2); |
576 | bytestream2_skip(&gbyte, 3); |
577 | |
578 | width = bytestream2_get_le32(&gbyte); |
579 | height = bytestream2_get_le32(&gbyte); |
580 | ret = ff_set_dimensions(avctx, width, height); |
581 | if (ret < 0) |
582 | return ret; |
583 | |
584 | slice_width = bytestream2_get_le32(&gbyte); |
585 | if (slice_width != avctx->coded_width) { |
586 | avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width); |
587 | return AVERROR_PATCHWELCOME; |
588 | } |
589 | s->slice_height = bytestream2_get_le32(&gbyte); |
590 | if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) { |
591 | av_log(avctx, AV_LOG_ERROR, |
592 | "invalid slice height: %d\n", s->slice_height); |
593 | return AVERROR_INVALIDDATA; |
594 | } |
595 | |
596 | bytestream2_skip(&gbyte, 4); |
597 | |
598 | s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height; |
599 | if (s->nb_slices > INT_MAX / sizeof(Slice)) { |
600 | av_log(avctx, AV_LOG_ERROR, |
601 | "invalid number of slices: %d\n", s->nb_slices); |
602 | return AVERROR_INVALIDDATA; |
603 | } |
604 | |
605 | for (i = 0; i < s->planes; i++) { |
606 | av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice)); |
607 | if (!s->slices[i]) |
608 | return AVERROR(ENOMEM); |
609 | |
610 | offset = bytestream2_get_le32(&gbyte); |
611 | if (offset >= avpkt->size - header_size) |
612 | return AVERROR_INVALIDDATA; |
613 | |
614 | if (i == 0) |
615 | first_offset = offset; |
616 | |
617 | for (j = 0; j < s->nb_slices - 1; j++) { |
618 | s->slices[i][j].start = offset + header_size; |
619 | |
620 | next_offset = bytestream2_get_le32(&gbyte); |
621 | if (next_offset <= offset || next_offset >= avpkt->size - header_size) |
622 | return AVERROR_INVALIDDATA; |
623 | |
624 | s->slices[i][j].size = next_offset - offset; |
625 | offset = next_offset; |
626 | } |
627 | |
628 | s->slices[i][j].start = offset + header_size; |
629 | s->slices[i][j].size = avpkt->size - s->slices[i][j].start; |
630 | } |
631 | |
632 | if (bytestream2_get_byte(&gbyte) != s->planes) |
633 | return AVERROR_INVALIDDATA; |
634 | |
635 | bytestream2_skip(&gbyte, s->nb_slices * s->planes); |
636 | |
637 | table_size = header_size + first_offset - bytestream2_tell(&gbyte); |
638 | if (table_size < 2) |
639 | return AVERROR_INVALIDDATA; |
640 | |
641 | ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size); |
642 | if (ret < 0) |
643 | return ret; |
644 | |
645 | ret = build_huffman(avctx, &gbit, s->max); |
646 | if (ret < 0) |
647 | return ret; |
648 | |
649 | p->pict_type = AV_PICTURE_TYPE_I; |
650 | p->key_frame = 1; |
651 | |
652 | if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) |
653 | return ret; |
654 | |
655 | s->buf = avpkt->data; |
656 | s->p = p; |
657 | avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices); |
658 | |
659 | if (avctx->pix_fmt == AV_PIX_FMT_GBRP || |
660 | avctx->pix_fmt == AV_PIX_FMT_GBRAP || |
661 | avctx->pix_fmt == AV_PIX_FMT_GBRP10 || |
662 | avctx->pix_fmt == AV_PIX_FMT_GBRAP10) { |
663 | FFSWAP(uint8_t*, p->data[0], p->data[1]); |
664 | FFSWAP(int, p->linesize[0], p->linesize[1]); |
665 | } else { |
666 | switch (s->color_matrix) { |
667 | case 1: |
668 | p->colorspace = AVCOL_SPC_BT470BG; |
669 | break; |
670 | case 2: |
671 | p->colorspace = AVCOL_SPC_BT709; |
672 | break; |
673 | } |
674 | p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
675 | } |
676 | |
677 | *got_frame = 1; |
678 | |
679 | return avpkt->size; |
680 | } |
681 | |
682 | #if HAVE_THREADS |
683 | static int magy_init_thread_copy(AVCodecContext *avctx) |
684 | { |
685 | MagicYUVContext *s = avctx->priv_data; |
686 | int i; |
687 | |
688 | for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) { |
689 | s->slices[i] = NULL; |
690 | s->slices_size[i] = 0; |
691 | } |
692 | |
693 | return 0; |
694 | } |
695 | #endif |
696 | |
697 | static av_cold int magy_decode_init(AVCodecContext *avctx) |
698 | { |
699 | MagicYUVContext *s = avctx->priv_data; |
700 | ff_llviddsp_init(&s->llviddsp); |
701 | return 0; |
702 | } |
703 | |
704 | static av_cold int magy_decode_end(AVCodecContext *avctx) |
705 | { |
706 | MagicYUVContext * const s = avctx->priv_data; |
707 | int i; |
708 | |
709 | for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) { |
710 | av_freep(&s->slices[i]); |
711 | s->slices_size[i] = 0; |
712 | ff_free_vlc(&s->vlc[i]); |
713 | } |
714 | |
715 | return 0; |
716 | } |
717 | |
718 | AVCodec ff_magicyuv_decoder = { |
719 | .name = "magicyuv", |
720 | .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), |
721 | .type = AVMEDIA_TYPE_VIDEO, |
722 | .id = AV_CODEC_ID_MAGICYUV, |
723 | .priv_data_size = sizeof(MagicYUVContext), |
724 | .init = magy_decode_init, |
725 | .init_thread_copy = ONLY_IF_THREADS_ENABLED(magy_init_thread_copy), |
726 | .close = magy_decode_end, |
727 | .decode = magy_decode_frame, |
728 | .capabilities = AV_CODEC_CAP_DR1 | |
729 | AV_CODEC_CAP_FRAME_THREADS | |
730 | AV_CODEC_CAP_SLICE_THREADS, |
731 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
732 | }; |
733 |