FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <stdlib.h>
25 #include <string.h>
26 
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "internal.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 {
44  size_t buffer_size;
46  size_t pbuffer_size;
47  int stride;
48  int bpp;
49  int yb, xb;
51  int 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 = 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 
396 static int decode_frame(AVCodecContext *avctx,
397  void *data, int *got_frame,
398  AVPacket *avpkt)
399 {
400  FMVCContext *s = avctx->priv_data;
401  GetByteContext *gb = &s->gb;
402  PutByteContext *pb = &s->pb;
403  AVFrame *frame = data;
404  int ret, y, x;
405 
406  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
407  return ret;
408 
409  bytestream2_init(gb, avpkt->data, avpkt->size);
410  bytestream2_skip(gb, 2);
411 
412  frame->key_frame = !!bytestream2_get_le16(gb);
414 
415  if (frame->key_frame) {
416  const uint8_t *src;
417  int type, size;
418  uint8_t *dst;
419 
420  type = bytestream2_get_le16(gb);
421  size = bytestream2_get_le16(gb);
422  if (size > bytestream2_get_bytes_left(gb))
423  return AVERROR_INVALIDDATA;
424 
426  if (type == 1) {
427  decode_type1(gb, pb);
428  } else if (type == 2){
429  decode_type2(gb, pb);
430  } else {
431  avpriv_report_missing_feature(avctx, "compression %d", type);
432  return AVERROR_PATCHWELCOME;
433  }
434 
435  src = s->buffer;
436  dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
437  for (y = 0; y < avctx->height; y++) {
438  memcpy(dst, src, avctx->width * s->bpp);
439  dst -= frame->linesize[0];
440  src += s->stride * 4;
441  }
442  } else {
443  int block, nb_blocks, type, k, l;
444  uint8_t *ssrc, *ddst;
445  const uint32_t *src;
446  uint32_t *dst;
447 
448  for (block = 0; block < s->nb_blocks; block++)
449  s->blocks[block].xor = 0;
450 
451  nb_blocks = bytestream2_get_le16(gb);
452  if (nb_blocks > s->nb_blocks)
453  return AVERROR_INVALIDDATA;
454 
456 
457  type = bytestream2_get_le16(gb);
458  for (block = 0; block < nb_blocks; block++) {
459  int size, offset, start = 0;
460 
461  offset = bytestream2_get_le16(gb);
462  if (offset >= s->nb_blocks)
463  return AVERROR_INVALIDDATA;
464 
465  size = bytestream2_get_le16(gb);
466  if (size > bytestream2_get_bytes_left(gb))
467  return AVERROR_INVALIDDATA;
468 
469  start = bytestream2_tell_p(pb);
470  if (type == 1) {
471  decode_type1(gb, pb);
472  } else if (type == 2){
473  decode_type2(gb, pb);
474  } else {
475  avpriv_report_missing_feature(avctx, "compression %d", type);
476  return AVERROR_PATCHWELCOME;
477  }
478 
479  if (s->blocks[offset].size * 4 != bytestream2_tell_p(pb) - start)
480  return AVERROR_INVALIDDATA;
481 
482  s->blocks[offset].xor = 1;
483  }
484 
485  src = (const uint32_t *)s->pbuffer;
486  dst = (uint32_t *)s->buffer;
487 
488  for (block = 0, y = 0; y < s->yb; y++) {
489  int block_h = s->blocks[block].h;
490  uint32_t *rect = dst;
491 
492  for (x = 0; x < s->xb; x++) {
493  int block_w = s->blocks[block].w;
494  uint32_t *row = dst;
495 
496  block_h = s->blocks[block].h;
497  if (s->blocks[block].xor) {
498  for (k = 0; k < block_h; k++) {
499  uint32_t *column = dst;
500  for (l = 0; l < block_w; l++) {
501  *dst++ ^= *src++;
502  }
503  dst = &column[s->stride];
504  }
505  }
506  dst = &row[block_w];
507  ++block;
508  }
509  dst = &rect[block_h * s->stride];
510  }
511 
512  ssrc = s->buffer;
513  ddst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
514  for (y = 0; y < avctx->height; y++) {
515  memcpy(ddst, ssrc, avctx->width * s->bpp);
516  ddst -= frame->linesize[0];
517  ssrc += s->stride * 4;
518  }
519  }
520 
521  *got_frame = 1;
522 
523  return avpkt->size;
524 }
525 
527 {
528  FMVCContext *s = avctx->priv_data;
529  int i, j, m, block = 0, h = BLOCK_HEIGHT, w = BLOCK_WIDTH;
530 
531  switch (avctx->bits_per_coded_sample) {
532  case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
533  case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
534  case 32: avctx->pix_fmt = AV_PIX_FMT_BGRA; break;
535  default:
536  av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", avctx->bits_per_coded_sample);
537  return AVERROR_INVALIDDATA;
538  }
539 
540  s->stride = (avctx->width * avctx->bits_per_coded_sample + 31) / 32;
541  s->xb = s->stride / BLOCK_WIDTH;
542  m = s->stride % BLOCK_WIDTH;
543  if (m) {
544  if (m < 37) {
545  w = m + BLOCK_WIDTH;
546  } else {
547  w = m;
548  s->xb++;
549  }
550  }
551 
552  s->yb = avctx->height / BLOCK_HEIGHT;
553  m = avctx->height % BLOCK_HEIGHT;
554  if (m) {
555  if (m < 49) {
556  h = m + BLOCK_HEIGHT;
557  } else {
558  h = m;
559  s->yb++;
560  }
561  }
562 
563  s->nb_blocks = s->xb * s->yb;
564  if (!s->nb_blocks)
565  return AVERROR_INVALIDDATA;
566 
567  s->blocks = av_calloc(s->nb_blocks, sizeof(*s->blocks));
568  if (!s->blocks)
569  return AVERROR(ENOMEM);
570 
571  for (i = 0; i < s->yb; i++) {
572  for (j = 0; j < s->xb; j++) {
573  if (i != (s->yb - 1) || j != (s->xb - 1)) {
574  if (i == s->yb - 1) {
575  s->blocks[block].w = BLOCK_WIDTH;
576  s->blocks[block].h = h;
577  s->blocks[block].size = BLOCK_WIDTH * h;
578  } else if (j == s->xb - 1) {
579  s->blocks[block].w = w;
580  s->blocks[block].h = BLOCK_HEIGHT;
581  s->blocks[block].size = BLOCK_HEIGHT * w;
582  } else {
583  s->blocks[block].w = BLOCK_WIDTH;
584  s->blocks[block].h = BLOCK_HEIGHT;
586  }
587  } else {
588  s->blocks[block].w = w;
589  s->blocks[block].h = h;
590  s->blocks[block].size = w * h;
591  }
592  block++;
593  }
594  }
595 
596  s->bpp = avctx->bits_per_coded_sample >> 3;
597  s->buffer_size = avctx->width * avctx->height * 4;
598  s->pbuffer_size = avctx->width * avctx->height * 4;
599  s->buffer = av_mallocz(s->buffer_size);
601  if (!s->buffer || !s->pbuffer)
602  return AVERROR(ENOMEM);
603 
604  return 0;
605 }
606 
608 {
609  FMVCContext *s = avctx->priv_data;
610 
611  av_freep(&s->buffer);
612  av_freep(&s->pbuffer);
613  av_freep(&s->blocks);
614 
615  return 0;
616 }
617 
619  .name = "fmvc",
620  .long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"),
621  .type = AVMEDIA_TYPE_VIDEO,
622  .id = AV_CODEC_ID_FMVC,
623  .priv_data_size = sizeof(FMVCContext),
624  .init = decode_init,
625  .close = decode_close,
626  .decode = decode_frame,
627  .capabilities = AV_CODEC_CAP_DR1,
628  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
630 };
size_t pbuffer_size
Definition: fmvc.c:46
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:201
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
int stride
Definition: fmvc.c:47
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1680
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
uint8_t * pbuffer
Definition: fmvc.c:45
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1989
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:222
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3739
int size
Definition: fmvc.c:36
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
GetByteContext gb
Definition: fmvc.c:41
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:230
static int16_t block[64]
Definition: dct.c:115
static av_cold int decode_init(AVCodecContext *avctx)
Definition: fmvc.c:526
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
int nb_blocks
Definition: fmvc.c:51
uint8_t
#define av_cold
Definition: attributes.h:82
static av_cold int decode_close(AVCodecContext *avctx)
Definition: fmvc.c:607
int h
Definition: fmvc.c:35
static AVFrame * frame
InterBlock * blocks
Definition: fmvc.c:50
uint8_t * data
Definition: avcodec.h:1679
int xor
Definition: fmvc.c:37
ptrdiff_t size
Definition: opengl_enc.c:101
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:3157
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int decode_type2(GetByteContext *gb, PutByteContext *pb)
Definition: fmvc.c:54
#define AVERROR(e)
Definition: error.h:43
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:179
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:96
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
const char * name
Name of the codec implementation.
Definition: avcodec.h:3746
uint8_t * buffer
Definition: fmvc.c:43
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:193
int yb
Definition: fmvc.c:49
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:284
uint8_t * buffer_start
Definition: bytestream.h:38
int width
picture width / height.
Definition: avcodec.h:1948
int w
Definition: fmvc.c:35
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:65
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int xb
Definition: fmvc.c:49
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:232
main external API structure.
Definition: avcodec.h:1761
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1669
GLint GLenum type
Definition: opengl_enc.c:105
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: fmvc.c:396
Definition: f_ebur128.c:91
static int decode_type1(GetByteContext *gb, PutByteContext *pb)
Definition: fmvc.c:289
AVCodec ff_fmvc_decoder
Definition: fmvc.c:618
#define BLOCK_HEIGHT
Definition: fmvc.c:31
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:215
PutByteContext pb
Definition: fmvc.c:42
common internal api header.
#define BLOCK_WIDTH
Definition: fmvc.c:32
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:367
int bpp
Definition: fmvc.c:48
void * priv_data
Definition: avcodec.h:1803
int len
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:279
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:690
size_t buffer_size
Definition: fmvc.c:44
This structure stores compressed data.
Definition: avcodec.h:1656
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:1002
for(j=16;j >0;--j)
Predicted.
Definition: avutil.h:275
uint8_t * buffer_end
Definition: bytestream.h:38