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