FFmpeg
pafvideo.c
Go to the documentation of this file.
1 /*
2  * Packed Animation File video decoder
3  * Copyright (c) 2012 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 "libavutil/attributes.h"
23 #include "libavutil/imgutils.h"
24 #include "libavutil/mem.h"
25 
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "copy_block.h"
29 #include "codec_internal.h"
30 #include "decode.h"
31 
32 
33 static const uint8_t block_sequences[16][8] = {
34  { 0, 0, 0, 0, 0, 0, 0, 0 },
35  { 2, 0, 0, 0, 0, 0, 0, 0 },
36  { 5, 7, 0, 0, 0, 0, 0, 0 },
37  { 5, 0, 0, 0, 0, 0, 0, 0 },
38  { 6, 0, 0, 0, 0, 0, 0, 0 },
39  { 5, 7, 5, 7, 0, 0, 0, 0 },
40  { 5, 7, 5, 0, 0, 0, 0, 0 },
41  { 5, 7, 6, 0, 0, 0, 0, 0 },
42  { 5, 5, 0, 0, 0, 0, 0, 0 },
43  { 3, 0, 0, 0, 0, 0, 0, 0 },
44  { 6, 6, 0, 0, 0, 0, 0, 0 },
45  { 2, 4, 0, 0, 0, 0, 0, 0 },
46  { 2, 4, 5, 7, 0, 0, 0, 0 },
47  { 2, 4, 5, 0, 0, 0, 0, 0 },
48  { 2, 4, 6, 0, 0, 0, 0, 0 },
49  { 2, 4, 5, 7, 5, 7, 0, 0 },
50 };
51 
52 typedef struct PAFVideoDecContext {
55 
56  int width;
57  int height;
58 
60  uint8_t *frame[4];
61  int dirty[4];
64 
65  uint8_t *opcodes;
67 
69 {
70  PAFVideoDecContext *c = avctx->priv_data;
71  int i;
72 
73  av_frame_free(&c->pic);
74 
75  for (i = 0; i < 4; i++)
76  av_freep(&c->frame[i]);
77 
78  return 0;
79 }
80 
82 {
83  PAFVideoDecContext *c = avctx->priv_data;
84  int i;
85  int ret;
86 
87  c->width = avctx->width;
88  c->height = avctx->height;
89 
90  if (avctx->height & 3 || avctx->width & 3) {
91  av_log(avctx, AV_LOG_ERROR,
92  "width %d and height %d must be multiplie of 4.\n",
93  avctx->width, avctx->height);
94  return AVERROR_INVALIDDATA;
95  }
96 
97  avctx->pix_fmt = AV_PIX_FMT_PAL8;
98  ret = av_image_check_size2(avctx->width, FFALIGN(avctx->height, 256), avctx->max_pixels, avctx->pix_fmt, 0, avctx);
99  if (ret < 0)
100  return ret;
101 
102  c->pic = av_frame_alloc();
103  if (!c->pic)
104  return AVERROR(ENOMEM);
105 
106  c->frame_size = avctx->width * FFALIGN(avctx->height, 256);
107  c->video_size = avctx->width * avctx->height;
108  for (i = 0; i < 4; i++) {
109  c->frame[i] = av_mallocz(c->frame_size);
110  if (!c->frame[i])
111  return AVERROR(ENOMEM);
112  }
113 
114  return 0;
115 }
116 
117 static void read4x4block(PAFVideoDecContext *c, uint8_t *dst, int width)
118 {
119  int i;
120 
121  for (i = 0; i < 4; i++) {
122  bytestream2_get_buffer(&c->gb, dst, 4);
123  dst += width;
124  }
125 }
126 
127 static void copy_color_mask(uint8_t *dst, int width, uint8_t mask, uint8_t color)
128 {
129  int i;
130 
131  for (i = 0; i < 4; i++) {
132  if (mask & (1 << 7 - i))
133  dst[i] = color;
134  if (mask & (1 << 3 - i))
135  dst[width + i] = color;
136  }
137 }
138 
139 static void copy_src_mask(uint8_t *dst, int width, uint8_t mask, const uint8_t *src)
140 {
141  int i;
142 
143  for (i = 0; i < 4; i++) {
144  if (mask & (1 << 7 - i))
145  dst[i] = src[i];
146  if (mask & (1 << 3 - i))
147  dst[width + i] = src[width + i];
148  }
149 }
150 
152  const uint8_t **p,
153  const uint8_t **pend)
154 {
155  int val = bytestream2_get_be16(&c->gb);
156  int page = val >> 14;
157  int x = (val & 0x7F);
158  int y = ((val >> 7) & 0x7F);
159 
160  *p = c->frame[page] + x * 2 + y * 2 * c->width;
161  *pend = c->frame[page] + c->frame_size;
162 }
163 
164 static int decode_0(PAFVideoDecContext *c, const uint8_t *pkt, uint8_t code)
165 {
166  uint32_t opcode_size, offset;
167  uint8_t *dst, *dend, mask = 0, color = 0;
168  const uint8_t *src, *send, *opcodes;
169  int i, j, op = 0;
170 
171  i = bytestream2_get_byte(&c->gb);
172  if (i) {
173  if (code & 0x10) {
174  int align;
175 
176  align = bytestream2_tell(&c->gb) & 3;
177  if (align)
178  bytestream2_skip(&c->gb, 4 - align);
179  }
180  do {
181  int page, val, x, y;
182  val = bytestream2_get_be16(&c->gb);
183  page = val >> 14;
184  x = (val & 0x7F) * 2;
185  y = ((val >> 7) & 0x7F) * 2;
186  dst = c->frame[page] + x + y * c->width;
187  dend = c->frame[page] + c->frame_size;
188  offset = (x & 0x7F) * 2;
189  j = bytestream2_get_le16(&c->gb) + offset;
190  if (bytestream2_get_bytes_left(&c->gb) < (j - offset) * 16)
191  return AVERROR_INVALIDDATA;
192  c->dirty[page] = 1;
193  do {
194  offset++;
195  if (dst + 3 * c->width + 4 > dend)
196  return AVERROR_INVALIDDATA;
197  read4x4block(c, dst, c->width);
198  if ((offset & 0x3F) == 0)
199  dst += c->width * 3;
200  dst += 4;
201  } while (offset < j);
202  } while (--i);
203  }
204 
205  dst = c->frame[c->current_frame];
206  dend = c->frame[c->current_frame] + c->frame_size;
207  do {
208  set_src_position(c, &src, &send);
209  if ((src + 3 * c->width + 4 > send) ||
210  (dst + 3 * c->width + 4 > dend) ||
211  bytestream2_get_bytes_left(&c->gb) < 4)
212  return AVERROR_INVALIDDATA;
213  copy_block4(dst, src, c->width, c->width, 4);
214  i++;
215  if ((i & 0x3F) == 0)
216  dst += c->width * 3;
217  dst += 4;
218  } while (i < c->video_size / 16);
219 
220  opcode_size = bytestream2_get_le16(&c->gb);
221  bytestream2_skip(&c->gb, 2);
222 
223  if (bytestream2_get_bytes_left(&c->gb) < opcode_size)
224  return AVERROR_INVALIDDATA;
225 
226  opcodes = pkt + bytestream2_tell(&c->gb);
227  bytestream2_skipu(&c->gb, opcode_size);
228 
229  dst = c->frame[c->current_frame];
230 
231  for (i = 0; i < c->height; i += 4, dst += c->width * 3)
232  for (j = 0; j < c->width; j += 4, dst += 4) {
233  int opcode, k = 0;
234  if (op > opcode_size)
235  return AVERROR_INVALIDDATA;
236  if (j & 4) {
237  opcode = opcodes[op] & 15;
238  op++;
239  } else {
240  opcode = opcodes[op] >> 4;
241  }
242 
243  while (block_sequences[opcode][k]) {
244  offset = c->width * 2;
245  code = block_sequences[opcode][k++];
246 
247  switch (code) {
248  case 2:
249  offset = 0;
251  case 3:
252  color = bytestream2_get_byte(&c->gb);
254  case 4:
255  mask = bytestream2_get_byte(&c->gb);
256  copy_color_mask(dst + offset, c->width, mask, color);
257  break;
258  case 5:
259  offset = 0;
261  case 6:
262  set_src_position(c, &src, &send);
264  case 7:
265  if (src + offset + c->width + 4 > send)
266  return AVERROR_INVALIDDATA;
267  mask = bytestream2_get_byte(&c->gb);
268  copy_src_mask(dst + offset, c->width, mask, src + offset);
269  break;
270  }
271  }
272  }
273 
274  return 0;
275 }
276 
277 static int paf_video_decode(AVCodecContext *avctx, AVFrame *rframe,
278  int *got_frame, AVPacket *pkt)
279 {
280  PAFVideoDecContext *c = avctx->priv_data;
281  uint8_t code, *dst, *end;
282  int i, frame, ret;
283 
284  if (pkt->size < 2)
285  return AVERROR_INVALIDDATA;
286 
287  bytestream2_init(&c->gb, pkt->data, pkt->size);
288 
289  code = bytestream2_get_byte(&c->gb);
290  if ((code & 0xF) > 4 || (code & 0xF) == 3) {
291  avpriv_request_sample(avctx, "unknown/invalid code");
292  return AVERROR_INVALIDDATA;
293  }
294 
295  if ((code & 0xF) == 0 &&
296  c->video_size / 32 - (int64_t)bytestream2_get_bytes_left(&c->gb) > c->video_size / 32 * (int64_t)avctx->discard_damaged_percentage / 100)
297  return AVERROR_INVALIDDATA;
298 
299  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
300  return ret;
301 
302  if (code & 0x20) { // frame is keyframe
303  memset(c->pic->data[1], 0, AVPALETTE_SIZE);
304  c->current_frame = 0;
305  c->pic->flags |= AV_FRAME_FLAG_KEY;
306  c->pic->pict_type = AV_PICTURE_TYPE_I;
307  } else {
308  c->pic->flags &= ~AV_FRAME_FLAG_KEY;
309  c->pic->pict_type = AV_PICTURE_TYPE_P;
310  }
311 
312  if (code & 0x40) { // palette update
313  uint32_t *out = (uint32_t *)c->pic->data[1];
314  int index, count;
315 
316  index = bytestream2_get_byte(&c->gb);
317  count = bytestream2_get_byte(&c->gb) + 1;
318 
319  if (index + count > 256)
320  return AVERROR_INVALIDDATA;
321  if (bytestream2_get_bytes_left(&c->gb) < 3 * count)
322  return AVERROR_INVALIDDATA;
323 
324  out += index;
325  for (i = 0; i < count; i++) {
326  unsigned r, g, b;
327 
328  r = bytestream2_get_byteu(&c->gb);
329  r = r << 2 | r >> 4;
330  g = bytestream2_get_byteu(&c->gb);
331  g = g << 2 | g >> 4;
332  b = bytestream2_get_byteu(&c->gb);
333  b = b << 2 | b >> 4;
334  *out++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
335  }
336  }
337 
338  c->dirty[c->current_frame] = 1;
339  if (code & 0x20)
340  for (i = 0; i < 4; i++) {
341  if (c->dirty[i])
342  memset(c->frame[i], 0, c->frame_size);
343  c->dirty[i] = 0;
344  }
345 
346  switch (code & 0x0F) {
347  case 0:
348  /* Block-based motion compensation using 4x4 blocks with either
349  * horizontal or vertical vectors; might incorporate VQ as well. */
350  if ((ret = decode_0(c, pkt->data, code)) < 0)
351  return ret;
352  break;
353  case 1:
354  /* Uncompressed data. This mode specifies that (width * height) bytes
355  * should be copied directly from the encoded buffer into the output. */
356  dst = c->frame[c->current_frame];
357  // possibly chunk length data
358  bytestream2_skip(&c->gb, 2);
359  if (bytestream2_get_bytes_left(&c->gb) < c->video_size)
360  return AVERROR_INVALIDDATA;
361  bytestream2_get_bufferu(&c->gb, dst, c->video_size);
362  break;
363  case 2:
364  /* Copy reference frame: Consume the next byte in the stream as the
365  * reference frame (which should be 0, 1, 2, or 3, and should not be
366  * the same as the current frame number). */
367  frame = bytestream2_get_byte(&c->gb);
368  if (frame > 3)
369  return AVERROR_INVALIDDATA;
370  if (frame != c->current_frame)
371  memcpy(c->frame[c->current_frame], c->frame[frame], c->frame_size);
372  break;
373  case 4:
374  /* Run length encoding.*/
375  dst = c->frame[c->current_frame];
376  end = dst + c->video_size;
377 
378  bytestream2_skip(&c->gb, 2);
379 
380  while (dst < end) {
381  int8_t code;
382  int count;
383 
384  if (bytestream2_get_bytes_left(&c->gb) < 2)
385  return AVERROR_INVALIDDATA;
386 
387  code = bytestream2_get_byteu(&c->gb);
388  count = FFABS(code) + 1;
389 
390  if (dst + count > end)
391  return AVERROR_INVALIDDATA;
392  if (code < 0)
393  memset(dst, bytestream2_get_byteu(&c->gb), count);
394  else
395  bytestream2_get_buffer(&c->gb, dst, count);
396  dst += count;
397  }
398  break;
399  default:
400  av_assert0(0);
401  }
402 
403  av_image_copy_plane(c->pic->data[0], c->pic->linesize[0],
404  c->frame[c->current_frame], c->width,
405  c->width, c->height);
406 
407  c->current_frame = (c->current_frame + 1) & 3;
408  if ((ret = av_frame_ref(rframe, c->pic)) < 0)
409  return ret;
410 
411  *got_frame = 1;
412 
413  return pkt->size;
414 }
415 
417  .p.name = "paf_video",
418  CODEC_LONG_NAME("Amazing Studio Packed Animation File Video"),
419  .p.type = AVMEDIA_TYPE_VIDEO,
420  .p.id = AV_CODEC_ID_PAF_VIDEO,
421  .priv_data_size = sizeof(PAFVideoDecContext),
422  .init = paf_video_init,
425  .p.capabilities = AV_CODEC_CAP_DR1,
426  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
427 };
paf_video_decode
static int paf_video_decode(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *pkt)
Definition: pafvideo.c:277
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:43
PAFVideoDecContext::opcodes
uint8_t * opcodes
Definition: pafvideo.c:65
r
const char * r
Definition: vf_curves.c:127
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
out
static FILE * out
Definition: movenc.c:55
color
Definition: vf_paletteuse.c:513
GetByteContext
Definition: bytestream.h:33
bytestream2_tell
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition: bytestream.h:192
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
int64_t
long long int64_t
Definition: coverity.c:34
PAFVideoDecContext::gb
GetByteContext gb
Definition: pafvideo.c:54
mask
int mask
Definition: mediacodecdec_common.c:154
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:435
PAFVideoDecContext::frame_size
int frame_size
Definition: pafvideo.c:62
AVPacket::data
uint8_t * data
Definition: packet.h:595
b
#define b
Definition: input.c:43
PAFVideoDecContext::frame
uint8_t * frame[4]
Definition: pafvideo.c:60
FFCodec
Definition: codec_internal.h:127
PAFVideoDecContext::width
int width
Definition: pafvideo.c:56
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
val
static double val(void *priv, double ch)
Definition: aeval.c:77
copy_src_mask
static void copy_src_mask(uint8_t *dst, int width, uint8_t mask, const uint8_t *src)
Definition: pafvideo.c:139
av_image_check_size2
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of a plane of an image with...
Definition: imgutils.c:289
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
PAFVideoDecContext::current_frame
int current_frame
Definition: pafvideo.c:59
PAFVideoDecContext
Definition: pafvideo.c:52
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:119
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:650
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:347
g
const char * g
Definition: vf_curves.c:128
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
decode.h
paf_video_init
static av_cold int paf_video_init(AVCodecContext *avctx)
Definition: pafvideo.c:81
AVCodecContext::max_pixels
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition: avcodec.h:1794
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
copy_color_mask
static void copy_color_mask(uint8_t *dst, int width, uint8_t mask, uint8_t color)
Definition: pafvideo.c:127
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
block_sequences
static const uint8_t block_sequences[16][8]
Definition: pafvideo.c:33
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
read4x4block
static void read4x4block(PAFVideoDecContext *c, uint8_t *dst, int width)
Definition: pafvideo.c:117
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
PAFVideoDecContext::video_size
int video_size
Definition: pafvideo.c:63
PAFVideoDecContext::pic
AVFrame * pic
Definition: pafvideo.c:53
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:551
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:596
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:98
PAFVideoDecContext::dirty
int dirty[4]
Definition: pafvideo.c:61
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:419
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
attributes.h
copy_block4
static void copy_block4(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)
Definition: copy_block.h:37
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
copy_block.h
AV_CODEC_ID_PAF_VIDEO
@ AV_CODEC_ID_PAF_VIDEO
Definition: codec_id.h:233
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
AVCodecContext::height
int height
Definition: avcodec.h:600
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:639
avcodec.h
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:1894
ret
ret
Definition: filter_design.txt:187
set_src_position
static void set_src_position(PAFVideoDecContext *c, const uint8_t **p, const uint8_t **pend)
Definition: pafvideo.c:151
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
ff_paf_video_decoder
const FFCodec ff_paf_video_decoder
Definition: pafvideo.c:416
U
#define U(x)
Definition: vpx_arith.h:37
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AVCodecContext::discard_damaged_percentage
int discard_damaged_percentage
The percentage of damaged samples to discard a frame.
Definition: avcodec.h:1829
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
PAFVideoDecContext::height
int height
Definition: pafvideo.c:57
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
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:572
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:600
bytestream.h
imgutils.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
paf_video_close
static av_cold int paf_video_close(AVCodecContext *avctx)
Definition: pafvideo.c:68
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
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
width
#define width
Definition: dsp.h:89
src
#define src
Definition: vp8dsp.c:248
decode_0
static int decode_0(PAFVideoDecContext *c, const uint8_t *pkt, uint8_t code)
Definition: pafvideo.c:164