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