FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dxv.c
Go to the documentation of this file.
1 /*
2  * Resolume DXV decoder
3  * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <stdint.h>
23 
24 #include "libavutil/imgutils.h"
25 
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "internal.h"
29 #include "lzf.h"
30 #include "texturedsp.h"
31 #include "thread.h"
32 
33 typedef struct DXVContext {
36 
37  uint8_t *tex_data; // Compressed texture
38  int tex_rat; // Compression ratio
39  int tex_step; // Distance between blocks
40  int64_t tex_size; // Texture size
41 
42  /* Optimal number of slices for parallel decoding */
44 
45  /* Pointer to the selected decompression function */
46  int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
47 } DXVContext;
48 
49 static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
50  int slice, int thread_nb)
51 {
52  DXVContext *ctx = avctx->priv_data;
53  AVFrame *frame = arg;
54  const uint8_t *d = ctx->tex_data;
55  int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
56  int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
57  int x, y;
58  int start_slice, end_slice;
59  int base_blocks_per_slice = h_block / ctx->slice_count;
60  int remainder_blocks = h_block % ctx->slice_count;
61 
62  /* When the frame height (in blocks) doesn't divide evenly between the
63  * number of slices, spread the remaining blocks evenly between the first
64  * operations */
65  start_slice = slice * base_blocks_per_slice;
66  /* Add any extra blocks (one per slice) that have been added
67  * before this slice */
68  start_slice += FFMIN(slice, remainder_blocks);
69 
70  end_slice = start_slice + base_blocks_per_slice;
71  /* Add an extra block if there are remainder blocks to be accounted for */
72  if (slice < remainder_blocks)
73  end_slice++;
74 
75  for (y = start_slice; y < end_slice; y++) {
76  uint8_t *p = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
77  int off = y * w_block;
78  for (x = 0; x < w_block; x++) {
79  ctx->tex_funct(p + x * 16, frame->linesize[0],
80  d + (off + x) * ctx->tex_step);
81  }
82  }
83 
84  return 0;
85 }
86 
87 /* This scheme addresses already decoded elements depending on 2-bit status:
88  * 0 -> copy new element
89  * 1 -> copy one element from position -x
90  * 2 -> copy one element from position -(get_byte() + 2) * x
91  * 3 -> copy one element from position -(get_16le() + 0x102) * x
92  * x is always 2 for dxt1 and 4 for dxt5. */
93 #define CHECKPOINT(x) \
94  do { \
95  if (state == 0) { \
96  value = bytestream2_get_le32(gbc); \
97  state = 16; \
98  } \
99  op = value & 0x3; \
100  value >>= 2; \
101  state--; \
102  switch (op) { \
103  case 1: \
104  idx = x; \
105  break; \
106  case 2: \
107  idx = (bytestream2_get_byte(gbc) + 2) * x; \
108  if (idx > pos) { \
109  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
110  return AVERROR_INVALIDDATA; \
111  } \
112  break; \
113  case 3: \
114  idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
115  if (idx > pos) { \
116  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
117  return AVERROR_INVALIDDATA; \
118  } \
119  break; \
120  } \
121  } while(0)
122 
124 {
125  DXVContext *ctx = avctx->priv_data;
126  GetByteContext *gbc = &ctx->gbc;
127  uint32_t value, prev, op;
128  int idx = 0, state = 0;
129  int pos = 2;
130 
131  /* Copy the first two elements */
132  AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
133  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
134 
135  /* Process input until the whole texture has been filled */
136  while (pos + 2 <= ctx->tex_size / 4) {
137  CHECKPOINT(2);
138 
139  /* Copy two elements from a previous offset or from the input buffer */
140  if (op) {
141  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
142  AV_WL32(ctx->tex_data + 4 * pos, prev);
143  pos++;
144 
145  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
146  AV_WL32(ctx->tex_data + 4 * pos, prev);
147  pos++;
148  } else {
149  CHECKPOINT(2);
150 
151  if (op)
152  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
153  else
154  prev = bytestream2_get_le32(gbc);
155  AV_WL32(ctx->tex_data + 4 * pos, prev);
156  pos++;
157 
158  CHECKPOINT(2);
159 
160  if (op)
161  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
162  else
163  prev = bytestream2_get_le32(gbc);
164  AV_WL32(ctx->tex_data + 4 * pos, prev);
165  pos++;
166  }
167  }
168 
169  return 0;
170 }
171 
173 {
174  DXVContext *ctx = avctx->priv_data;
175  GetByteContext *gbc = &ctx->gbc;
176  uint32_t value, op;
177  int idx, prev, state = 0;
178  int pos = 4;
179  int run = 0;
180  int probe, check;
181 
182  /* Copy the first four elements */
183  AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
184  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
185  AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
186  AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
187 
188  /* Process input until the whole texture has been filled */
189  while (pos + 2 <= ctx->tex_size / 4) {
190  if (run) {
191  run--;
192 
193  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
194  AV_WL32(ctx->tex_data + 4 * pos, prev);
195  pos++;
196  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
197  AV_WL32(ctx->tex_data + 4 * pos, prev);
198  pos++;
199  } else {
200  if (state == 0) {
201  value = bytestream2_get_le32(gbc);
202  state = 16;
203  }
204  op = value & 0x3;
205  value >>= 2;
206  state--;
207 
208  switch (op) {
209  case 0:
210  /* Long copy */
211  check = bytestream2_get_byte(gbc) + 1;
212  if (check == 256) {
213  do {
214  probe = bytestream2_get_le16(gbc);
215  check += probe;
216  } while (probe == 0xFFFF);
217  }
218  while (check && pos + 4 <= ctx->tex_size / 4) {
219  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
220  AV_WL32(ctx->tex_data + 4 * pos, prev);
221  pos++;
222 
223  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
224  AV_WL32(ctx->tex_data + 4 * pos, prev);
225  pos++;
226 
227  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
228  AV_WL32(ctx->tex_data + 4 * pos, prev);
229  pos++;
230 
231  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
232  AV_WL32(ctx->tex_data + 4 * pos, prev);
233  pos++;
234 
235  check--;
236  }
237 
238  /* Restart (or exit) the loop */
239  continue;
240  break;
241  case 1:
242  /* Load new run value */
243  run = bytestream2_get_byte(gbc);
244  if (run == 255) {
245  do {
246  probe = bytestream2_get_le16(gbc);
247  run += probe;
248  } while (probe == 0xFFFF);
249  }
250 
251  /* Copy two dwords from previous data */
252  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
253  AV_WL32(ctx->tex_data + 4 * pos, prev);
254  pos++;
255 
256  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
257  AV_WL32(ctx->tex_data + 4 * pos, prev);
258  pos++;
259  break;
260  case 2:
261  /* Copy two dwords from a previous index */
262  idx = 8 + bytestream2_get_le16(gbc);
263  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
264  return AVERROR_INVALIDDATA;
265  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
266  AV_WL32(ctx->tex_data + 4 * pos, prev);
267  pos++;
268 
269  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
270  AV_WL32(ctx->tex_data + 4 * pos, prev);
271  pos++;
272  break;
273  case 3:
274  /* Copy two dwords from input */
275  prev = bytestream2_get_le32(gbc);
276  AV_WL32(ctx->tex_data + 4 * pos, prev);
277  pos++;
278 
279  prev = bytestream2_get_le32(gbc);
280  AV_WL32(ctx->tex_data + 4 * pos, prev);
281  pos++;
282  break;
283  }
284  }
285 
286  CHECKPOINT(4);
287  if (pos + 2 > ctx->tex_size / 4)
288  return AVERROR_INVALIDDATA;
289 
290  /* Copy two elements from a previous offset or from the input buffer */
291  if (op) {
292  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
293  return AVERROR_INVALIDDATA;
294  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
295  AV_WL32(ctx->tex_data + 4 * pos, prev);
296  pos++;
297 
298  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
299  AV_WL32(ctx->tex_data + 4 * pos, prev);
300  pos++;
301  } else {
302  CHECKPOINT(4);
303 
304  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
305  return AVERROR_INVALIDDATA;
306  if (op)
307  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
308  else
309  prev = bytestream2_get_le32(gbc);
310  AV_WL32(ctx->tex_data + 4 * pos, prev);
311  pos++;
312 
313  CHECKPOINT(4);
314 
315  if (op)
316  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
317  else
318  prev = bytestream2_get_le32(gbc);
319  AV_WL32(ctx->tex_data + 4 * pos, prev);
320  pos++;
321  }
322  }
323 
324  return 0;
325 }
326 
328 {
329  DXVContext *ctx = avctx->priv_data;
330  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
331 }
332 
334 {
335  DXVContext *ctx = avctx->priv_data;
336  GetByteContext *gbc = &ctx->gbc;
337 
338  if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
339  return AVERROR_INVALIDDATA;
340 
341  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
342  return 0;
343 }
344 
345 static int dxv_decode(AVCodecContext *avctx, void *data,
346  int *got_frame, AVPacket *avpkt)
347 {
348  DXVContext *ctx = avctx->priv_data;
349  ThreadFrame tframe;
350  GetByteContext *gbc = &ctx->gbc;
351  int (*decompress_tex)(AVCodecContext *avctx);
352  const char *msgcomp, *msgtext;
353  uint32_t tag;
354  int version_major, version_minor = 0;
355  int size = 0, old_type = 0;
356  int ret;
357 
358  bytestream2_init(gbc, avpkt->data, avpkt->size);
359 
360  tag = bytestream2_get_le32(gbc);
361  switch (tag) {
362  case MKBETAG('D', 'X', 'T', '1'):
363  decompress_tex = dxv_decompress_dxt1;
364  ctx->tex_funct = ctx->texdsp.dxt1_block;
365  ctx->tex_rat = 8;
366  ctx->tex_step = 8;
367  msgcomp = "DXTR1";
368  msgtext = "DXT1";
369  break;
370  case MKBETAG('D', 'X', 'T', '5'):
371  decompress_tex = dxv_decompress_dxt5;
372  ctx->tex_funct = ctx->texdsp.dxt5_block;
373  ctx->tex_rat = 4;
374  ctx->tex_step = 16;
375  msgcomp = "DXTR5";
376  msgtext = "DXT5";
377  break;
378  case MKBETAG('Y', 'C', 'G', '6'):
379  case MKBETAG('Y', 'G', '1', '0'):
380  avpriv_report_missing_feature(avctx, "Tag 0x%08"PRIX32, tag);
381  return AVERROR_PATCHWELCOME;
382  default:
383  /* Old version does not have a real header, just size and type. */
384  size = tag & 0x00FFFFFF;
385  old_type = tag >> 24;
386  version_major = (old_type & 0x0F) - 1;
387 
388  if (old_type & 0x80) {
389  msgcomp = "RAW";
390  decompress_tex = dxv_decompress_raw;
391  } else {
392  msgcomp = "LZF";
393  decompress_tex = dxv_decompress_lzf;
394  }
395 
396  if (old_type & 0x40) {
397  msgtext = "DXT5";
398 
399  ctx->tex_funct = ctx->texdsp.dxt5_block;
400  ctx->tex_step = 16;
401  } else if (old_type & 0x20 || version_major == 1) {
402  msgtext = "DXT1";
403 
404  ctx->tex_funct = ctx->texdsp.dxt1_block;
405  ctx->tex_step = 8;
406  } else {
407  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
408  return AVERROR_INVALIDDATA;
409  }
410  ctx->tex_rat = 1;
411  break;
412  }
413 
414  /* New header is 12 bytes long. */
415  if (!old_type) {
416  version_major = bytestream2_get_byte(gbc) - 1;
417  version_minor = bytestream2_get_byte(gbc);
418 
419  /* Encoder copies texture data when compression is not advantageous. */
420  if (bytestream2_get_byte(gbc)) {
421  msgcomp = "RAW";
422  ctx->tex_rat = 1;
423  decompress_tex = dxv_decompress_raw;
424  }
425 
426  bytestream2_skip(gbc, 1); // unknown
427  size = bytestream2_get_le32(gbc);
428  }
429  av_log(avctx, AV_LOG_DEBUG,
430  "%s compression with %s texture (version %d.%d)\n",
431  msgcomp, msgtext, version_major, version_minor);
432 
433  if (size != bytestream2_get_bytes_left(gbc)) {
434  av_log(avctx, AV_LOG_ERROR,
435  "Incomplete or invalid file (header %d, left %u).\n",
436  size, bytestream2_get_bytes_left(gbc));
437  return AVERROR_INVALIDDATA;
438  }
439 
440  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
441  ret = av_reallocp(&ctx->tex_data, ctx->tex_size);
442  if (ret < 0)
443  return ret;
444 
445  /* Decompress texture out of the intermediate compression. */
446  ret = decompress_tex(avctx);
447  if (ret < 0)
448  return ret;
449 
450  tframe.f = data;
451  ret = ff_thread_get_buffer(avctx, &tframe, 0);
452  if (ret < 0)
453  return ret;
454 
455  /* Now decompress the texture with the standard functions. */
456  avctx->execute2(avctx, decompress_texture_thread,
457  tframe.f, NULL, ctx->slice_count);
458 
459  /* Frame is ready to be output. */
460  tframe.f->pict_type = AV_PICTURE_TYPE_I;
461  tframe.f->key_frame = 1;
462  *got_frame = 1;
463 
464  return avpkt->size;
465 }
466 
467 static int dxv_init(AVCodecContext *avctx)
468 {
469  DXVContext *ctx = avctx->priv_data;
470  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
471 
472  if (ret < 0) {
473  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
474  avctx->width, avctx->height);
475  return ret;
476  }
477 
478  /* Codec requires 16x16 alignment. */
479  avctx->coded_width = FFALIGN(avctx->width, 16);
480  avctx->coded_height = FFALIGN(avctx->height, 16);
481 
482  ff_texturedsp_init(&ctx->texdsp);
483  avctx->pix_fmt = AV_PIX_FMT_RGBA;
484 
485  ctx->slice_count = av_clip(avctx->thread_count, 1,
486  avctx->coded_height / TEXTURE_BLOCK_H);
487 
488  return 0;
489 }
490 
491 static int dxv_close(AVCodecContext *avctx)
492 {
493  DXVContext *ctx = avctx->priv_data;
494 
495  av_freep(&ctx->tex_data);
496 
497  return 0;
498 }
499 
501  .name = "dxv",
502  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
503  .type = AVMEDIA_TYPE_VIDEO,
504  .id = AV_CODEC_ID_DXV,
505  .init = dxv_init,
506  .decode = dxv_decode,
507  .close = dxv_close,
508  .priv_data_size = sizeof(DXVContext),
509  .capabilities = AV_CODEC_CAP_DR1 |
512  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
514 };
#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
#define NULL
Definition: coverity.c:32
#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:187
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1934
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
misc image utilities
AVFrame * f
Definition: thread.h:36
Texture block (4x4) module.
int size
Definition: avcodec.h:1658
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1960
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition: dxv.c:123
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
uint8_t run
Definition: svq3.c:206
AVCodec.
Definition: avcodec.h:3681
static int16_t block[64]
Definition: dct.c:115
#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
uint8_t
uint8_t * tex_data
Definition: dxv.c:37
static int dxv_decompress_dxt5(AVCodecContext *avctx)
Definition: dxv.c:172
int64_t tex_size
Definition: dxv.c:40
Multithreading support functions.
#define CHECKPOINT(x)
Definition: dxv.c:93
static AVFrame * frame
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:43
uint8_t * data
Definition: avcodec.h:1657
uint32_t tag
Definition: movenc.c:1413
ptrdiff_t size
Definition: opengl_enc.c:101
static int probe(AVProbeData *p)
Definition: act.c:36
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
TextureDSPContext texdsp
Definition: dxv.c:34
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
Definition: lzf.c:40
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int decompress_texture_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb)
Definition: dxv.c:49
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
AVCodec ff_dxv_decoder
Definition: dxv.c:500
GetByteContext gbc
Definition: dxv.c:35
static struct @253 state
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
const char * arg
Definition: jacosubdec.c:66
static int dxv_close(AVCodecContext *avctx)
Definition: dxv.c:491
const char * name
Name of the codec implementation.
Definition: avcodec.h:3688
int(* dxt5_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:51
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1057
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:327
Definition: dxv.c:33
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:281
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:599
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:261
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1919
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
int tex_rat
Definition: dxv.c:38
AVFormatContext * ctx
Definition: movenc.c:48
int slice_count
Definition: dxv.c:43
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:3161
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: avcodec.h:1061
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:163
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:218
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
main external API structure.
Definition: avcodec.h:1732
int coded_height
Definition: avcodec.h:1934
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:467
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:201
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:46
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:78
int
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:345
common internal api header.
#define MKBETAG(a, b, c, d)
Definition: common.h:343
void * priv_data
Definition: avcodec.h:1774
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition: avcodec.h:3221
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:256
#define av_freep(p)
#define stride
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:42
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1634
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:994
int tex_step
Definition: dxv.c:39
#define AV_WL32(p, v)
Definition: intreadwrite.h:431
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:333
#define check(x, y, S, v)