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 < 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 < 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 < 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) {
264  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos);
265  return AVERROR_INVALIDDATA;
266  }
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 
290  /* Copy two elements from a previous offset or from the input buffer */
291  if (op) {
292  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
293  AV_WL32(ctx->tex_data + 4 * pos, prev);
294  pos++;
295 
296  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
297  AV_WL32(ctx->tex_data + 4 * pos, prev);
298  pos++;
299  } else {
300  CHECKPOINT(4);
301 
302  if (op)
303  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
304  else
305  prev = bytestream2_get_le32(gbc);
306  AV_WL32(ctx->tex_data + 4 * pos, prev);
307  pos++;
308 
309  CHECKPOINT(4);
310 
311  if (op)
312  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
313  else
314  prev = bytestream2_get_le32(gbc);
315  AV_WL32(ctx->tex_data + 4 * pos, prev);
316  pos++;
317  }
318  }
319 
320  return 0;
321 }
322 
324 {
325  DXVContext *ctx = avctx->priv_data;
326  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
327 }
328 
330 {
331  DXVContext *ctx = avctx->priv_data;
332  GetByteContext *gbc = &ctx->gbc;
333 
334  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
335  return 0;
336 }
337 
338 static int dxv_decode(AVCodecContext *avctx, void *data,
339  int *got_frame, AVPacket *avpkt)
340 {
341  DXVContext *ctx = avctx->priv_data;
342  ThreadFrame tframe;
343  GetByteContext *gbc = &ctx->gbc;
344  int (*decompress_tex)(AVCodecContext *avctx);
345  const char *msgcomp, *msgtext;
346  uint32_t tag;
347  int version_major, version_minor = 0;
348  int size = 0, old_type = 0;
349  int ret;
350 
351  bytestream2_init(gbc, avpkt->data, avpkt->size);
352 
353  tag = bytestream2_get_le32(gbc);
354  switch (tag) {
355  case MKBETAG('D', 'X', 'T', '1'):
356  decompress_tex = dxv_decompress_dxt1;
357  ctx->tex_funct = ctx->texdsp.dxt1_block;
358  ctx->tex_rat = 8;
359  ctx->tex_step = 8;
360  msgcomp = "DXTR1";
361  msgtext = "DXT1";
362  break;
363  case MKBETAG('D', 'X', 'T', '5'):
364  decompress_tex = dxv_decompress_dxt5;
365  ctx->tex_funct = ctx->texdsp.dxt5_block;
366  ctx->tex_rat = 4;
367  ctx->tex_step = 16;
368  msgcomp = "DXTR5";
369  msgtext = "DXT5";
370  break;
371  case MKBETAG('Y', 'C', 'G', '6'):
372  case MKBETAG('Y', 'G', '1', '0'):
373  avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag);
374  return AVERROR_PATCHWELCOME;
375  default:
376  /* Old version does not have a real header, just size and type. */
377  size = tag & 0x00FFFFFF;
378  old_type = tag >> 24;
379  version_major = (old_type & 0x0F) - 1;
380 
381  if (old_type & 0x80) {
382  msgcomp = "RAW";
383  decompress_tex = dxv_decompress_raw;
384  } else {
385  msgcomp = "LZF";
386  decompress_tex = dxv_decompress_lzf;
387  }
388 
389  if (old_type & 0x40) {
390  msgtext = "DXT5";
391 
392  ctx->tex_funct = ctx->texdsp.dxt5_block;
393  ctx->tex_step = 16;
394  } else if (old_type & 0x20 || version_major == 1) {
395  msgtext = "DXT1";
396 
397  ctx->tex_funct = ctx->texdsp.dxt1_block;
398  ctx->tex_step = 8;
399  } else {
400  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag);
401  return AVERROR_INVALIDDATA;
402  }
403  ctx->tex_rat = 1;
404  break;
405  }
406 
407  /* New header is 12 bytes long. */
408  if (!old_type) {
409  version_major = bytestream2_get_byte(gbc) - 1;
410  version_minor = bytestream2_get_byte(gbc);
411 
412  /* Encoder copies texture data when compression is not advantageous. */
413  if (bytestream2_get_byte(gbc)) {
414  msgcomp = "RAW";
415  ctx->tex_rat = 1;
416  decompress_tex = dxv_decompress_raw;
417  }
418 
419  bytestream2_skip(gbc, 1); // unknown
420  size = bytestream2_get_le32(gbc);
421  }
422  av_log(avctx, AV_LOG_DEBUG,
423  "%s compression with %s texture (version %d.%d)\n",
424  msgcomp, msgtext, version_major, version_minor);
425 
426  if (size != bytestream2_get_bytes_left(gbc)) {
427  av_log(avctx, AV_LOG_ERROR,
428  "Incomplete or invalid file (header %d, left %d).\n",
429  size, bytestream2_get_bytes_left(gbc));
430  return AVERROR_INVALIDDATA;
431  }
432 
433  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
434  ret = av_reallocp(&ctx->tex_data, ctx->tex_size);
435  if (ret < 0)
436  return ret;
437 
438  /* Decompress texture out of the intermediate compression. */
439  ret = decompress_tex(avctx);
440  if (ret < 0)
441  return ret;
442 
443  tframe.f = data;
444  ret = ff_thread_get_buffer(avctx, &tframe, 0);
445  if (ret < 0)
446  return ret;
447 
448  /* Now decompress the texture with the standard functions. */
449  avctx->execute2(avctx, decompress_texture_thread,
450  tframe.f, NULL, ctx->slice_count);
451 
452  /* Frame is ready to be output. */
453  tframe.f->pict_type = AV_PICTURE_TYPE_I;
454  tframe.f->key_frame = 1;
455  *got_frame = 1;
456 
457  return avpkt->size;
458 }
459 
460 static int dxv_init(AVCodecContext *avctx)
461 {
462  DXVContext *ctx = avctx->priv_data;
463  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
464 
465  if (ret < 0) {
466  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
467  avctx->width, avctx->height);
468  return ret;
469  }
470 
471  /* Codec requires 16x16 alignment. */
472  avctx->coded_width = FFALIGN(avctx->width, 16);
473  avctx->coded_height = FFALIGN(avctx->height, 16);
474 
475  ff_texturedsp_init(&ctx->texdsp);
476  avctx->pix_fmt = AV_PIX_FMT_RGBA;
477 
478  ctx->slice_count = av_clip(avctx->thread_count, 1,
479  avctx->coded_height / TEXTURE_BLOCK_H);
480 
481  return 0;
482 }
483 
484 static int dxv_close(AVCodecContext *avctx)
485 {
486  DXVContext *ctx = avctx->priv_data;
487 
488  av_freep(&ctx->tex_data);
489 
490  return 0;
491 }
492 
494  .name = "dxv",
495  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
496  .type = AVMEDIA_TYPE_VIDEO,
497  .id = AV_CODEC_ID_DXV,
498  .init = dxv_init,
499  .decode = dxv_decode,
500  .close = dxv_close,
501  .priv_data_size = sizeof(DXVContext),
502  .capabilities = AV_CODEC_CAP_DR1 |
505  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
507 };
#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:184
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:1878
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:1602
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1904
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:3600
static int16_t block[64]
Definition: dct.c:113
#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:1601
uint32_t tag
Definition: movenc.c:1382
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:176
AVCodec ff_dxv_decoder
Definition: dxv.c:493
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:484
const char * name
Name of the codec implementation.
Definition: avcodec.h:3607
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:1022
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:323
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:251
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:599
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:258
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1863
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:3107
#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:1026
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:187
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
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:1676
static struct @246 state
int coded_height
Definition: avcodec.h:1878
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:460
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:198
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
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:338
common internal api header.
#define MKBETAG(a, b, c, d)
Definition: common.h:343
void * priv_data
Definition: avcodec.h:1718
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:3167
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:253
#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:1578
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:959
int tex_step
Definition: dxv.c:39
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:329
#define check(x, y, S, v)