FFmpeg
gdv.c
Go to the documentation of this file.
1 /*
2  * Gremlin Digital Video (GDV) decoder
3  * Copyright (c) 2017 Konstantin Shishkov
4  * Copyright (c) 2017 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/common.h"
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "decode.h"
27 #include "internal.h"
28 
29 typedef struct GDVContext {
31 
35 
36  uint32_t pal[256];
37  uint8_t *frame;
38  unsigned frame_size;
39  unsigned scale_h, scale_v;
40 } GDVContext;
41 
42 typedef struct Bits8 {
43  uint8_t queue;
44  uint8_t fill;
45 } Bits8;
46 
47 typedef struct Bits32 {
48  uint32_t queue;
49  uint8_t fill;
50 } Bits32;
51 
52 #define PREAMBLE_SIZE 4096
53 
55 {
56  GDVContext *gdv = avctx->priv_data;
57  int i, j, k;
58 
59  avctx->pix_fmt = AV_PIX_FMT_PAL8;
60  gdv->frame_size = avctx->width * avctx->height + PREAMBLE_SIZE;
61  gdv->frame = av_calloc(gdv->frame_size, 1);
62  if (!gdv->frame)
63  return AVERROR(ENOMEM);
64 
65  for (i = 0; i < 2; i++) {
66  for (j = 0; j < 256; j++) {
67  for (k = 0; k < 8; k++) {
68  gdv->frame[i * 2048 + j * 8 + k] = j;
69  }
70  }
71  }
72 
73  return 0;
74 }
75 
76 static void scaleup(uint8_t *dst, const uint8_t *src, int w)
77 {
78  int x;
79  for (x = 0; x < w - 7; x+=8) {
80  dst[x + 0] =
81  dst[x + 1] = src[(x>>1) + 0];
82  dst[x + 2] =
83  dst[x + 3] = src[(x>>1) + 1];
84  dst[x + 4] =
85  dst[x + 5] = src[(x>>1) + 2];
86  dst[x + 6] =
87  dst[x + 7] = src[(x>>1) + 3];
88  }
89  for (; x < w; x++) {
90  dst[x] = src[(x>>1)];
91  }
92 }
93 
94 static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w)
95 {
96  int x;
97 
98  for (x = w - 1; (x+1) & 7; x--) {
99  dst[x] = src[(x>>1)];
100  }
101  for (x -= 7; x >= 0; x -= 8) {
102  dst[x + 6] =
103  dst[x + 7] = src[(x>>1) + 3];
104  dst[x + 4] =
105  dst[x + 5] = src[(x>>1) + 2];
106  dst[x + 2] =
107  dst[x + 3] = src[(x>>1) + 1];
108  dst[x + 0] =
109  dst[x + 1] = src[(x>>1) + 0];
110  }
111 }
112 
113 static void scaledown(uint8_t *dst, const uint8_t *src, int w)
114 {
115  int x;
116  for (x = 0; x < w - 7; x+=8) {
117  dst[x + 0] = src[2*x + 0];
118  dst[x + 1] = src[2*x + 2];
119  dst[x + 2] = src[2*x + 4];
120  dst[x + 3] = src[2*x + 6];
121  dst[x + 4] = src[2*x + 8];
122  dst[x + 5] = src[2*x +10];
123  dst[x + 6] = src[2*x +12];
124  dst[x + 7] = src[2*x +14];
125  }
126  for (; x < w; x++) {
127  dst[x] = src[2*x];
128  }
129 }
130 
131 static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h)
132 {
133  int j, y;
134 
135  if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) {
136  return;
137  }
138 
139  if (gdv->scale_v) {
140  for (j = 0; j < h; j++) {
141  int y = h - j - 1;
142  uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
143  uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1);
144 
145  scaleup_rev(dst1, src1, w);
146  }
147  } else if (gdv->scale_h) {
148  for (j = 0; j < h; j++) {
149  int y = h - j - 1;
150  uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
151  uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>1) * w;
152  memcpy(dst1, src1, w);
153  }
154  }
155 
156  if (scale_h && scale_v) {
157  for (y = 0; y < (h>>1); y++) {
158  uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1);
159  uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
160  scaledown(dst1, src1, w>>1);
161  }
162  } else if (scale_h) {
163  for (y = 0; y < (h>>1); y++) {
164  uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
165  uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
166  memcpy(dst1, src1, w);
167  }
168  } else if (scale_v) {
169  for (y = 0; y < h; y++) {
170  uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
171  scaledown(dst1, dst1, w>>1);
172  }
173  }
174 
175  gdv->scale_v = scale_v;
176  gdv->scale_h = scale_h;
177 }
178 
180 {
181  int res;
182 
183  if (bits->fill == 0) {
184  bits->queue |= bytestream2_get_byte(gb);
185  bits->fill = 8;
186  }
187  res = bits->queue >> 6;
188  bits->queue <<= 2;
189  bits->fill -= 2;
190 
191  return res;
192 }
193 
195 {
196  bits->queue = bytestream2_get_le32(gb);
197  bits->fill = 32;
198 }
199 
200 static int read_bits32(Bits32 *bits, GetByteContext *gb, int nbits)
201 {
202  int res = bits->queue & ((1 << nbits) - 1);
203 
204  bits->queue >>= nbits;
205  bits->fill -= nbits;
206  if (bits->fill <= 16) {
207  bits->queue |= bytestream2_get_le16(gb) << bits->fill;
208  bits->fill += 16;
209  }
210 
211  return res;
212 }
213 
214 static void lz_copy(PutByteContext *pb, GetByteContext *g2, int offset, unsigned len)
215 {
216  int i;
217 
218  if (offset == -1) {
219  int c;
220 
221  bytestream2_seek(g2, bytestream2_tell_p(pb) - 1, SEEK_SET);
222  c = bytestream2_get_byte(g2);
223  for (i = 0; i < len; i++) {
224  bytestream2_put_byte(pb, c);
225  }
226  } else if (offset < 0) {
227  int start = bytestream2_tell_p(pb) - (-offset);
228 
229  bytestream2_seek(g2, start, SEEK_SET);
230  for (i = 0; i < len; i++) {
231  bytestream2_put_byte(pb, bytestream2_get_byte(g2));
232  }
233  } else {
234  int start = bytestream2_tell_p(pb) + offset;
235 
236  bytestream2_seek(g2, start, SEEK_SET);
237  for (i = 0; i < len; i++) {
238  bytestream2_put_byte(pb, bytestream2_get_byte(g2));
239  }
240  }
241 }
242 
243 static int decompress_2(AVCodecContext *avctx)
244 {
245  GDVContext *gdv = avctx->priv_data;
246  GetByteContext *gb = &gdv->gb;
247  GetByteContext *g2 = &gdv->g2;
248  PutByteContext *pb = &gdv->pb;
249  Bits8 bits = { 0 };
250  int c, i;
251 
252  bytestream2_init(g2, gdv->frame, gdv->frame_size);
254 
255  for (c = 0; c < 256; c++) {
256  for (i = 0; i < 16; i++) {
257  gdv->frame[c * 16 + i] = c;
258  }
259  }
260 
261  while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
262  int tag = read_bits2(&bits, gb);
263  if (tag == 0) {
264  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
265  } else if (tag == 1) {
266  int b = bytestream2_get_byte(gb);
267  int len = (b & 0xF) + 3;
268  int top = (b >> 4) & 0xF;
269  int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
270  lz_copy(pb, g2, off, len);
271  } else if (tag == 2) {
272  int len = (bytestream2_get_byte(gb)) + 2;
273  bytestream2_skip_p(pb, len);
274  } else {
275  break;
276  }
277  }
278 
279  if (bytestream2_get_bytes_left_p(pb) > 0)
280  return AVERROR_INVALIDDATA;
281 
282  return 0;
283 }
284 
285 static int decompress_5(AVCodecContext *avctx, unsigned skip)
286 {
287  GDVContext *gdv = avctx->priv_data;
288  GetByteContext *gb = &gdv->gb;
289  GetByteContext *g2 = &gdv->g2;
290  PutByteContext *pb = &gdv->pb;
291  Bits8 bits = { 0 };
292 
293  bytestream2_init(g2, gdv->frame, gdv->frame_size);
294  bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
295 
296  while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
297  int tag = read_bits2(&bits, gb);
298  if (bytestream2_get_bytes_left(gb) < 1)
299  return AVERROR_INVALIDDATA;
300  if (tag == 0) {
301  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
302  } else if (tag == 1) {
303  int b = bytestream2_get_byte(gb);
304  int len = (b & 0xF) + 3;
305  int top = b >> 4;
306  int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
307  lz_copy(pb, g2, off, len);
308  } else if (tag == 2) {
309  int len;
310  int b = bytestream2_get_byte(gb);
311  if (b == 0) {
312  return 0;
313  }
314  if (b != 0xFF) {
315  len = b;
316  } else {
317  len = bytestream2_get_le16(gb);
318  }
319  bytestream2_skip_p(pb, len + 1);
320  } else {
321  int b = bytestream2_get_byte(gb);
322  int len = (b & 0x3) + 2;
323  int off = -(b >> 2) - 1;
324  lz_copy(pb, g2, off, len);
325  }
326  }
327  if (bytestream2_get_bytes_left_p(pb) > 0)
328  return AVERROR_INVALIDDATA;
329  return 0;
330 }
331 
332 static int decompress_68(AVCodecContext *avctx, unsigned skip, unsigned use8)
333 {
334  GDVContext *gdv = avctx->priv_data;
335  GetByteContext *gb = &gdv->gb;
336  GetByteContext *g2 = &gdv->g2;
337  PutByteContext *pb = &gdv->pb;
338  Bits32 bits;
339 
340  bytestream2_init(g2, gdv->frame, gdv->frame_size);
341  bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
342  fill_bits32(&bits, gb);
343 
344  while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
345  int tag = read_bits32(&bits, gb, 2);
346  if (tag == 0) {
347  int b = read_bits32(&bits, gb, 1);
348  if (b == 0) {
349  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
350  } else {
351  int i, len = 2;
352  int lbits = 0;
353  while (1) {
354  int val;
355 
356  lbits += 1;
357  val = read_bits32(&bits, gb, lbits);
358  len += val;
359  if (val != ((1 << lbits) - 1)) {
360  break;
361  }
362  if (lbits >= 16)
363  return AVERROR_INVALIDDATA;
364  }
365  for (i = 0; i < len; i++) {
366  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
367  }
368  }
369  } else if (tag == 1) {
370  int b = read_bits32(&bits, gb, 1);
371  int len;
372 
373  if (b == 0) {
374  len = (read_bits32(&bits, gb, 4)) + 2;
375  } else {
376  int bb = bytestream2_get_byte(gb);
377  if ((bb & 0x80) == 0) {
378  len = bb + 18;
379  } else {
380  int top = (bb & 0x7F) << 8;
381  len = top + bytestream2_get_byte(gb) + 146;
382  }
383  }
384  bytestream2_skip_p(pb, len);
385  } else if (tag == 2) {
386  int i, subtag = read_bits32(&bits, gb, 2);
387 
388  if (subtag != 3) {
389  int top = (read_bits32(&bits, gb, 4)) << 8;
390  int offs = top + bytestream2_get_byte(gb);
391  if ((subtag != 0) || (offs <= 0xF80)) {
392  int len = (subtag) + 3;
393  lz_copy(pb, g2, (offs) - 4096, len);
394  } else {
395  int real_off, len, c1, c2;
396 
397  if (offs == 0xFFF) {
398  return 0;
399  }
400 
401  real_off = ((offs >> 4) & 0x7) + 1;
402  len = ((offs & 0xF) + 2) * 2;
403  c1 = gdv->frame[bytestream2_tell_p(pb) - real_off];
404  c2 = gdv->frame[bytestream2_tell_p(pb) - real_off + 1];
405  for (i = 0; i < len/2; i++) {
406  bytestream2_put_byte(pb, c1);
407  bytestream2_put_byte(pb, c2);
408  }
409  }
410  } else {
411  int b = bytestream2_get_byte(gb);
412  int off = ((b & 0x7F)) + 1;
413  int len = ((b & 0x80) == 0) ? 2 : 3;
414 
415  lz_copy(pb, g2, -off, len);
416  }
417  } else {
418  int len;
419  int off;
420  if (use8) {
421  int q, b = bytestream2_get_byte(gb);
422  if ((b & 0xC0) == 0xC0) {
423  len = ((b & 0x3F)) + 8;
424  q = read_bits32(&bits, gb, 4);
425  off = (q << 8) + (bytestream2_get_byte(gb)) + 1;
426  } else {
427  int ofs1;
428  if ((b & 0x80) == 0) {
429  len = ((b >> 4)) + 6;
430  ofs1 = (b & 0xF);
431  } else {
432  len = ((b & 0x3F)) + 14;
433  ofs1 = read_bits32(&bits, gb, 4);
434  }
435  off = (ofs1 << 8) + (bytestream2_get_byte(gb)) - 4096;
436  }
437  } else {
438  int ofs1, b = bytestream2_get_byte(gb);
439 
440  if ((b >> 4) == 0xF) {
441  len = bytestream2_get_byte(gb) + 21;
442  } else {
443  len = (b >> 4) + 6;
444  }
445  ofs1 = (b & 0xF);
446  off = (ofs1 << 8) + bytestream2_get_byte(gb) - 4096;
447  }
448  lz_copy(pb, g2, off, len);
449  }
450  }
451 
452  if (bytestream2_get_bytes_left_p(pb) > 0)
453  return AVERROR_INVALIDDATA;
454 
455  return 0;
456 }
457 
458 static int gdv_decode_frame(AVCodecContext *avctx, void *data,
459  int *got_frame, AVPacket *avpkt)
460 {
461  GDVContext *gdv = avctx->priv_data;
462  GetByteContext *gb = &gdv->gb;
463  PutByteContext *pb = &gdv->pb;
464  AVFrame *frame = data;
465  int ret, i;
466  int compression;
467  unsigned flags;
468  uint8_t *dst;
469 
470  bytestream2_init(gb, avpkt->data, avpkt->size);
471  bytestream2_init_writer(pb, gdv->frame, gdv->frame_size);
472 
473  flags = bytestream2_get_le32(gb);
474  compression = flags & 0xF;
475 
476  if (compression == 4 || compression == 7 || compression > 8)
477  return AVERROR_INVALIDDATA;
478 
479  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
480  return ret;
481  ff_copy_palette(gdv->pal, avpkt, avctx);
482 
483  if (compression < 2 && bytestream2_get_bytes_left(gb) < 256*3)
484  return AVERROR_INVALIDDATA;
485  rescale(gdv, gdv->frame, avctx->width, avctx->height,
486  !!(flags & 0x10), !!(flags & 0x20));
487 
488  switch (compression) {
489  case 1:
490  memset(gdv->frame + PREAMBLE_SIZE, 0, gdv->frame_size - PREAMBLE_SIZE);
491  case 0:
492  for (i = 0; i < 256; i++) {
493  unsigned r = bytestream2_get_byte(gb);
494  unsigned g = bytestream2_get_byte(gb);
495  unsigned b = bytestream2_get_byte(gb);
496  gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2;
497  }
498  break;
499  case 2:
500  ret = decompress_2(avctx);
501  break;
502  case 3:
503  break;
504  case 5:
505  ret = decompress_5(avctx, flags >> 8);
506  break;
507  case 6:
508  ret = decompress_68(avctx, flags >> 8, 0);
509  break;
510  case 8:
511  ret = decompress_68(avctx, flags >> 8, 1);
512  break;
513  default:
514  av_assert0(0);
515  }
516  if (ret < 0)
517  return ret;
518 
519  memcpy(frame->data[1], gdv->pal, AVPALETTE_SIZE);
520  dst = frame->data[0];
521 
522  if (!gdv->scale_v && !gdv->scale_h) {
523  int sidx = PREAMBLE_SIZE, didx = 0;
524  int y;
525 
526  for (y = 0; y < avctx->height; y++) {
527  memcpy(dst + didx, gdv->frame + sidx, avctx->width);
528  sidx += avctx->width;
529  didx += frame->linesize[0];
530  }
531  } else {
532  int sidx = PREAMBLE_SIZE, didx = 0;
533  int y;
534 
535  for (y = 0; y < avctx->height; y++) {
536  if (!gdv->scale_v) {
537  memcpy(dst + didx, gdv->frame + sidx, avctx->width);
538  } else {
539  uint8_t *dst2 = dst + didx;
540  uint8_t *src2 = gdv->frame + sidx;
541 
542  scaleup(dst2, src2, avctx->width);
543  }
544  if (!gdv->scale_h || ((y & 1) == 1)) {
545  sidx += !gdv->scale_v ? avctx->width : avctx->width/2;
546  }
547  didx += frame->linesize[0];
548  }
549  }
550 
551  *got_frame = 1;
552 
553  return avpkt->size;
554 }
555 
557 {
558  GDVContext *gdv = avctx->priv_data;
559  av_freep(&gdv->frame);
560  return 0;
561 }
562 
564  .name = "gdv",
565  .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
566  .type = AVMEDIA_TYPE_VIDEO,
567  .id = AV_CODEC_ID_GDV,
568  .priv_data_size = sizeof(GDVContext),
570  .close = gdv_decode_close,
572  .capabilities = AV_CODEC_CAP_DR1,
573  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
574 };
AVCodec
AVCodec.
Definition: codec.h:202
GDVContext::pb
PutByteContext pb
Definition: gdv.c:34
FF_CODEC_CAP_INIT_THREADSAFE
#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:42
r
const char * r
Definition: vf_curves.c:116
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
GetByteContext
Definition: bytestream.h:33
decompress_2
static int decompress_2(AVCodecContext *avctx)
Definition: gdv.c:243
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:212
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
b
#define b
Definition: input.c:40
decompress_68
static int decompress_68(AVCodecContext *avctx, unsigned skip, unsigned use8)
Definition: gdv.c:332
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:197
data
const char data[16]
Definition: mxf.c:143
GDVContext::avctx
AVCodecContext * avctx
Definition: gdv.c:30
AV_CODEC_ID_GDV
@ AV_CODEC_ID_GDV
Definition: codec_id.h:284
c1
static const uint64_t c1
Definition: murmur3.c:51
Bits32::fill
uint8_t fill
Definition: gdv.c:49
GDVContext::frame
uint8_t * frame
Definition: gdv.c:37
GDVContext::frame_size
unsigned frame_size
Definition: gdv.c:38
init
static int init
Definition: av_tx.c:47
U
#define U(x)
Definition: vp56_arith.h:37
val
static double val(void *priv, double ch)
Definition: aeval.c:76
PREAMBLE_SIZE
#define PREAMBLE_SIZE
Definition: gdv.c:52
scaleup
static void scaleup(uint8_t *dst, const uint8_t *src, int w)
Definition: gdv.c:76
bytestream2_get_bytes_left_p
static av_always_inline int bytestream2_get_bytes_left_p(PutByteContext *p)
Definition: bytestream.h:163
av_cold
#define av_cold
Definition: attributes.h:90
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
read_bits2
static int read_bits2(Bits8 *bits, GetByteContext *gb)
Definition: gdv.c:179
g
const char * g
Definition: vf_curves.c:117
bits
uint8_t bits
Definition: vp3data.h:141
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
gdv_decode_init
static av_cold int gdv_decode_init(AVCodecContext *avctx)
Definition: gdv.c:54
GDVContext::scale_v
unsigned scale_v
Definition: gdv.c:39
decode.h
lz_copy
static void lz_copy(PutByteContext *pb, GetByteContext *g2, int offset, unsigned len)
Definition: gdv.c:214
Bits8
Definition: gdv.c:42
Bits8::fill
uint8_t fill
Definition: gdv.c:44
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
src
#define src
Definition: vp8dsp.c:255
Bits32::queue
uint32_t queue
Definition: gdv.c:48
gdv_decode_close
static av_cold int gdv_decode_close(AVCodecContext *avctx)
Definition: gdv.c:556
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
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
PutByteContext
Definition: bytestream.h:37
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1652
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:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
rescale
static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h)
Definition: gdv.c:131
ff_gdv_decoder
const AVCodec ff_gdv_decoder
Definition: gdv.c:563
GDVContext
Definition: gdv.c:29
fill_bits32
static void fill_bits32(Bits32 *bits, GetByteContext *gb)
Definition: gdv.c:194
offset
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
Definition: writing_filters.txt:86
src1
#define src1
Definition: h264pred.c:140
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
scaledown
static void scaledown(uint8_t *dst, const uint8_t *src, int w)
Definition: gdv.c:113
bytestream2_skip_p
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition: bytestream.h:180
common.h
gdv_decode_frame
static int gdv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: gdv.c:458
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
GDVContext::pal
uint32_t pal[256]
Definition: gdv.c:36
tag
uint32_t tag
Definition: movenc.c:1596
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:264
scaleup_rev
static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w)
Definition: gdv.c:94
GDVContext::g2
GetByteContext g2
Definition: gdv.c:33
AVCodecContext
main external API structure.
Definition: avcodec.h:383
c2
static const uint64_t c2
Definition: murmur3.c:52
decompress_5
static int decompress_5(AVCodecContext *avctx, unsigned skip)
Definition: gdv.c:285
GDVContext::gb
GetByteContext gb
Definition: gdv.c:32
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
Bits8::queue
uint8_t queue
Definition: gdv.c:43
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
GDVContext::scale_h
unsigned scale_h
Definition: gdv.c:39
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2038
Bits32
Definition: gdv.c:47
ff_copy_palette
int ff_copy_palette(void *dst, const AVPacket *src, void *logctx)
Check whether the side-data of src contains a palette of size AVPALETTE_SIZE; if so,...
Definition: decode.c:1854
read_bits32
static int read_bits32(Bits32 *bits, GetByteContext *gb, int nbits)
Definition: gdv.c:200