FFmpeg
fmvc.c
Go to the documentation of this file.
1 /*
2  * FM Screen Capture Codec decoder
3  *
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 <stdio.h>
24 #include <string.h>
25 
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "codec_internal.h"
29 #include "decode.h"
30 
31 #define BLOCK_HEIGHT 112u
32 #define BLOCK_WIDTH 84u
33 
34 typedef struct InterBlock {
35  int w, h;
36  int size;
37  int xor;
38 } InterBlock;
39 
40 typedef struct FMVCContext {
43  uint8_t *buffer;
44  size_t buffer_size;
45  uint8_t *pbuffer;
46  size_t pbuffer_size;
47  ptrdiff_t stride;
48  int bpp;
49  int yb, xb;
51  unsigned nb_blocks;
52 } FMVCContext;
53 
55 {
56  unsigned repeat = 0, first = 1, opcode = 0;
57  int i, len, pos;
58 
59  while (bytestream2_get_bytes_left(gb) > 0) {
60  GetByteContext gbc;
61 
62  while (bytestream2_get_bytes_left(gb) > 0) {
63  if (first) {
64  first = 0;
65  if (bytestream2_peek_byte(gb) > 17) {
66  len = bytestream2_get_byte(gb) - 17;
67  if (len < 4) {
68  do {
69  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
70  --len;
71  } while (len);
72  opcode = bytestream2_peek_byte(gb);
73  continue;
74  } else {
75  do {
76  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
77  --len;
78  } while (len);
79  opcode = bytestream2_peek_byte(gb);
80  if (opcode < 0x10) {
81  bytestream2_skip(gb, 1);
82  pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;
83 
85  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
86 
87  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
88  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
89  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
90  len = opcode & 3;
91  if (!len) {
92  repeat = 1;
93  } else {
94  do {
95  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
96  --len;
97  } while (len);
98  opcode = bytestream2_peek_byte(gb);
99  }
100  continue;
101  }
102  }
103  repeat = 0;
104  }
105  repeat = 1;
106  }
107  if (repeat) {
108  repeat = 0;
109  opcode = bytestream2_peek_byte(gb);
110  if (opcode < 0x10) {
111  bytestream2_skip(gb, 1);
112  if (!opcode) {
113  if (!bytestream2_peek_byte(gb)) {
114  do {
115  bytestream2_skip(gb, 1);
116  opcode += 255;
117  } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
118  }
119  opcode += bytestream2_get_byte(gb) + 15;
120  }
121  bytestream2_put_le32(pb, bytestream2_get_le32(gb));
122  for (i = opcode - 1; i > 0; --i)
123  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
124  opcode = bytestream2_peek_byte(gb);
125  if (opcode < 0x10) {
126  bytestream2_skip(gb, 1);
127  pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;
128 
130  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
131 
132  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
133  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
134  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
135  len = opcode & 3;
136  if (!len) {
137  repeat = 1;
138  } else {
139  do {
140  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
141  --len;
142  } while (len);
143  opcode = bytestream2_peek_byte(gb);
144  }
145  continue;
146  }
147  }
148  }
149 
150  if (opcode >= 0x40) {
151  bytestream2_skip(gb, 1);
152  pos = - ((opcode >> 2) & 7) - 1 - 8 * bytestream2_get_byte(gb);
153  len = (opcode >> 5) - 1;
154 
156  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
157 
158  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
159  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
160  do {
161  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
162  --len;
163  } while (len);
164 
165  len = opcode & 3;
166 
167  if (!len) {
168  repeat = 1;
169  } else {
170  do {
171  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
172  --len;
173  } while (len);
174  opcode = bytestream2_peek_byte(gb);
175  }
176  continue;
177  } else if (opcode < 0x20) {
178  break;
179  }
180  len = opcode & 0x1F;
181  bytestream2_skip(gb, 1);
182  if (!len) {
183  if (!bytestream2_peek_byte(gb)) {
184  do {
185  bytestream2_skip(gb, 1);
186  len += 255;
187  } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
188  }
189  len += bytestream2_get_byte(gb) + 31;
190  }
191  i = bytestream2_get_le16(gb);
192  pos = - (i >> 2) - 1;
193 
195  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
196 
197  if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
198  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
199  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
200  do {
201  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
202  --len;
203  } while (len);
204  } else {
205  bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
206  for (len = len - 2; len; --len)
207  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
208  }
209  len = i & 3;
210  if (!len) {
211  repeat = 1;
212  } else {
213  do {
214  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
215  --len;
216  } while (len);
217  opcode = bytestream2_peek_byte(gb);
218  }
219  }
220  bytestream2_skip(gb, 1);
221  if (opcode < 0x10) {
222  pos = -(opcode >> 2) - 1 - 4 * bytestream2_get_byte(gb);
223 
225  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
226 
227  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
228  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
229  len = opcode & 3;
230  if (!len) {
231  repeat = 1;
232  } else {
233  do {
234  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
235  --len;
236  } while (len);
237  opcode = bytestream2_peek_byte(gb);
238  }
239  continue;
240  }
241  len = opcode & 7;
242  if (!len) {
243  if (!bytestream2_peek_byte(gb)) {
244  do {
245  bytestream2_skip(gb, 1);
246  len += 255;
247  } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
248  }
249  len += bytestream2_get_byte(gb) + 7;
250  }
251  i = bytestream2_get_le16(gb);
252  pos = bytestream2_tell_p(pb) - 2048 * (opcode & 8);
253  pos = pos - (i >> 2);
254  if (pos == bytestream2_tell_p(pb))
255  break;
256 
257  pos = pos - 0x4000;
259  bytestream2_seek(&gbc, pos, SEEK_SET);
260 
261  if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
262  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
263  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
264  do {
265  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
266  --len;
267  } while (len);
268  } else {
269  bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
270  for (len = len - 2; len; --len)
271  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
272  }
273 
274  len = i & 3;
275  if (!len) {
276  repeat = 1;
277  } else {
278  do {
279  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
280  --len;
281  } while (len);
282  opcode = bytestream2_peek_byte(gb);
283  }
284  }
285 
286  return 0;
287 }
288 
290 {
291  unsigned opcode = 0, len;
292  int high = 0;
293  int i, pos;
294 
295  while (bytestream2_get_bytes_left(gb) > 0) {
296  GetByteContext gbc;
297 
298  while (bytestream2_get_bytes_left(gb) > 0) {
299  while (bytestream2_get_bytes_left(gb) > 0) {
300  opcode = bytestream2_get_byte(gb);
301  high = opcode >= 0x20;
302  if (high)
303  break;
304  if (opcode)
305  break;
306  opcode = bytestream2_get_byte(gb);
307  if (opcode < 0xF8) {
308  opcode += 32;
309  break;
310  }
311  i = opcode - 0xF8;
312  if (i) {
313  len = 256;
314  do {
315  len *= 2;
316  --i;
317  } while (i);
318  } else {
319  len = 280;
320  }
321  do {
322  bytestream2_put_le32(pb, bytestream2_get_le32(gb));
323  bytestream2_put_le32(pb, bytestream2_get_le32(gb));
324  len -= 8;
325  } while (len && bytestream2_get_bytes_left(gb) > 0);
326  }
327 
328  if (!high) {
329  do {
330  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
331  --opcode;
332  } while (opcode && bytestream2_get_bytes_left(gb) > 0);
333 
334  while (bytestream2_get_bytes_left(gb) > 0) {
335  GetByteContext gbc;
336 
337  opcode = bytestream2_get_byte(gb);
338  if (opcode >= 0x20)
339  break;
341 
342  pos = -(opcode | 32 * bytestream2_get_byte(gb)) - 1;
343  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
344  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
345  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
346  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
347  bytestream2_put_byte(pb, bytestream2_get_byte(gb));
348  }
349  }
350  high = 0;
351  if (opcode < 0x40)
352  break;
354  pos = (-((opcode & 0x1F) | 32 * bytestream2_get_byte(gb)) - 1);
355  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
356  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
357  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
358  len = (opcode >> 5) - 1;
359  do {
360  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
361  --len;
362  } while (len && bytestream2_get_bytes_left(&gbc) > 0);
363  }
364  len = opcode & 0x1F;
365  if (!len) {
366  if (!bytestream2_peek_byte(gb)) {
367  do {
368  bytestream2_skip(gb, 1);
369  len += 255;
370  } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
371  }
372  len += bytestream2_get_byte(gb) + 31;
373  }
374  pos = -bytestream2_get_byte(gb);
376  bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos - (bytestream2_get_byte(gb) << 8), SEEK_SET);
377  if (bytestream2_tell_p(pb) == bytestream2_tell(&gbc))
378  break;
379  if (len < 5 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
380  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
381  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
382  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
383  } else {
384  bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
385  len--;
386  }
387  do {
388  bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
389  len--;
390  } while (len && bytestream2_get_bytes_left(&gbc) > 0);
391  }
392 
393  return 0;
394 }
395 
397  int *got_frame, AVPacket *avpkt)
398 {
399  FMVCContext *s = avctx->priv_data;
400  GetByteContext *gb = &s->gb;
401  PutByteContext *pb = &s->pb;
402  int ret, y, x;
403  int key_frame;
404 
405  if (avpkt->size < 8)
406  return AVERROR_INVALIDDATA;
407 
408  bytestream2_init(gb, avpkt->data, avpkt->size);
409  bytestream2_skip(gb, 2);
410 
411  key_frame = !!bytestream2_get_le16(gb);
412 
413  if (key_frame) {
414  const uint8_t *src;
415  unsigned type, size;
416  uint8_t *dst;
417 
418  type = bytestream2_get_le16(gb);
419  size = bytestream2_get_le16(gb);
421  return AVERROR_INVALIDDATA;
422 
423  bytestream2_init_writer(pb, s->buffer, s->buffer_size);
424  if (type == 1) {
425  decode_type1(gb, pb);
426  } else if (type == 2){
427  decode_type2(gb, pb);
428  } else {
429  avpriv_report_missing_feature(avctx, "Compression type %d", type);
430  return AVERROR_PATCHWELCOME;
431  }
432 
433  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
434  return ret;
435 
436  frame->flags |= AV_FRAME_FLAG_KEY;
437  frame->pict_type = AV_PICTURE_TYPE_I;
438 
439  src = s->buffer;
440  dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
441  for (y = 0; y < avctx->height; y++) {
442  memcpy(dst, src, avctx->width * s->bpp);
443  dst -= frame->linesize[0];
444  src += s->stride * 4;
445  if (bytestream2_tell_p(pb) < y*s->stride * 4)
446  break;
447  }
448  } else {
449  unsigned block, nb_blocks;
450  int type, k, l;
451  uint8_t *ssrc, *ddst;
452  const uint32_t *src;
453  uint32_t *dst;
454 
455  for (block = 0; block < s->nb_blocks; block++)
456  s->blocks[block].xor = 0;
457 
458  nb_blocks = bytestream2_get_le16(gb);
459  if (nb_blocks > s->nb_blocks)
460  return AVERROR_INVALIDDATA;
461 
462  bytestream2_init_writer(pb, s->pbuffer, s->pbuffer_size);
463 
464  type = bytestream2_get_le16(gb);
465  for (block = 0; block < nb_blocks; block++) {
466  unsigned size, offset;
467  int start = 0;
468 
469  offset = bytestream2_get_le16(gb);
470  if (offset >= s->nb_blocks)
471  return AVERROR_INVALIDDATA;
472 
473  size = bytestream2_get_le16(gb);
475  return AVERROR_INVALIDDATA;
476 
477  start = bytestream2_tell_p(pb);
478  if (type == 1) {
479  decode_type1(gb, pb);
480  } else if (type == 2){
481  decode_type2(gb, pb);
482  } else {
483  avpriv_report_missing_feature(avctx, "Compression type %d", type);
484  return AVERROR_PATCHWELCOME;
485  }
486 
487  if (s->blocks[offset].size * 4 != bytestream2_tell_p(pb) - start)
488  return AVERROR_INVALIDDATA;
489 
490  s->blocks[offset].xor = 1;
491  }
492 
493  src = (const uint32_t *)s->pbuffer;
494  dst = (uint32_t *)s->buffer;
495 
496  for (block = 0, y = 0; y < s->yb; y++) {
497  int block_h = s->blocks[block].h;
498  uint32_t *rect = dst;
499 
500  for (x = 0; x < s->xb; x++) {
501  int block_w = s->blocks[block].w;
502  uint32_t *row = dst;
503 
504  block_h = s->blocks[block].h;
505  if (s->blocks[block].xor) {
506  for (k = 0; k < block_h; k++) {
507  uint32_t *column = dst;
508  for (l = 0; l < block_w; l++)
509  *dst++ ^= *src++;
510  dst = &column[s->stride];
511  }
512  }
513  dst = &row[block_w];
514  ++block;
515  }
516  dst = &rect[block_h * s->stride];
517  }
518 
519  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
520  return ret;
521 
522  frame->flags &= ~AV_FRAME_FLAG_KEY;
523  frame->pict_type = AV_PICTURE_TYPE_P;
524 
525  ssrc = s->buffer;
526  ddst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
527  for (y = 0; y < avctx->height; y++) {
528  memcpy(ddst, ssrc, avctx->width * s->bpp);
529  ddst -= frame->linesize[0];
530  ssrc += s->stride * 4;
531  }
532  }
533 
534  *got_frame = 1;
535 
536  return avpkt->size;
537 }
538 
540 {
541  FMVCContext *s = avctx->priv_data;
542  int i, j, m, block = 0, h = BLOCK_HEIGHT, w = BLOCK_WIDTH;
543 
544  switch (avctx->bits_per_coded_sample) {
545  case 16:
546  avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
547  break;
548  case 24:
549  avctx->pix_fmt = AV_PIX_FMT_BGR24;
550  break;
551  case 32:
552  avctx->pix_fmt = AV_PIX_FMT_BGRA;
553  break;
554  default:
555  av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n",
556  avctx->bits_per_coded_sample);
557  return AVERROR_INVALIDDATA;
558  }
559 
560  s->stride = (avctx->width * avctx->bits_per_coded_sample + 31) / 32;
561  s->xb = s->stride / BLOCK_WIDTH;
562  m = s->stride % BLOCK_WIDTH;
563  if (m) {
564  if (m < 37) {
565  w = m + BLOCK_WIDTH;
566  } else {
567  w = m;
568  s->xb++;
569  }
570  }
571 
572  s->yb = avctx->height / BLOCK_HEIGHT;
573  m = avctx->height % BLOCK_HEIGHT;
574  if (m) {
575  if (m < 49) {
576  h = m + BLOCK_HEIGHT;
577  } else {
578  h = m;
579  s->yb++;
580  }
581  }
582 
583  s->nb_blocks = s->xb * s->yb;
584  if (!s->nb_blocks)
585  return AVERROR_INVALIDDATA;
586  s->blocks = av_calloc(s->nb_blocks, sizeof(*s->blocks));
587  if (!s->blocks)
588  return AVERROR(ENOMEM);
589 
590  for (i = 0; i < s->yb; i++) {
591  for (j = 0; j < s->xb; j++) {
592  if (i != (s->yb - 1) || j != (s->xb - 1)) {
593  if (i == s->yb - 1) {
594  s->blocks[block].w = BLOCK_WIDTH;
595  s->blocks[block].h = h;
596  s->blocks[block].size = BLOCK_WIDTH * h;
597  } else if (j == s->xb - 1) {
598  s->blocks[block].w = w;
599  s->blocks[block].h = BLOCK_HEIGHT;
600  s->blocks[block].size = BLOCK_HEIGHT * w;
601  } else {
602  s->blocks[block].w = BLOCK_WIDTH;
603  s->blocks[block].h = BLOCK_HEIGHT;
604  s->blocks[block].size = BLOCK_WIDTH * BLOCK_HEIGHT;
605  }
606  } else {
607  s->blocks[block].w = w;
608  s->blocks[block].h = h;
609  s->blocks[block].size = w * h;
610  }
611  block++;
612  }
613  }
614 
615  s->bpp = avctx->bits_per_coded_sample >> 3;
616  s->buffer_size = avctx->width * avctx->height * 4;
617  s->pbuffer_size = avctx->width * avctx->height * 4;
618  s->buffer = av_mallocz(s->buffer_size);
619  s->pbuffer = av_mallocz(s->pbuffer_size);
620  if (!s->buffer || !s->pbuffer)
621  return AVERROR(ENOMEM);
622 
623  return 0;
624 }
625 
627 {
628  FMVCContext *s = avctx->priv_data;
629 
630  av_freep(&s->buffer);
631  av_freep(&s->pbuffer);
632  av_freep(&s->blocks);
633 
634  return 0;
635 }
636 
638  .p.name = "fmvc",
639  CODEC_LONG_NAME("FM Screen Capture Codec"),
640  .p.type = AVMEDIA_TYPE_VIDEO,
641  .p.id = AV_CODEC_ID_FMVC,
642  .priv_data_size = sizeof(FMVCContext),
643  .init = decode_init,
644  .close = decode_close,
646  .p.capabilities = AV_CODEC_CAP_DR1,
647  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
648 };
ff_fmvc_decoder
const FFCodec ff_fmvc_decoder
Definition: fmvc.c:637
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
GetByteContext
Definition: bytestream.h:33
rect
Definition: f_ebur128.c:78
InterBlock::size
int size
Definition: fmvc.c:36
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:212
FMVCContext::blocks
InterBlock * blocks
Definition: fmvc.c:50
w
uint8_t w
Definition: llviddspenc.c:38
FMVCContext::pbuffer_size
size_t pbuffer_size
Definition: fmvc.c:46
AVPacket::data
uint8_t * data
Definition: packet.h:522
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:197
FFCodec
Definition: codec_internal.h:127
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
InterBlock::xor
int xor
Definition: fmvc.c:37
FMVCContext::yb
int yb
Definition: fmvc.c:49
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
InterBlock::h
int h
Definition: fmvc.c:35
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
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
FMVCContext::buffer
uint8_t * buffer
Definition: fmvc.c:43
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:626
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:287
s
#define s(width, name)
Definition: cbs_vp9.c:198
InterBlock::w
int w
Definition: fmvc.c:35
FMVCContext::nb_blocks
unsigned nb_blocks
Definition: fmvc.c:51
decode.h
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
InterBlock
Definition: fmvc.c:34
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
PutByteContext::buffer_start
uint8_t * buffer_start
Definition: bytestream.h:38
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
decode_frame
static int decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: fmvc.c:396
AV_CODEC_ID_FMVC
@ AV_CODEC_ID_FMVC
Definition: codec_id.h:276
FMVCContext::pbuffer
uint8_t * pbuffer
Definition: fmvc.c:45
decode_type1
static int decode_type1(GetByteContext *gb, PutByteContext *pb)
Definition: fmvc.c:289
FMVCContext::pb
PutByteContext pb
Definition: fmvc.c:42
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
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:1553
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
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:523
codec_internal.h
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
size
int size
Definition: twinvq_data.h:10344
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: fmvc.c:539
FMVCContext
Definition: fmvc.c:40
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
FMVCContext::bpp
int bpp
Definition: fmvc.c:48
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1567
AV_PIX_FMT_RGB555LE
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
Definition: pixfmt.h:115
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
len
int len
Definition: vorbis_enc_data.h:426
decode_type2
static int decode_type2(GetByteContext *gb, PutByteContext *pb)
Definition: fmvc.c:54
AVCodecContext::height
int height
Definition: avcodec.h:618
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
avcodec.h
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
pos
unsigned int pos
Definition: spdifenc.c:413
BLOCK_HEIGHT
#define BLOCK_HEIGHT
Definition: fmvc.c:31
PutByteContext::buffer_end
uint8_t * buffer_end
Definition: bytestream.h:38
AVCodecContext
main external API structure.
Definition: avcodec.h:445
FMVCContext::gb
GetByteContext gb
Definition: fmvc.c:41
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
BLOCK_WIDTH
#define BLOCK_WIDTH
Definition: fmvc.c:32
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVPacket
This structure stores compressed data.
Definition: packet.h:499
FMVCContext::stride
ptrdiff_t stride
Definition: fmvc.c:47
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
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
FMVCContext::buffer_size
size_t buffer_size
Definition: fmvc.c:44
h
h
Definition: vp9dsp_template.c:2038
decode_close
static av_cold int decode_close(AVCodecContext *avctx)
Definition: fmvc.c:626
FMVCContext::xb
int xb
Definition: fmvc.c:49