Libav
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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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  break; \
109  case 3: \
110  idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
111  break; \
112  } \
113  } while(0)
114 
116 {
117  DXVContext *ctx = avctx->priv_data;
118  GetByteContext *gbc = &ctx->gbc;
119  uint32_t value, prev, op;
120  int idx = 0, state = 0;
121  int pos = 2;
122 
123  /* Copy the first two elements */
124  AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
125  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
126 
127  /* Process input until the whole texture has been filled */
128  while (pos + 2 <= ctx->tex_size / 4) {
129  CHECKPOINT(2);
130 
131  /* Copy two elements from a previous offset or from the input buffer */
132  if (op) {
133  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
134  AV_WL32(ctx->tex_data + 4 * pos, prev);
135  pos++;
136 
137  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
138  AV_WL32(ctx->tex_data + 4 * pos, prev);
139  pos++;
140  } else {
141  CHECKPOINT(2);
142 
143  if (op)
144  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
145  else
146  prev = bytestream2_get_le32(gbc);
147  AV_WL32(ctx->tex_data + 4 * pos, prev);
148  pos++;
149 
150  CHECKPOINT(2);
151 
152  if (op)
153  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
154  else
155  prev = bytestream2_get_le32(gbc);
156  AV_WL32(ctx->tex_data + 4 * pos, prev);
157  pos++;
158  }
159  }
160 
161  return 0;
162 }
163 
165 {
166  DXVContext *ctx = avctx->priv_data;
167  GetByteContext *gbc = &ctx->gbc;
168  uint32_t value, op;
169  int idx, prev, state = 0;
170  int pos = 4;
171  int run = 0;
172  int probe, check;
173 
174  /* Copy the first four elements */
175  AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
176  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
177  AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
178  AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
179 
180  /* Process input until the whole texture has been filled */
181  while (pos + 2 <= ctx->tex_size / 4) {
182  if (run) {
183  run--;
184 
185  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
186  AV_WL32(ctx->tex_data + 4 * pos, prev);
187  pos++;
188  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
189  AV_WL32(ctx->tex_data + 4 * pos, prev);
190  pos++;
191  } else {
192  if (state == 0) {
193  value = bytestream2_get_le32(gbc);
194  state = 16;
195  }
196  op = value & 0x3;
197  value >>= 2;
198  state--;
199 
200  switch (op) {
201  case 0:
202  /* Long copy */
203  check = bytestream2_get_byte(gbc) + 1;
204  if (check == 256) {
205  do {
206  probe = bytestream2_get_le16(gbc);
207  check += probe;
208  } while (probe == 0xFFFF);
209  }
210  while (check && pos + 4 <= ctx->tex_size / 4) {
211  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
212  AV_WL32(ctx->tex_data + 4 * pos, prev);
213  pos++;
214 
215  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
216  AV_WL32(ctx->tex_data + 4 * pos, prev);
217  pos++;
218 
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  check--;
228  }
229 
230  /* Restart (or exit) the loop */
231  continue;
232  break;
233  case 1:
234  /* Load new run value */
235  run = bytestream2_get_byte(gbc);
236  if (run == 255) {
237  do {
238  probe = bytestream2_get_le16(gbc);
239  run += probe;
240  } while (probe == 0xFFFF);
241  }
242 
243  /* Copy two dwords from previous data */
244  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
245  AV_WL32(ctx->tex_data + 4 * pos, prev);
246  pos++;
247 
248  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
249  AV_WL32(ctx->tex_data + 4 * pos, prev);
250  pos++;
251  break;
252  case 2:
253  /* Copy two dwords from a previous index */
254  idx = 8 + bytestream2_get_le16(gbc);
255  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
256  return AVERROR_INVALIDDATA;
257  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
258  AV_WL32(ctx->tex_data + 4 * pos, prev);
259  pos++;
260 
261  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
262  AV_WL32(ctx->tex_data + 4 * pos, prev);
263  pos++;
264  break;
265  case 3:
266  /* Copy two dwords from input */
267  prev = bytestream2_get_le32(gbc);
268  AV_WL32(ctx->tex_data + 4 * pos, prev);
269  pos++;
270 
271  prev = bytestream2_get_le32(gbc);
272  AV_WL32(ctx->tex_data + 4 * pos, prev);
273  pos++;
274  break;
275  }
276  }
277 
278  CHECKPOINT(4);
279  if (pos + 2 > ctx->tex_size / 4)
280  return AVERROR_INVALIDDATA;
281 
282  /* Copy two elements from a previous offset or from the input buffer */
283  if (op) {
284  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
285  return AVERROR_INVALIDDATA;
286  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
287  AV_WL32(ctx->tex_data + 4 * pos, prev);
288  pos++;
289 
290  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
291  AV_WL32(ctx->tex_data + 4 * pos, prev);
292  pos++;
293  } else {
294  CHECKPOINT(4);
295 
296  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
297  return AVERROR_INVALIDDATA;
298  if (op)
299  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
300  else
301  prev = bytestream2_get_le32(gbc);
302  AV_WL32(ctx->tex_data + 4 * pos, prev);
303  pos++;
304 
305  CHECKPOINT(4);
306 
307  if (op)
308  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
309  else
310  prev = bytestream2_get_le32(gbc);
311  AV_WL32(ctx->tex_data + 4 * pos, prev);
312  pos++;
313  }
314  }
315 
316  return 0;
317 }
318 
320 {
321  DXVContext *ctx = avctx->priv_data;
322  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
323 }
324 
326 {
327  DXVContext *ctx = avctx->priv_data;
328  GetByteContext *gbc = &ctx->gbc;
329 
330  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
331  return 0;
332 }
333 
334 static int dxv_decode(AVCodecContext *avctx, void *data,
335  int *got_frame, AVPacket *avpkt)
336 {
337  DXVContext *ctx = avctx->priv_data;
338  ThreadFrame tframe;
339  GetByteContext *gbc = &ctx->gbc;
340  int (*decompress_tex)(AVCodecContext *avctx);
341  const char *msgcomp, *msgtext;
342  uint32_t tag;
343  int version_major, version_minor = 0;
344  int size = 0, old_type = 0;
345  int ret;
346 
347  bytestream2_init(gbc, avpkt->data, avpkt->size);
348 
349  tag = bytestream2_get_le32(gbc);
350  switch (tag) {
351  case MKBETAG('D', 'X', 'T', '1'):
352  decompress_tex = dxv_decompress_dxt1;
353  ctx->tex_funct = ctx->texdsp.dxt1_block;
354  ctx->tex_rat = 8;
355  ctx->tex_step = 8;
356  msgcomp = "DXTR1";
357  msgtext = "DXT1";
358  break;
359  case MKBETAG('D', 'X', 'T', '5'):
360  decompress_tex = dxv_decompress_dxt5;
361  ctx->tex_funct = ctx->texdsp.dxt5_block;
362  ctx->tex_rat = 4;
363  ctx->tex_step = 16;
364  msgcomp = "DXTR5";
365  msgtext = "DXT5";
366  break;
367  case MKBETAG('Y', 'C', 'G', '6'):
368  case MKBETAG('Y', 'G', '1', '0'):
369  avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag);
370  return AVERROR_PATCHWELCOME;
371  default:
372  /* Old version does not have a real header, just size and type. */
373  size = tag & 0x00FFFFFF;
374  old_type = tag >> 24;
375  version_major = (old_type & 0x0F) - 1;
376 
377  if (old_type & 0x80) {
378  msgcomp = "RAW";
379  decompress_tex = dxv_decompress_raw;
380  } else {
381  msgcomp = "LZF";
382  decompress_tex = dxv_decompress_lzf;
383  }
384 
385  if (old_type & 0x40) {
386  msgtext = "DXT5";
387 
388  ctx->tex_funct = ctx->texdsp.dxt5_block;
389  ctx->tex_step = 16;
390  } else if (old_type & 0x20 || version_major == 1) {
391  msgtext = "DXT1";
392 
393  ctx->tex_funct = ctx->texdsp.dxt1_block;
394  ctx->tex_step = 8;
395  } else {
396  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag);
397  return AVERROR_INVALIDDATA;
398  }
399  ctx->tex_rat = 1;
400  break;
401  }
402 
403  /* New header is 12 bytes long. */
404  if (!old_type) {
405  version_major = bytestream2_get_byte(gbc) - 1;
406  version_minor = bytestream2_get_byte(gbc);
407 
408  /* Encoder copies texture data when compression is not advantageous. */
409  if (bytestream2_get_byte(gbc)) {
410  msgcomp = "RAW";
411  ctx->tex_rat = 1;
412  decompress_tex = dxv_decompress_raw;
413  }
414 
415  bytestream2_skip(gbc, 1); // unknown
416  size = bytestream2_get_le32(gbc);
417  }
418  av_log(avctx, AV_LOG_DEBUG,
419  "%s compression with %s texture (version %d.%d)\n",
420  msgcomp, msgtext, version_major, version_minor);
421 
422  if (size != bytestream2_get_bytes_left(gbc)) {
423  av_log(avctx, AV_LOG_ERROR,
424  "Incomplete or invalid file (header %d, left %d).\n",
425  size, bytestream2_get_bytes_left(gbc));
426  return AVERROR_INVALIDDATA;
427  }
428 
429  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
430  ret = av_reallocp(&ctx->tex_data, ctx->tex_size);
431  if (ret < 0)
432  return ret;
433 
434  /* Decompress texture out of the intermediate compression. */
435  ret = decompress_tex(avctx);
436  if (ret < 0)
437  return ret;
438 
439  tframe.f = data;
440  ret = ff_thread_get_buffer(avctx, &tframe, 0);
441  if (ret < 0)
442  return ret;
443  ff_thread_finish_setup(avctx);
444 
445  /* Now decompress the texture with the standard functions. */
446  avctx->execute2(avctx, decompress_texture_thread,
447  tframe.f, NULL, ctx->slice_count);
448 
449  /* Frame is ready to be output. */
450  tframe.f->pict_type = AV_PICTURE_TYPE_I;
451  tframe.f->key_frame = 1;
452  *got_frame = 1;
453 
454  return avpkt->size;
455 }
456 
457 static int dxv_init(AVCodecContext *avctx)
458 {
459  DXVContext *ctx = avctx->priv_data;
460  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
461 
462  if (ret < 0) {
463  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
464  avctx->width, avctx->height);
465  return ret;
466  }
467 
468  /* Codec requires 16x16 alignment. */
469  avctx->coded_width = FFALIGN(avctx->width, 16);
470  avctx->coded_height = FFALIGN(avctx->height, 16);
471 
472  ff_texturedsp_init(&ctx->texdsp);
473  avctx->pix_fmt = AV_PIX_FMT_RGBA;
474 
475  ctx->slice_count = av_clip(avctx->thread_count, 1,
476  avctx->coded_height / TEXTURE_BLOCK_H);
477 
478  return 0;
479 }
480 
481 static int dxv_close(AVCodecContext *avctx)
482 {
483  DXVContext *ctx = avctx->priv_data;
484 
485  av_freep(&ctx->tex_data);
486 
487  return 0;
488 }
489 
491  .name = "dxv",
492  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
493  .type = AVMEDIA_TYPE_VIDEO,
494  .id = AV_CODEC_ID_DXV,
495  .init = dxv_init,
496  .decode = dxv_decode,
497  .close = dxv_close,
498  .priv_data_size = sizeof(DXVContext),
499  .capabilities = AV_CODEC_CAP_DR1 |
502  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
504 };
#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 AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
int size
int(* dxt5_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:51
This structure describes decoded (raw) audio or video data.
Definition: frame.h:140
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1595
misc image utilities
AVFrame * f
Definition: thread.h:36
Texture block (4x4) module.
int size
Definition: avcodec.h:1347
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1621
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition: dxv.c:115
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:132
uint8_t run
Definition: svq3.c:203
int stride
Definition: mace.c:144
AVCodec.
Definition: avcodec.h:3120
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:202
static int16_t block[64]
Definition: dct.c:97
#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:164
int64_t tex_size
Definition: dxv.c:40
Multithreading support functions.
#define CHECKPOINT(x)
Definition: dxv.c:93
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:43
const char data[16]
Definition: mxf.c:70
uint8_t * data
Definition: avcodec.h:1346
int av_reallocp(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:140
uint32_t tag
Definition: movenc.c:854
void ff_thread_finish_setup(AVCodecContext *avctx)
If the codec defines update_thread_context(), call this when they are ready for the next thread to st...
#define FFALIGN(x, a)
Definition: macros.h:48
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:124
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:161
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:148
AVCodec ff_dxv_decoder
Definition: dxv.c:490
GetByteContext gbc
Definition: dxv.c:35
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:260
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:145
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:151
static int dxv_close(AVCodecContext *avctx)
Definition: dxv.c:481
const char * name
Name of the codec implementation.
Definition: avcodec.h:3127
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:893
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:90
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:319
Definition: dxv.c:33
static int probe(AVProbeData *p)
Definition: anm.c:50
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:223
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:598
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:201
#define FFMIN(a, b)
Definition: common.h:66
int width
picture width / height.
Definition: avcodec.h:1580
int tex_rat
Definition: dxv.c:38
AVFormatContext * ctx
Definition: movenc.c:48
int slice_count
Definition: dxv.c:43
#define AV_RL32
Definition: intreadwrite.h:146
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:2806
#define AVERROR_PATCHWELCOME
Not yet implemented in Libav, patches welcome.
Definition: error.h:57
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: avcodec.h:897
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:2866
NULL
Definition: eval.c:55
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:158
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:1409
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
int coded_height
Definition: avcodec.h:1595
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:457
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:146
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:76
static struct @174 state
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:334
common internal api header.
#define MKBETAG(a, b, c, d)
Definition: common.h:257
void * priv_data
Definition: avcodec.h:1451
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:196
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:46
#define AV_WL32(p, val)
Definition: intreadwrite.h:263
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:42
This structure stores compressed data.
Definition: avcodec.h:1323
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:838
int tex_step
Definition: dxv.c:39
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:325
#define check(x, y, S, v)