FFmpeg
magicyuv.c
Go to the documentation of this file.
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 #define CACHED_BITSTREAM_READER !ARCH_X86_32
26 
27 #include "libavutil/pixdesc.h"
28 
29 #include "avcodec.h"
30 #include "bytestream.h"
31 #include "get_bits.h"
32 #include "huffyuvdsp.h"
33 #include "internal.h"
34 #include "lossless_videodsp.h"
35 #include "thread.h"
36 
37 typedef struct Slice {
38  uint32_t start;
39  uint32_t size;
40 } Slice;
41 
42 typedef enum Prediction {
43  LEFT = 1,
46 } Prediction;
47 
48 typedef struct HuffEntry {
50  uint16_t code;
51 } HuffEntry;
52 
53 typedef struct MagicYUVContext {
55  int max;
56  int bps;
58  int nb_slices;
59  int planes; // number of encoded planes in bitstream
60  int decorrelate; // postprocessing work
61  int color_matrix; // video color matrix
62  int flags;
63  int interlaced; // video is interlaced
64  const uint8_t *buf; // pointer to AVPacket->data
65  int hshift[4];
66  int vshift[4];
67  Slice *slices[4]; // slice bitstream positions for each plane
68  unsigned int slices_size[4]; // slice sizes for each plane
69  VLC vlc[4]; // VLC for each plane
70  int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata,
71  int j, int threadnr);
74 
75 static int huff_build(HuffEntry he[], uint16_t codes_count[33],
76  VLC *vlc, int nb_elems)
77 {
78  unsigned nb_codes = 0, max = 0;
79 
80  for (int i = 32; i > 0; i--) {
81  uint16_t curr = codes_count[i]; // # of leafs of length i
82  codes_count[i] = nb_codes / 2; // # of non-leaf nodes on level i
83  nb_codes = codes_count[i] + curr; // # of nodes on level i
84  if (curr && !max)
85  max = i;
86  }
87 
88  for (unsigned i = 0; i < nb_elems; i++) {
89  he[i].code = codes_count[he[i].len];
90  codes_count[he[i].len]++;
91  }
92  ff_free_vlc(vlc);
93  return init_vlc(vlc, FFMIN(max, 12), nb_elems,
94  &he[0].len, sizeof(he[0]), sizeof(he[0].len),
95  &he[0].code, sizeof(he[0]), sizeof(he[0].code), 0);
96 }
97 
98 static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
99  const uint16_t *diff, intptr_t w,
100  int *left, int *left_top, int max)
101 {
102  int i;
103  uint16_t l, lt;
104 
105  l = *left;
106  lt = *left_top;
107 
108  for (i = 0; i < w; i++) {
109  l = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i];
110  l &= max;
111  lt = src1[i];
112  dst[i] = l;
113  }
114 
115  *left = l;
116  *left_top = lt;
117 }
118 
119 static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
120  int j, int threadnr)
121 {
122  MagicYUVContext *s = avctx->priv_data;
123  int interlaced = s->interlaced;
124  const int bps = s->bps;
125  const int max = s->max - 1;
126  AVFrame *p = s->p;
127  int i, k, x;
128  GetBitContext gb;
129  uint16_t *dst;
130 
131  for (i = 0; i < s->planes; i++) {
132  int left, lefttop, top;
133  int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
134  int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
135  int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
136  ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced);
137  ptrdiff_t stride = p->linesize[i] / 2;
138  int flags, pred;
139  int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
140  s->slices[i][j].size);
141 
142  if (ret < 0)
143  return ret;
144 
145  flags = get_bits(&gb, 8);
146  pred = get_bits(&gb, 8);
147 
148  dst = (uint16_t *)p->data[i] + j * sheight * stride;
149  if (flags & 1) {
150  if (get_bits_left(&gb) < bps * width * height)
151  return AVERROR_INVALIDDATA;
152  for (k = 0; k < height; k++) {
153  for (x = 0; x < width; x++)
154  dst[x] = get_bits(&gb, bps);
155 
156  dst += stride;
157  }
158  } else {
159  for (k = 0; k < height; k++) {
160  for (x = 0; x < width; x++) {
161  int pix;
162  if (get_bits_left(&gb) <= 0)
163  return AVERROR_INVALIDDATA;
164 
165  pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
166  if (pix < 0)
167  return AVERROR_INVALIDDATA;
168 
169  dst[x] = pix;
170  }
171  dst += stride;
172  }
173  }
174 
175  switch (pred) {
176  case LEFT:
177  dst = (uint16_t *)p->data[i] + j * sheight * stride;
178  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
179  dst += stride;
180  if (interlaced) {
181  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
182  dst += stride;
183  }
184  for (k = 1 + interlaced; k < height; k++) {
185  s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]);
186  dst += stride;
187  }
188  break;
189  case GRADIENT:
190  dst = (uint16_t *)p->data[i] + j * sheight * stride;
191  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
192  dst += stride;
193  if (interlaced) {
194  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
195  dst += stride;
196  }
197  for (k = 1 + interlaced; k < height; k++) {
198  top = dst[-fake_stride];
199  left = top + dst[0];
200  dst[0] = left & max;
201  for (x = 1; x < width; x++) {
202  top = dst[x - fake_stride];
203  lefttop = dst[x - (fake_stride + 1)];
204  left += top - lefttop + dst[x];
205  dst[x] = left & max;
206  }
207  dst += stride;
208  }
209  break;
210  case MEDIAN:
211  dst = (uint16_t *)p->data[i] + j * sheight * stride;
212  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
213  dst += stride;
214  if (interlaced) {
215  s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
216  dst += stride;
217  }
218  lefttop = left = dst[0];
219  for (k = 1 + interlaced; k < height; k++) {
220  magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max);
221  lefttop = left = dst[0];
222  dst += stride;
223  }
224  break;
225  default:
226  avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
227  }
228  }
229 
230  if (s->decorrelate) {
231  int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
232  int width = avctx->coded_width;
233  uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2;
234  uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2;
235  uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2;
236 
237  for (i = 0; i < height; i++) {
238  for (k = 0; k < width; k++) {
239  b[k] = (b[k] + g[k]) & max;
240  r[k] = (r[k] + g[k]) & max;
241  }
242  b += p->linesize[0] / 2;
243  g += p->linesize[1] / 2;
244  r += p->linesize[2] / 2;
245  }
246  }
247 
248  return 0;
249 }
250 
251 static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
252  int j, int threadnr)
253 {
254  MagicYUVContext *s = avctx->priv_data;
255  int interlaced = s->interlaced;
256  AVFrame *p = s->p;
257  int i, k, x, min_width;
258  GetBitContext gb;
259  uint8_t *dst;
260 
261  for (i = 0; i < s->planes; i++) {
262  int left, lefttop, top;
263  int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
264  int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
265  int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
266  ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced);
267  ptrdiff_t stride = p->linesize[i];
268  const uint8_t *slice = s->buf + s->slices[i][j].start;
269  int flags, pred;
270 
271  flags = bytestream_get_byte(&slice);
272  pred = bytestream_get_byte(&slice);
273 
274  dst = p->data[i] + j * sheight * stride;
275  if (flags & 1) {
276  if (s->slices[i][j].size - 2 < width * height)
277  return AVERROR_INVALIDDATA;
278  for (k = 0; k < height; k++) {
279  bytestream_get_buffer(&slice, dst, width);
280  dst += stride;
281  }
282  } else {
283  int ret = init_get_bits8(&gb, slice, s->slices[i][j].size - 2);
284 
285  if (ret < 0)
286  return ret;
287 
288  for (k = 0; k < height; k++) {
289  for (x = 0; x < width; x++) {
290  int pix;
291  if (get_bits_left(&gb) <= 0)
292  return AVERROR_INVALIDDATA;
293 
294  pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
295  if (pix < 0)
296  return AVERROR_INVALIDDATA;
297 
298  dst[x] = pix;
299  }
300  dst += stride;
301  }
302  }
303 
304  switch (pred) {
305  case LEFT:
306  dst = p->data[i] + j * sheight * stride;
307  s->llviddsp.add_left_pred(dst, dst, width, 0);
308  dst += stride;
309  if (interlaced) {
310  s->llviddsp.add_left_pred(dst, dst, width, 0);
311  dst += stride;
312  }
313  for (k = 1 + interlaced; k < height; k++) {
314  s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]);
315  dst += stride;
316  }
317  break;
318  case GRADIENT:
319  dst = p->data[i] + j * sheight * stride;
320  s->llviddsp.add_left_pred(dst, dst, width, 0);
321  dst += stride;
322  if (interlaced) {
323  s->llviddsp.add_left_pred(dst, dst, width, 0);
324  dst += stride;
325  }
326  min_width = FFMIN(width, 32);
327  for (k = 1 + interlaced; k < height; k++) {
328  top = dst[-fake_stride];
329  left = top + dst[0];
330  dst[0] = left;
331  for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */
332  top = dst[x - fake_stride];
333  lefttop = dst[x - (fake_stride + 1)];
334  left += top - lefttop + dst[x];
335  dst[x] = left;
336  }
337  if (width > 32)
338  s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32);
339  dst += stride;
340  }
341  break;
342  case MEDIAN:
343  dst = p->data[i] + j * sheight * stride;
344  s->llviddsp.add_left_pred(dst, dst, width, 0);
345  dst += stride;
346  if (interlaced) {
347  s->llviddsp.add_left_pred(dst, dst, width, 0);
348  dst += stride;
349  }
350  lefttop = left = dst[0];
351  for (k = 1 + interlaced; k < height; k++) {
352  s->llviddsp.add_median_pred(dst, dst - fake_stride,
353  dst, width, &left, &lefttop);
354  lefttop = left = dst[0];
355  dst += stride;
356  }
357  break;
358  default:
359  avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
360  }
361  }
362 
363  if (s->decorrelate) {
364  int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
365  int width = avctx->coded_width;
366  uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0];
367  uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1];
368  uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2];
369 
370  for (i = 0; i < height; i++) {
371  s->llviddsp.add_bytes(b, g, width);
372  s->llviddsp.add_bytes(r, g, width);
373  b += p->linesize[0];
374  g += p->linesize[1];
375  r += p->linesize[2];
376  }
377  }
378 
379  return 0;
380 }
381 
382 static int build_huffman(AVCodecContext *avctx, const uint8_t *table,
383  int table_size, int max)
384 {
385  MagicYUVContext *s = avctx->priv_data;
386  GetByteContext gb;
387  HuffEntry he[4096];
388  uint16_t length_count[33] = { 0 };
389  int i = 0, j = 0, k;
390 
391  bytestream2_init(&gb, table, table_size);
392 
393  while (bytestream2_get_bytes_left(&gb) > 0) {
394  int b = bytestream2_peek_byteu(&gb) & 0x80;
395  int x = bytestream2_get_byteu(&gb) & ~0x80;
396  int l = 1;
397 
398  if (b) {
399  if (bytestream2_get_bytes_left(&gb) <= 0)
400  break;
401  l += bytestream2_get_byteu(&gb);
402  }
403  k = j + l;
404  if (k > max || x == 0 || x > 32) {
405  av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n");
406  return AVERROR_INVALIDDATA;
407  }
408 
409  length_count[x] += l;
410  for (; j < k; j++)
411  he[j].len = x;
412 
413  if (j == max) {
414  j = 0;
415  if (huff_build(he, length_count, &s->vlc[i], max)) {
416  av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
417  return AVERROR_INVALIDDATA;
418  }
419  i++;
420  if (i == s->planes) {
421  break;
422  }
423  memset(length_count, 0, sizeof(length_count));
424  }
425  }
426 
427  if (i != s->planes) {
428  av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n");
429  return AVERROR_INVALIDDATA;
430  }
431 
432  return 0;
433 }
434 
435 static int magy_decode_frame(AVCodecContext *avctx, void *data,
436  int *got_frame, AVPacket *avpkt)
437 {
438  MagicYUVContext *s = avctx->priv_data;
439  ThreadFrame frame = { .f = data };
440  AVFrame *p = data;
441  GetByteContext gb;
442  uint32_t first_offset, offset, next_offset, header_size, slice_width;
443  int width, height, format, version, table_size;
444  int ret, i, j;
445 
446  if (avpkt->size < 36)
447  return AVERROR_INVALIDDATA;
448 
449  bytestream2_init(&gb, avpkt->data, avpkt->size);
450  if (bytestream2_get_le32u(&gb) != MKTAG('M', 'A', 'G', 'Y'))
451  return AVERROR_INVALIDDATA;
452 
453  header_size = bytestream2_get_le32u(&gb);
454  if (header_size < 32 || header_size >= avpkt->size) {
455  av_log(avctx, AV_LOG_ERROR,
456  "header or packet too small %"PRIu32"\n", header_size);
457  return AVERROR_INVALIDDATA;
458  }
459 
460  version = bytestream2_get_byteu(&gb);
461  if (version != 7) {
462  avpriv_request_sample(avctx, "Version %d", version);
463  return AVERROR_PATCHWELCOME;
464  }
465 
466  s->hshift[1] =
467  s->vshift[1] =
468  s->hshift[2] =
469  s->vshift[2] = 0;
470  s->decorrelate = 0;
471  s->bps = 8;
472 
473  format = bytestream2_get_byteu(&gb);
474  switch (format) {
475  case 0x65:
476  avctx->pix_fmt = AV_PIX_FMT_GBRP;
477  s->decorrelate = 1;
478  break;
479  case 0x66:
480  avctx->pix_fmt = AV_PIX_FMT_GBRAP;
481  s->decorrelate = 1;
482  break;
483  case 0x67:
484  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
485  break;
486  case 0x68:
487  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
488  s->hshift[1] =
489  s->hshift[2] = 1;
490  break;
491  case 0x69:
492  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
493  s->hshift[1] =
494  s->vshift[1] =
495  s->hshift[2] =
496  s->vshift[2] = 1;
497  break;
498  case 0x6a:
499  avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
500  break;
501  case 0x6b:
502  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
503  break;
504  case 0x6c:
505  avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
506  s->hshift[1] =
507  s->hshift[2] = 1;
508  s->bps = 10;
509  break;
510  case 0x76:
511  avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
512  s->bps = 10;
513  break;
514  case 0x6d:
515  avctx->pix_fmt = AV_PIX_FMT_GBRP10;
516  s->decorrelate = 1;
517  s->bps = 10;
518  break;
519  case 0x6e:
520  avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
521  s->decorrelate = 1;
522  s->bps = 10;
523  break;
524  case 0x6f:
525  avctx->pix_fmt = AV_PIX_FMT_GBRP12;
526  s->decorrelate = 1;
527  s->bps = 12;
528  break;
529  case 0x70:
530  avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
531  s->decorrelate = 1;
532  s->bps = 12;
533  break;
534  case 0x73:
535  avctx->pix_fmt = AV_PIX_FMT_GRAY10;
536  s->bps = 10;
537  break;
538  case 0x7b:
539  avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
540  s->hshift[1] =
541  s->vshift[1] =
542  s->hshift[2] =
543  s->vshift[2] = 1;
544  s->bps = 10;
545  break;
546  default:
547  avpriv_request_sample(avctx, "Format 0x%X", format);
548  return AVERROR_PATCHWELCOME;
549  }
550  s->max = 1 << s->bps;
553 
554  bytestream2_skipu(&gb, 1);
555  s->color_matrix = bytestream2_get_byteu(&gb);
556  s->flags = bytestream2_get_byteu(&gb);
557  s->interlaced = !!(s->flags & 2);
558  bytestream2_skipu(&gb, 3);
559 
560  width = bytestream2_get_le32u(&gb);
561  height = bytestream2_get_le32u(&gb);
562  ret = ff_set_dimensions(avctx, width, height);
563  if (ret < 0)
564  return ret;
565 
566  slice_width = bytestream2_get_le32u(&gb);
567  if (slice_width != avctx->coded_width) {
568  avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width);
569  return AVERROR_PATCHWELCOME;
570  }
571  s->slice_height = bytestream2_get_le32u(&gb);
572  if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) {
573  av_log(avctx, AV_LOG_ERROR,
574  "invalid slice height: %d\n", s->slice_height);
575  return AVERROR_INVALIDDATA;
576  }
577 
578  bytestream2_skipu(&gb, 4);
579 
580  s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height;
581  if (s->nb_slices > INT_MAX / FFMAX(sizeof(Slice), 4 * 5)) {
582  av_log(avctx, AV_LOG_ERROR,
583  "invalid number of slices: %d\n", s->nb_slices);
584  return AVERROR_INVALIDDATA;
585  }
586 
587  if (s->interlaced) {
588  if ((s->slice_height >> s->vshift[1]) < 2) {
589  av_log(avctx, AV_LOG_ERROR, "impossible slice height\n");
590  return AVERROR_INVALIDDATA;
591  }
592  if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) {
593  av_log(avctx, AV_LOG_ERROR, "impossible height\n");
594  return AVERROR_INVALIDDATA;
595  }
596  }
597 
598  if (bytestream2_get_bytes_left(&gb) <= s->nb_slices * s->planes * 5)
599  return AVERROR_INVALIDDATA;
600  for (i = 0; i < s->planes; i++) {
601  av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice));
602  if (!s->slices[i])
603  return AVERROR(ENOMEM);
604 
605  offset = bytestream2_get_le32u(&gb);
606  if (offset >= avpkt->size - header_size)
607  return AVERROR_INVALIDDATA;
608 
609  if (i == 0)
610  first_offset = offset;
611 
612  for (j = 0; j < s->nb_slices - 1; j++) {
613  s->slices[i][j].start = offset + header_size;
614 
615  next_offset = bytestream2_get_le32u(&gb);
616  if (next_offset <= offset || next_offset >= avpkt->size - header_size)
617  return AVERROR_INVALIDDATA;
618 
619  s->slices[i][j].size = next_offset - offset;
620  if (s->slices[i][j].size < 2)
621  return AVERROR_INVALIDDATA;
622  offset = next_offset;
623  }
624 
625  s->slices[i][j].start = offset + header_size;
626  s->slices[i][j].size = avpkt->size - s->slices[i][j].start;
627 
628  if (s->slices[i][j].size < 2)
629  return AVERROR_INVALIDDATA;
630  }
631 
632  if (bytestream2_get_byteu(&gb) != s->planes)
633  return AVERROR_INVALIDDATA;
634 
635  bytestream2_skipu(&gb, s->nb_slices * s->planes);
636 
637  table_size = header_size + first_offset - bytestream2_tell(&gb);
638  if (table_size < 2)
639  return AVERROR_INVALIDDATA;
640 
641  ret = build_huffman(avctx, avpkt->data + bytestream2_tell(&gb),
642  table_size, s->max);
643  if (ret < 0)
644  return ret;
645 
647  p->key_frame = 1;
648 
649  if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
650  return ret;
651 
652  s->buf = avpkt->data;
653  s->p = p;
654  avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices);
655 
656  if (avctx->pix_fmt == AV_PIX_FMT_GBRP ||
657  avctx->pix_fmt == AV_PIX_FMT_GBRAP ||
658  avctx->pix_fmt == AV_PIX_FMT_GBRP10 ||
659  avctx->pix_fmt == AV_PIX_FMT_GBRAP10||
660  avctx->pix_fmt == AV_PIX_FMT_GBRAP12||
661  avctx->pix_fmt == AV_PIX_FMT_GBRP12) {
662  FFSWAP(uint8_t*, p->data[0], p->data[1]);
663  FFSWAP(int, p->linesize[0], p->linesize[1]);
664  } else {
665  switch (s->color_matrix) {
666  case 1:
668  break;
669  case 2:
671  break;
672  }
674  }
675 
676  *got_frame = 1;
677 
678  return avpkt->size;
679 }
680 
682 {
683  MagicYUVContext *s = avctx->priv_data;
685  return 0;
686 }
687 
689 {
690  MagicYUVContext * const s = avctx->priv_data;
691  int i;
692 
693  for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
694  av_freep(&s->slices[i]);
695  s->slices_size[i] = 0;
696  ff_free_vlc(&s->vlc[i]);
697  }
698 
699  return 0;
700 }
701 
703  .name = "magicyuv",
704  .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"),
705  .type = AVMEDIA_TYPE_VIDEO,
706  .id = AV_CODEC_ID_MAGICYUV,
707  .priv_data_size = sizeof(MagicYUVContext),
709  .close = magy_decode_end,
711  .capabilities = AV_CODEC_CAP_DR1 |
714  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
715 };
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:514
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int(* add_left_pred)(uint8_t *dst, const uint8_t *src, ptrdiff_t w, int left)
version
Definition: libkvazaar.c:317
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:719
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:106
const char * g
Definition: vf_curves.c:115
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
Definition: pixfmt.h:518
#define avpriv_request_sample(...)
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
int size
Definition: packet.h:364
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
unsigned int slices_size[4]
Definition: magicyuv.c:68
static int build_huffman(AVCodecContext *avctx, const uint8_t *table, int table_size, int max)
Definition: magicyuv.c:382
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
AVCodec.
Definition: codec.h:190
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
LLVidDSPContext llviddsp
Definition: magicyuv.c:72
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
static int huff_build(HuffEntry he[], uint16_t codes_count[33], VLC *vlc, int nb_elems)
Definition: magicyuv.c:75
uint8_t
#define av_cold
Definition: attributes.h:88
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Multithreading support functions.
Prediction
Definition: magicyuv.c:42
#define height
uint8_t * data
Definition: packet.h:363
void(* add_median_pred)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, ptrdiff_t w, int *left, int *left_top)
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
bitstream reader API header.
int hshift[4]
Definition: magicyuv.c:65
#define max(a, b)
Definition: cuda_runtime.h:33
uint16_t code
Definition: magicyuv.c:50
#define av_log(a,...)
static const uint16_t table[]
Definition: prosumer.c:206
void(* add_gradient_pred)(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width)
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int j, int threadnr)
Definition: magicyuv.c:251
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int slice_height
Definition: magicyuv.c:57
#define init_vlc(vlc, nb_bits, nb_codes,bits, bits_wrap, bits_size,codes, codes_wrap, codes_size,flags)
Definition: vlc.h:38
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
const char * r
Definition: vf_curves.c:114
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:558
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:569
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
const char * name
Name of the codec implementation.
Definition: codec.h:197
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
#define FFMAX(a, b)
Definition: common.h:94
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:106
Definition: vlc.h:26
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
Slice * slices[4]
Definition: magicyuv.c:67
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames.The frames must then be freed with ff_thread_release_buffer().Otherwise decode directly into the user-supplied frames.Call ff_thread_report_progress() after some part of the current picture has decoded.A good place to put this is where draw_horiz_band() is called-add this if it isn't called anywhere
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:502
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:397
int vshift[4]
Definition: magicyuv.c:66
#define FFMIN(a, b)
Definition: common.h:96
uint8_t interlaced
Definition: mxfenc.c:2168
#define width
uint8_t w
Definition: llviddspenc.c:38
Definition: magicyuv.c:37
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define s(width, name)
Definition: cbs_vp9.c:257
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:797
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
Definition: bytestream.h:363
#define FF_ARRAY_ELEMS(a)
Full range content.
Definition: pixfmt.h:586
int bits
Definition: vlc.h:27
if(ret)
static const float pred[4]
Definition: siprdata.h:259
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:110
static av_cold int magy_decode_init(AVCodecContext *avctx)
Definition: magicyuv.c:681
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition: avcodec.h:1850
int(* add_left_pred_int16)(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned left)
#define src1
Definition: h264pred.c:139
uint8_t len
Definition: magicyuv.c:49
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
main external API structure.
Definition: avcodec.h:531
static int magy_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: magicyuv.c:435
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:206
uint32_t size
Definition: magicyuv.c:39
void ff_llviddsp_init(LLVidDSPContext *c)
uint32_t start
Definition: magicyuv.c:38
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
int coded_height
Definition: avcodec.h:719
AVCodec ff_magicyuv_decoder
Definition: magicyuv.c:702
Definition: magicyuv.c:43
#define mid_pred
Definition: mathops.h:97
VLC vlc[4]
Definition: magicyuv.c:69
AVFrame * p
Definition: magicyuv.c:54
static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, int j, int threadnr)
Definition: magicyuv.c:119
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
int(* magy_decode_slice)(AVCodecContext *avctx, void *tdata, int j, int threadnr)
Definition: magicyuv.c:70
#define flags(name, subs,...)
Definition: cbs_av1.c:560
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
Narrow or limited range content.
Definition: pixfmt.h:569
static av_cold int magy_decode_end(AVCodecContext *avctx)
Definition: magicyuv.c:688
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
int
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
common internal api header.
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
const uint8_t * buf
Definition: magicyuv.c:64
unsigned bps
Definition: movenc.c:1598
void * priv_data
Definition: avcodec.h:558
static av_always_inline int diff(const uint32_t a, const uint32_t b)
int len
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:392
static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1, const uint16_t *diff, intptr_t w, int *left, int *left_top, int max)
Definition: magicyuv.c:98
#define av_freep(p)
#define FFSWAP(type, a, b)
Definition: common.h:99
#define stride
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
void(* add_bytes)(uint8_t *dst, uint8_t *src, ptrdiff_t w)
#define MKTAG(a, b, c, d)
Definition: common.h:405
This structure stores compressed data.
Definition: packet.h:340
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:365
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
for(j=16;j >0;--j)
int i
Definition: input.c:407
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
int color_matrix
Definition: magicyuv.c:61