FFmpeg
argo.c
Go to the documentation of this file.
1 /*
2  * Argonaut Games Video decoder
3  * Copyright (c) 2020 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 <string.h>
23 
24 #include "libavutil/attributes.h"
25 #include "libavutil/internal.h"
26 #include "libavutil/intreadwrite.h"
27 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "codec_internal.h"
31 #include "decode.h"
32 
33 typedef struct ArgoContext {
35 
36  int bpp;
37  int key;
38  int mv0[128][2];
39  int mv1[16][2];
40  uint32_t pal[256];
42 } ArgoContext;
43 
44 static int decode_pal8(AVCodecContext *avctx, uint32_t *pal)
45 {
46  ArgoContext *s = avctx->priv_data;
47  GetByteContext *gb = &s->gb;
48  int start, count;
49 
50  start = bytestream2_get_le16(gb);
51  count = bytestream2_get_le16(gb);
52 
53  if (start + count > 256)
54  return AVERROR_INVALIDDATA;
55 
56  if (bytestream2_get_bytes_left(gb) < 3 * count)
57  return AVERROR_INVALIDDATA;
58 
59  for (int i = 0; i < count; i++)
60  pal[start + i] = (0xFFU << 24) | bytestream2_get_be24u(gb);
61 
62  return 0;
63 }
64 
66 {
67  ArgoContext *s = avctx->priv_data;
68  GetByteContext *gb = &s->gb;
69  const int l = frame->linesize[0];
70  const uint8_t *map = gb->buffer;
71  uint8_t *dst = frame->data[0];
72 
73  if (bytestream2_get_bytes_left(gb) < 1024 + (frame->width / 2) * (frame->height / 2))
74  return AVERROR_INVALIDDATA;
75 
76  bytestream2_skipu(gb, 1024);
77  for (int y = 0; y < frame->height; y += 2) {
78  for (int x = 0; x < frame->width; x += 2) {
79  int index = bytestream2_get_byteu(gb);
80  const uint8_t *block = map + index * 4;
81 
82  dst[x+0] = block[0];
83  dst[x+1] = block[1];
84  dst[x+l] = block[2];
85  dst[x+l+1] = block[3];
86  }
87 
88  dst += frame->linesize[0] * 2;
89  }
90 
91  return 0;
92 }
93 
95 {
96  ArgoContext *s = avctx->priv_data;
97  GetByteContext *gb = &s->gb;
98  GetByteContext sb;
99  const int l = frame->linesize[0];
100  const uint8_t *map = gb->buffer;
101  uint8_t *dst = frame->data[0];
102  uint8_t codes = 0;
103  int count = 0;
104 
105  if (bytestream2_get_bytes_left(gb) < 1024 + (((frame->width / 2) * (frame->height / 2) + 7) >> 3))
106  return AVERROR_INVALIDDATA;
107 
108  bytestream2_skipu(gb, 1024);
109  sb = *gb;
110  bytestream2_skipu(gb, ((frame->width / 2) * (frame->height / 2) + 7) >> 3);
111 
112  for (int y = 0; y < frame->height; y += 2) {
113  for (int x = 0; x < frame->width; x += 2) {
114  const uint8_t *block;
115  int index;
116 
117  if (count == 0) {
118  codes = bytestream2_get_byteu(&sb);
119  count = 8;
120  }
121 
122  if (codes & 0x80) {
123  index = bytestream2_get_byte(gb);
124  block = map + index * 4;
125 
126  dst[x+0] = block[0];
127  dst[x+1] = block[1];
128  dst[x+l] = block[2];
129  dst[x+l+1] = block[3];
130  }
131 
132  codes <<= 1;
133  count--;
134  }
135 
136  dst += frame->linesize[0] * 2;
137  }
138 
139  return 0;
140 }
141 
143 {
144  ArgoContext *s = avctx->priv_data;
145  GetByteContext *gb = &s->gb;
146  const int w = frame->width;
147  const int h = frame->height;
148  const int l = frame->linesize[0];
149 
150  while (bytestream2_get_bytes_left(gb) > 0) {
151  int size, type, pos, dy;
152  uint8_t *dst;
153 
154  type = bytestream2_get_byte(gb);
155  if (type == 0xFF)
156  break;
157 
158  switch (type) {
159  case 8:
160  dst = frame->data[0];
161  for (int y = 0; y < h; y += 8) {
162  for (int x = 0; x < w; x += 8) {
163  int fill = bytestream2_get_byte(gb);
164  uint8_t *ddst = dst + x;
165 
166  for (int by = 0; by < 8; by++) {
167  memset(ddst, fill, 8);
168  ddst += l;
169  }
170  }
171 
172  dst += 8 * l;
173  }
174  break;
175  case 7:
176  while (bytestream2_get_bytes_left(gb) > 0) {
177  int bsize = bytestream2_get_byte(gb);
178  uint8_t *src;
179  int count;
180 
181  if (!bsize)
182  break;
183 
184  count = bytestream2_get_be16(gb);
185  while (count > 0) {
186  int mvx, mvy, a, b, c, mx, my;
187  int bsize_w, bsize_h;
188 
189  bsize_w = bsize_h = bsize;
190  if (bytestream2_get_bytes_left(gb) < 4)
191  return AVERROR_INVALIDDATA;
192  mvx = bytestream2_get_byte(gb) * bsize;
193  mvy = bytestream2_get_byte(gb) * bsize;
194  a = bytestream2_get_byte(gb);
195  b = bytestream2_get_byte(gb);
196  c = ((a & 0x3F) << 8) + b;
197  mx = mvx + (c & 0x7F) - 64;
198  my = mvy + (c >> 7) - 64;
199 
200  if (mvy < 0 || mvy >= h)
201  return AVERROR_INVALIDDATA;
202 
203  if (mvx < 0 || mvx >= w)
204  return AVERROR_INVALIDDATA;
205 
206  if (my < 0 || my >= h)
207  return AVERROR_INVALIDDATA;
208 
209  if (mx < 0 || mx >= w)
210  return AVERROR_INVALIDDATA;
211 
212  dst = frame->data[0] + mvx + l * mvy;
213  src = frame->data[0] + mx + l * my;
214 
215  bsize_w = FFMIN3(bsize_w, w - mvx, w - mx);
216  bsize_h = FFMIN3(bsize_h, h - mvy, h - my);
217 
218  if (mvy >= my && (mvy != my || mvx >= mx)) {
219  src += (bsize_h - 1) * l;
220  dst += (bsize_h - 1) * l;
221  for (int by = 0; by < bsize_h; by++) {
222  memmove(dst, src, bsize_w);
223  src -= l;
224  dst -= l;
225  }
226  } else {
227  for (int by = 0; by < bsize_h; by++) {
228  memmove(dst, src, bsize_w);
229  src += l;
230  dst += l;
231  }
232  }
233 
234  count--;
235  }
236  }
237  break;
238  case 6:
239  dst = frame->data[0];
240  if (bytestream2_get_bytes_left(gb) < w * h)
241  return AVERROR_INVALIDDATA;
242  for (int y = 0; y < h; y++) {
244  dst += l;
245  }
246  break;
247  case 5:
248  dst = frame->data[0];
249  for (int y = 0; y < h; y += 2) {
250  for (int x = 0; x < w; x += 2) {
251  int fill = bytestream2_get_byte(gb);
252  uint8_t *ddst = dst + x;
253 
254  fill = (fill << 8) | fill;
255  for (int by = 0; by < 2; by++) {
256  AV_WN16(ddst, fill);
257 
258  ddst += l;
259  }
260  }
261 
262  dst += 2 * l;
263  }
264  break;
265  case 3:
266  size = bytestream2_get_le16(gb);
267  if (size > 0) {
268  int x = bytestream2_get_byte(gb) * 4;
269  int y = bytestream2_get_byte(gb) * 4;
270  int count = bytestream2_get_byte(gb);
271  int fill = bytestream2_get_byte(gb);
272 
273  av_log(avctx, AV_LOG_DEBUG, "%d %d %d %d\n", x, y, count, fill);
274  for (int i = 0; i < count; i++)
275  ;
276  return AVERROR_PATCHWELCOME;
277  }
278  break;
279  case 2:
280  dst = frame->data[0];
281  pos = 0;
282  dy = 0;
283  while (bytestream2_get_bytes_left(gb) > 0) {
284  int count = bytestream2_get_byteu(gb);
285  int skip = count & 0x3F;
286 
287  count = count >> 6;
288  if (skip == 0x3F) {
289  pos += 0x3E;
290  while (pos >= w) {
291  pos -= w;
292  dst += l;
293  dy++;
294  if (dy >= h)
295  return 0;
296  }
297  } else {
298  pos += skip;
299  while (pos >= w) {
300  pos -= w;
301  dst += l;
302  dy++;
303  if (dy >= h)
304  return 0;
305  }
306  while (count >= 0) {
307  int bits = bytestream2_get_byte(gb);
308 
309  for (int i = 0; i < 4; i++) {
310  switch (bits & 3) {
311  case 0:
312  break;
313  case 1:
314  if (dy < 1 && !pos)
315  return AVERROR_INVALIDDATA;
316  else
317  dst[pos] = pos ? dst[pos - 1] : dst[-l + w - 1];
318  break;
319  case 2:
320  if (dy < 1)
321  return AVERROR_INVALIDDATA;
322  dst[pos] = dst[pos - l];
323  break;
324  case 3:
325  dst[pos] = bytestream2_get_byte(gb);
326  break;
327  }
328 
329  pos++;
330  if (pos >= w) {
331  pos -= w;
332  dst += l;
333  dy++;
334  if (dy >= h)
335  return 0;
336  }
337  bits >>= 2;
338  }
339  count--;
340  }
341  }
342  }
343  break;
344  default:
345  return AVERROR_INVALIDDATA;
346  }
347  }
348 
349  return 0;
350 }
351 
353 {
354  ArgoContext *s = avctx->priv_data;
355  GetByteContext *gb = &s->gb;
356  const int w = frame->width;
357  const int h = frame->height;
358  const int l = frame->linesize[0] / 4;
359 
360  while (bytestream2_get_bytes_left(gb) > 0) {
361  int osize, type, pos, dy, di, bcode, value, v14;
362  const uint8_t *bits;
363  uint32_t *dst;
364 
365  type = bytestream2_get_byte(gb);
366  if (type == 0xFF)
367  return 0;
368 
369  switch (type) {
370  case 8:
371  dst = (uint32_t *)frame->data[0];
372  for (int y = 0; y + 12 <= h; y += 12) {
373  for (int x = 0; x + 12 <= w; x += 12) {
374  int fill = bytestream2_get_be24(gb);
375  uint32_t *dstp = dst + x;
376 
377  for (int by = 0; by < 12; by++) {
378  for (int bx = 0; bx < 12; bx++)
379  dstp[bx] = fill;
380 
381  dstp += l;
382  }
383  }
384 
385  dst += 12 * l;
386  }
387  break;
388  case 7:
389  while (bytestream2_get_bytes_left(gb) > 0) {
390  int bsize = bytestream2_get_byte(gb);
391  uint32_t *src;
392  int count;
393 
394  if (!bsize)
395  break;
396 
397  count = bytestream2_get_be16(gb);
398  while (count > 0) {
399  int mvx, mvy, a, b, c, mx, my;
400  int bsize_w, bsize_h;
401 
402  bsize_w = bsize_h = bsize;
403  if (bytestream2_get_bytes_left(gb) < 4)
404  return AVERROR_INVALIDDATA;
405  mvx = bytestream2_get_byte(gb) * bsize;
406  mvy = bytestream2_get_byte(gb) * bsize;
407  a = bytestream2_get_byte(gb);
408  b = bytestream2_get_byte(gb);
409  c = ((a & 0x3F) << 8) + b;
410  mx = mvx + (c & 0x7F) - 64;
411  my = mvy + (c >> 7) - 64;
412 
413  if (mvy < 0 || mvy >= h)
414  return AVERROR_INVALIDDATA;
415 
416  if (mvx < 0 || mvx >= w)
417  return AVERROR_INVALIDDATA;
418 
419  if (my < 0 || my >= h)
420  return AVERROR_INVALIDDATA;
421 
422  if (mx < 0 || mx >= w)
423  return AVERROR_INVALIDDATA;
424 
425  dst = (uint32_t *)frame->data[0] + mvx + l * mvy;
426  src = (uint32_t *)frame->data[0] + mx + l * my;
427 
428  bsize_w = FFMIN3(bsize_w, w - mvx, w - mx);
429  bsize_h = FFMIN3(bsize_h, h - mvy, h - my);
430 
431  if (mvy >= my && (mvy != my || mvx >= mx)) {
432  src += (bsize_h - 1) * l;
433  dst += (bsize_h - 1) * l;
434  for (int by = 0; by < bsize_h; by++) {
435  memmove(dst, src, bsize_w * 4);
436  src -= l;
437  dst -= l;
438  }
439  } else {
440  for (int by = 0; by < bsize_h; by++) {
441  memmove(dst, src, bsize_w * 4);
442  src += l;
443  dst += l;
444  }
445  }
446 
447  count--;
448  }
449  }
450  break;
451  case 12:
452  osize = ((h + 3) / 4) * ((w + 3) / 4) + 7;
453  bits = gb->buffer;
454  di = 0;
455  bcode = v14 = 0;
456  if (bytestream2_get_bytes_left(gb) < osize >> 3)
457  return AVERROR_INVALIDDATA;
458  bytestream2_skip(gb, osize >> 3);
459  for (int x = 0; x < w; x += 4) {
460  for (int y = 0; y < h; y += 4) {
461  int astate = 0;
462 
463  if (bits[di >> 3] & (1 << (di & 7))) {
464  int codes = bytestream2_get_byte(gb);
465 
466  for (int count = 0; count < 4; count++) {
467  uint32_t *src = (uint32_t *)frame->data[0];
468  size_t src_size = l * (h - 1) + (w - 1);
469  int nv, v, code = codes & 3;
470 
471  pos = x;
472  dy = y + count;
473  dst = (uint32_t *)frame->data[0] + pos + dy * l;
474  if (code & 1)
475  bcode = bytestream2_get_byte(gb);
476  if (code == 3) {
477  for (int j = 0; j < 4; j++) {
478  switch (bcode & 3) {
479  case 0:
480  break;
481  case 1:
482  if (dy < 1 && !pos)
483  return AVERROR_INVALIDDATA;
484  dst[0] = dst[-1];
485  break;
486  case 2:
487  if (dy < 1)
488  return AVERROR_INVALIDDATA;
489  dst[0] = dst[-l];
490  break;
491  case 3:
492  if (astate) {
493  nv = value >> 4;
494  } else {
495  value = bytestream2_get_byte(gb);
496  nv = value & 0xF;
497  }
498  astate ^= 1;
499  dst[0] = src[av_clip(l * (dy + s->mv1[nv][1]) + pos +
500  s->mv1[nv][0], 0, src_size)];
501  break;
502  }
503 
504  bcode >>= 2;
505  dst++;
506  pos++;
507  }
508  } else if (code) {
509  if (code == 1)
510  v14 = bcode;
511  else
512  bcode = v14;
513  for (int j = 0; j < 4; j++) {
514  switch (bcode & 3) {
515  case 0:
516  break;
517  case 1:
518  if (dy < 1 && !pos)
519  return AVERROR_INVALIDDATA;
520  dst[0] = dst[-1];
521  break;
522  case 2:
523  if (dy < 1)
524  return AVERROR_INVALIDDATA;
525  dst[0] = dst[-l];
526  break;
527  case 3:
528  v = bytestream2_get_byte(gb);
529  if (v < 128) {
530  dst[0] = src[av_clip(l * (dy + s->mv0[v][1]) + pos +
531  s->mv0[v][0], 0, src_size)];
532  } else {
533  dst[0] = ((v & 0x7F) << 17) | bytestream2_get_be16(gb);
534  }
535  break;
536  }
537 
538  bcode >>= 2;
539  dst++;
540  pos++;
541  }
542  }
543 
544  codes >>= 2;
545  }
546  }
547 
548  di++;
549  }
550  }
551  break;
552  default:
553  return AVERROR_INVALIDDATA;
554  }
555  }
556 
557  return AVERROR_INVALIDDATA;
558 }
559 
561 {
562  ArgoContext *s = avctx->priv_data;
563  GetByteContext *gb = &s->gb;
564  const int w = frame->width;
565  const int h = frame->height;
566  const int l = frame->linesize[0];
567  uint8_t *dst = frame->data[0];
568  int pos = 0, y = 0;
569 
570  while (bytestream2_get_bytes_left(gb) > 0) {
571  int count = bytestream2_get_byte(gb);
572  int pixel = bytestream2_get_byte(gb);
573 
574  if (!count) {
575  pos += pixel;
576  while (pos >= w) {
577  pos -= w;
578  y++;
579  if (y >= h)
580  return 0;
581  }
582  } else {
583  while (count > 0) {
584  dst[pos + y * l] = pixel;
585  count--;
586  pos++;
587  if (pos >= w) {
588  pos = 0;
589  y++;
590  if (y >= h)
591  return 0;
592  }
593  }
594  }
595  }
596 
597  return 0;
598 }
599 
600 static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
601  int *got_frame, AVPacket *avpkt)
602 {
603  ArgoContext *s = avctx->priv_data;
604  GetByteContext *gb = &s->gb;
605  AVFrame *frame = s->frame;
606  uint32_t chunk;
607  int ret;
608 
609  if (avpkt->size < 4)
610  return AVERROR_INVALIDDATA;
611 
612  bytestream2_init(gb, avpkt->data, avpkt->size);
613 
614  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
615  return ret;
616 
617  chunk = bytestream2_get_be32(gb);
618  switch (chunk) {
619  case MKBETAG('P', 'A', 'L', '8'):
620  for (int y = 0; y < frame->height; y++)
621  memset(frame->data[0] + y * frame->linesize[0], 0, frame->width * s->bpp);
622  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
623  memset(frame->data[1], 0, AVPALETTE_SIZE);
624  return decode_pal8(avctx, s->pal);
625  case MKBETAG('M', 'A', 'D', '1'):
626  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
627  ret = decode_mad1(avctx, frame);
628  else
629  ret = decode_mad1_24(avctx, frame);
630  break;
631  case MKBETAG('A', 'V', 'C', 'F'):
632  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
633  s->key = 1;
634  ret = decode_avcf(avctx, frame);
635  break;
636  }
637  case MKBETAG('A', 'L', 'C', 'D'):
638  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
639  s->key = 0;
640  ret = decode_alcd(avctx, frame);
641  break;
642  }
643  case MKBETAG('R', 'L', 'E', 'F'):
644  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
645  s->key = 1;
646  ret = decode_rle(avctx, frame);
647  break;
648  }
649  case MKBETAG('R', 'L', 'E', 'D'):
650  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
651  s->key = 0;
652  ret = decode_rle(avctx, frame);
653  break;
654  }
655  default:
656  av_log(avctx, AV_LOG_DEBUG, "unknown chunk 0x%X\n", chunk);
657  break;
658  }
659 
660  if (ret < 0)
661  return ret;
662 
663  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
664  memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
665 
666  if ((ret = av_frame_ref(rframe, s->frame)) < 0)
667  return ret;
668 
669  frame->pict_type = s->key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
670  if (s->key)
671  frame->flags |= AV_FRAME_FLAG_KEY;
672  else
673  frame->flags &= ~AV_FRAME_FLAG_KEY;
674  *got_frame = 1;
675 
676  return avpkt->size;
677 }
678 
680 {
681  ArgoContext *s = avctx->priv_data;
682 
683  switch (avctx->bits_per_coded_sample) {
684  case 8: s->bpp = 1;
685  avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
686  case 24: s->bpp = 4;
687  avctx->pix_fmt = AV_PIX_FMT_BGR0; break;
688  default: avpriv_request_sample(s, "depth == %u", avctx->bits_per_coded_sample);
689  return AVERROR_PATCHWELCOME;
690  }
691 
692  if (avctx->width % 2 || avctx->height % 2) {
693  avpriv_request_sample(s, "Odd dimensions\n");
694  return AVERROR_PATCHWELCOME;
695  }
696 
697  s->frame = av_frame_alloc();
698  if (!s->frame)
699  return AVERROR(ENOMEM);
700 
701  for (int n = 0, i = -4; i < 4; i++) {
702  for (int j = -14; j < 2; j++) {
703  s->mv0[n][0] = j;
704  s->mv0[n++][1] = i;
705  }
706  }
707 
708  for (int n = 0, i = -5; i <= 1; i += 2) {
709  int j = -5;
710 
711  while (j <= 1) {
712  s->mv1[n][0] = j;
713  s->mv1[n++][1] = i;
714  j += 2;
715  }
716  }
717 
718  return 0;
719 }
720 
722 {
723  ArgoContext *s = avctx->priv_data;
724 
725  av_frame_unref(s->frame);
726 }
727 
729 {
730  ArgoContext *s = avctx->priv_data;
731 
732  av_frame_free(&s->frame);
733 
734  return 0;
735 }
736 
738  .p.name = "argo",
739  CODEC_LONG_NAME("Argonaut Games Video"),
740  .p.type = AVMEDIA_TYPE_VIDEO,
741  .p.id = AV_CODEC_ID_ARGO,
742  .priv_data_size = sizeof(ArgoContext),
743  .init = decode_init,
745  .flush = decode_flush,
746  .close = decode_close,
747  .p.capabilities = AV_CODEC_CAP_DR1,
748  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
749 };
decode_close
static av_cold int decode_close(AVCodecContext *avctx)
Definition: argo.c:728
av_clip
#define av_clip
Definition: common.h:100
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
AVERROR
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
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
GetByteContext
Definition: bytestream.h:33
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
ArgoContext::frame
AVFrame * frame
Definition: argo.c:41
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
w
uint8_t w
Definition: llviddspenc.c:38
AVPacket::data
uint8_t * data
Definition: packet.h:558
b
#define b
Definition: input.c:42
FFCodec
Definition: codec_internal.h:127
ArgoContext::gb
GetByteContext gb
Definition: argo.c:34
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
mx
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
Definition: dsp.h:57
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ArgoContext::mv1
int mv1[16][2]
Definition: argo.c:39
type
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 type
Definition: writing_filters.txt:86
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
av_cold
#define av_cold
Definition: attributes.h:90
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:642
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:346
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
AV_CODEC_ID_ARGO
@ AV_CODEC_ID_ARGO
Definition: codec_id.h:311
bits
uint8_t bits
Definition: vp3data.h:128
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
decode.h
ArgoContext::key
int key
Definition: argo.c:37
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:331
my
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
Definition: dsp.h:57
if
if(ret)
Definition: filter_design.txt:179
ArgoContext
Definition: argo.c:33
decode_avcf
static int decode_avcf(AVCodecContext *avctx, AVFrame *frame)
Definition: argo.c:65
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
pixel
uint8_t pixel
Definition: tiny_ssim.c:41
decode_rle
static int decode_rle(AVCodecContext *avctx, AVFrame *frame)
Definition: argo.c:560
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
decode_frame
static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: argo.c:600
decode_mad1
static int decode_mad1(AVCodecContext *avctx, AVFrame *frame)
Definition: argo.c:142
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:559
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:278
codec_internal.h
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
size
int size
Definition: twinvq_data.h:10344
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
ArgoContext::pal
uint32_t pal[256]
Definition: argo.c:40
ArgoContext::mv0
int mv0[128][2]
Definition: argo.c:38
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
attributes.h
decode_alcd
static int decode_alcd(AVCodecContext *avctx, AVFrame *frame)
Definition: argo.c:94
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1546
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
code
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
Definition: filter_design.txt:178
ArgoContext::bpp
int bpp
Definition: argo.c:36
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
internal.h
value
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 default value
Definition: writing_filters.txt:86
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
decode_pal8
static int decode_pal8(AVCodecContext *avctx, uint32_t *pal)
Definition: argo.c:44
avcodec.h
decode_flush
static av_cold void decode_flush(AVCodecContext *avctx)
Definition: argo.c:721
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ff_reget_buffer
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:1840
ret
ret
Definition: filter_design.txt:187
frame
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
Definition: filter_design.txt:265
pos
unsigned int pos
Definition: spdifenc.c:414
ff_argo_decoder
const FFCodec ff_argo_decoder
Definition: argo.c:737
AVCodecContext
main external API structure.
Definition: avcodec.h:431
decode_mad1_24
static int decode_mad1_24(AVCodecContext *avctx, AVFrame *frame)
Definition: argo.c:352
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
bytestream2_get_bufferu
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:277
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
AVPacket
This structure stores compressed data.
Definition: packet.h:535
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2070
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: argo.c:679
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:383
src
#define src
Definition: vp8dsp.c:248
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:368