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 (bytestream2_get_bytes_left(gbc) < 1)
201  return AVERROR_INVALIDDATA;
202  if (state == 0) {
203  value = bytestream2_get_le32(gbc);
204  state = 16;
205  }
206  op = value & 0x3;
207  value >>= 2;
208  state--;
209 
210  switch (op) {
211  case 0:
212  /* Long copy */
213  check = bytestream2_get_byte(gbc) + 1;
214  if (check == 256) {
215  do {
216  probe = bytestream2_get_le16(gbc);
217  check += probe;
218  } while (probe == 0xFFFF);
219  }
220  while (check && pos + 4 <= ctx->tex_size / 4) {
221  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
222  AV_WL32(ctx->tex_data + 4 * pos, prev);
223  pos++;
224 
225  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
226  AV_WL32(ctx->tex_data + 4 * pos, prev);
227  pos++;
228 
229  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
230  AV_WL32(ctx->tex_data + 4 * pos, prev);
231  pos++;
232 
233  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
234  AV_WL32(ctx->tex_data + 4 * pos, prev);
235  pos++;
236 
237  check--;
238  }
239 
240  /* Restart (or exit) the loop */
241  continue;
242  break;
243  case 1:
244  /* Load new run value */
245  run = bytestream2_get_byte(gbc);
246  if (run == 255) {
247  do {
248  probe = bytestream2_get_le16(gbc);
249  run += probe;
250  } while (probe == 0xFFFF);
251  }
252 
253  /* Copy two dwords from previous data */
254  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
255  AV_WL32(ctx->tex_data + 4 * pos, prev);
256  pos++;
257 
258  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
259  AV_WL32(ctx->tex_data + 4 * pos, prev);
260  pos++;
261  break;
262  case 2:
263  /* Copy two dwords from a previous index */
264  idx = 8 + bytestream2_get_le16(gbc);
265  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
266  return AVERROR_INVALIDDATA;
267  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
268  AV_WL32(ctx->tex_data + 4 * pos, prev);
269  pos++;
270 
271  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
272  AV_WL32(ctx->tex_data + 4 * pos, prev);
273  pos++;
274  break;
275  case 3:
276  /* Copy two dwords from input */
277  prev = bytestream2_get_le32(gbc);
278  AV_WL32(ctx->tex_data + 4 * pos, prev);
279  pos++;
280 
281  prev = bytestream2_get_le32(gbc);
282  AV_WL32(ctx->tex_data + 4 * pos, prev);
283  pos++;
284  break;
285  }
286  }
287 
288  CHECKPOINT(4);
289  if (pos + 2 > ctx->tex_size / 4)
290  return AVERROR_INVALIDDATA;
291 
292  /* Copy two elements from a previous offset or from the input buffer */
293  if (op) {
294  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
295  return AVERROR_INVALIDDATA;
296  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
297  AV_WL32(ctx->tex_data + 4 * pos, prev);
298  pos++;
299 
300  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
301  AV_WL32(ctx->tex_data + 4 * pos, prev);
302  pos++;
303  } else {
304  CHECKPOINT(4);
305 
306  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
307  return AVERROR_INVALIDDATA;
308  if (op)
309  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
310  else
311  prev = bytestream2_get_le32(gbc);
312  AV_WL32(ctx->tex_data + 4 * pos, prev);
313  pos++;
314 
315  CHECKPOINT(4);
316 
317  if (op)
318  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
319  else
320  prev = bytestream2_get_le32(gbc);
321  AV_WL32(ctx->tex_data + 4 * pos, prev);
322  pos++;
323  }
324  }
325 
326  return 0;
327 }
328 
330 {
331  DXVContext *ctx = avctx->priv_data;
332  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
333 }
334 
336 {
337  DXVContext *ctx = avctx->priv_data;
338  GetByteContext *gbc = &ctx->gbc;
339 
340  if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
341  return AVERROR_INVALIDDATA;
342 
343  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
344  return 0;
345 }
346 
347 static int dxv_decode(AVCodecContext *avctx, void *data,
348  int *got_frame, AVPacket *avpkt)
349 {
350  DXVContext *ctx = avctx->priv_data;
351  ThreadFrame tframe;
352  GetByteContext *gbc = &ctx->gbc;
353  int (*decompress_tex)(AVCodecContext *avctx);
354  const char *msgcomp, *msgtext;
355  uint32_t tag;
356  int version_major, version_minor = 0;
357  int size = 0, old_type = 0;
358  int ret;
359 
360  bytestream2_init(gbc, avpkt->data, avpkt->size);
361 
362  tag = bytestream2_get_le32(gbc);
363  switch (tag) {
364  case MKBETAG('D', 'X', 'T', '1'):
365  decompress_tex = dxv_decompress_dxt1;
366  ctx->tex_funct = ctx->texdsp.dxt1_block;
367  ctx->tex_rat = 8;
368  ctx->tex_step = 8;
369  msgcomp = "DXTR1";
370  msgtext = "DXT1";
371  break;
372  case MKBETAG('D', 'X', 'T', '5'):
373  decompress_tex = dxv_decompress_dxt5;
374  ctx->tex_funct = ctx->texdsp.dxt5_block;
375  ctx->tex_rat = 4;
376  ctx->tex_step = 16;
377  msgcomp = "DXTR5";
378  msgtext = "DXT5";
379  break;
380  case MKBETAG('Y', 'C', 'G', '6'):
381  case MKBETAG('Y', 'G', '1', '0'):
382  avpriv_report_missing_feature(avctx, "Tag 0x%08"PRIX32, tag);
383  return AVERROR_PATCHWELCOME;
384  default:
385  /* Old version does not have a real header, just size and type. */
386  size = tag & 0x00FFFFFF;
387  old_type = tag >> 24;
388  version_major = (old_type & 0x0F) - 1;
389 
390  if (old_type & 0x80) {
391  msgcomp = "RAW";
392  decompress_tex = dxv_decompress_raw;
393  } else {
394  msgcomp = "LZF";
395  decompress_tex = dxv_decompress_lzf;
396  }
397 
398  if (old_type & 0x40) {
399  msgtext = "DXT5";
400 
401  ctx->tex_funct = ctx->texdsp.dxt5_block;
402  ctx->tex_step = 16;
403  } else if (old_type & 0x20 || version_major == 1) {
404  msgtext = "DXT1";
405 
406  ctx->tex_funct = ctx->texdsp.dxt1_block;
407  ctx->tex_step = 8;
408  } else {
409  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
410  return AVERROR_INVALIDDATA;
411  }
412  ctx->tex_rat = 1;
413  break;
414  }
415 
416  /* New header is 12 bytes long. */
417  if (!old_type) {
418  version_major = bytestream2_get_byte(gbc) - 1;
419  version_minor = bytestream2_get_byte(gbc);
420 
421  /* Encoder copies texture data when compression is not advantageous. */
422  if (bytestream2_get_byte(gbc)) {
423  msgcomp = "RAW";
424  ctx->tex_rat = 1;
425  decompress_tex = dxv_decompress_raw;
426  }
427 
428  bytestream2_skip(gbc, 1); // unknown
429  size = bytestream2_get_le32(gbc);
430  }
431  av_log(avctx, AV_LOG_DEBUG,
432  "%s compression with %s texture (version %d.%d)\n",
433  msgcomp, msgtext, version_major, version_minor);
434 
435  if (size != bytestream2_get_bytes_left(gbc)) {
436  av_log(avctx, AV_LOG_ERROR,
437  "Incomplete or invalid file (header %d, left %u).\n",
438  size, bytestream2_get_bytes_left(gbc));
439  return AVERROR_INVALIDDATA;
440  }
441 
442  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
443  ret = av_reallocp(&ctx->tex_data, ctx->tex_size);
444  if (ret < 0)
445  return ret;
446 
447  /* Decompress texture out of the intermediate compression. */
448  ret = decompress_tex(avctx);
449  if (ret < 0)
450  return ret;
451 
452  tframe.f = data;
453  ret = ff_thread_get_buffer(avctx, &tframe, 0);
454  if (ret < 0)
455  return ret;
456 
457  /* Now decompress the texture with the standard functions. */
458  avctx->execute2(avctx, decompress_texture_thread,
459  tframe.f, NULL, ctx->slice_count);
460 
461  /* Frame is ready to be output. */
462  tframe.f->pict_type = AV_PICTURE_TYPE_I;
463  tframe.f->key_frame = 1;
464  *got_frame = 1;
465 
466  return avpkt->size;
467 }
468 
469 static int dxv_init(AVCodecContext *avctx)
470 {
471  DXVContext *ctx = avctx->priv_data;
472  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
473 
474  if (ret < 0) {
475  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
476  avctx->width, avctx->height);
477  return ret;
478  }
479 
480  /* Codec requires 16x16 alignment. */
481  avctx->coded_width = FFALIGN(avctx->width, 16);
482  avctx->coded_height = FFALIGN(avctx->height, 16);
483 
484  ff_texturedsp_init(&ctx->texdsp);
485  avctx->pix_fmt = AV_PIX_FMT_RGBA;
486 
487  ctx->slice_count = av_clip(avctx->thread_count, 1,
488  avctx->coded_height / TEXTURE_BLOCK_H);
489 
490  return 0;
491 }
492 
493 static int dxv_close(AVCodecContext *avctx)
494 {
495  DXVContext *ctx = avctx->priv_data;
496 
497  av_freep(&ctx->tex_data);
498 
499  return 0;
500 }
501 
503  .name = "dxv",
504  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
505  .type = AVMEDIA_TYPE_VIDEO,
506  .id = AV_CODEC_ID_DXV,
507  .init = dxv_init,
508  .decode = dxv_decode,
509  .close = dxv_close,
510  .priv_data_size = sizeof(DXVContext),
511  .capabilities = AV_CODEC_CAP_DR1 |
514  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
516 };
#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:201
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static struct @260 state
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1963
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:1680
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1989
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:3739
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:1679
uint32_t tag
Definition: movenc.c:1409
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:502
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: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:493
const char * name
Name of the codec implementation.
Definition: avcodec.h:3746
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:1065
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:329
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:284
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1948
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:3192
#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:1069
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:232
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:1761
int coded_height
Definition: avcodec.h:1963
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:469
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
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:347
common internal api header.
#define MKBETAG(a, b, c, d)
Definition: common.h:343
void * priv_data
Definition: avcodec.h:1803
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:3252
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:279
#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:1656
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:1002
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:335
#define check(x, y, S, v)