FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules 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  * Copyright (C) 2018 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 <stdint.h>
24 
25 #include "libavutil/imgutils.h"
26 #include "libavutil/mem.h"
27 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "codec_internal.h"
31 #include "dxv.h"
32 #include "lzf.h"
33 #include "texturedsp.h"
34 #include "thread.h"
35 
36 typedef struct DXVContext {
39 
40  uint8_t *tex_data; // Compressed texture
41  unsigned tex_data_size;
42  uint8_t *ctex_data; // Compressed chroma texture
43  unsigned ctex_data_size;
44 
45  int64_t tex_size; // Texture size
46  int64_t ctex_size; // Chroma texture size
47 
48  uint8_t *op_data[4]; // Opcodes
49  unsigned op_data_size[4];
50  int64_t op_size[4]; // Opcodes size
51 } DXVContext;
52 
53 /* This scheme addresses already decoded elements depending on 2-bit status:
54  * 0 -> copy new element
55  * 1 -> copy one element from position -x
56  * 2 -> copy one element from position -(get_byte() + 2) * x
57  * 3 -> copy one element from position -(get_16le() + 0x102) * x
58  * x is always 2 for dxt1 and 4 for dxt5. */
59 #define CHECKPOINT(x) \
60  do { \
61  if (state == 0) { \
62  if (bytestream2_get_bytes_left(gbc) < 4) \
63  return AVERROR_INVALIDDATA; \
64  value = bytestream2_get_le32(gbc); \
65  state = 16; \
66  } \
67  op = value & 0x3; \
68  value >>= 2; \
69  state--; \
70  switch (op) { \
71  case 1: \
72  idx = x; \
73  break; \
74  case 2: \
75  idx = (bytestream2_get_byte(gbc) + 2) * x; \
76  if (idx > pos) { \
77  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
78  return AVERROR_INVALIDDATA; \
79  } \
80  break; \
81  case 3: \
82  idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
83  if (idx > pos) { \
84  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
85  return AVERROR_INVALIDDATA; \
86  } \
87  break; \
88  } \
89  } while(0)
90 
92 {
93  DXVContext *ctx = avctx->priv_data;
94  GetByteContext *gbc = &ctx->gbc;
95  uint32_t value, prev, op;
96  int idx = 0, state = 0;
97  int pos = 2;
98 
99  /* Copy the first two elements */
100  AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
101  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
102 
103  /* Process input until the whole texture has been filled */
104  while (pos + 2 <= ctx->tex_size / 4) {
105  CHECKPOINT(2);
106 
107  /* Copy two elements from a previous offset or from the input buffer */
108  if (op) {
109  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
110  AV_WL32(ctx->tex_data + 4 * pos, prev);
111  pos++;
112 
113  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
114  AV_WL32(ctx->tex_data + 4 * pos, prev);
115  pos++;
116  } else {
117  CHECKPOINT(2);
118 
119  if (op)
120  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
121  else
122  prev = bytestream2_get_le32(gbc);
123  AV_WL32(ctx->tex_data + 4 * pos, prev);
124  pos++;
125 
126  CHECKPOINT(2);
127 
128  if (op)
129  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
130  else
131  prev = bytestream2_get_le32(gbc);
132  AV_WL32(ctx->tex_data + 4 * pos, prev);
133  pos++;
134  }
135  }
136 
137  return 0;
138 }
139 
140 typedef struct OpcodeTable {
141  int16_t next;
142  uint8_t val1;
143  uint8_t val2;
144 } OpcodeTable;
145 
146 static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
147 {
148  unsigned half = 512, bits = 1023, left = 1024, input, mask;
149  int value, counter = 0, rshift = 10, lshift = 30;
150 
151  mask = bytestream2_get_le32(gb) >> 2;
152  while (left) {
153  if (counter >= 256)
154  return AVERROR_INVALIDDATA;
155  value = bits & mask;
156  left -= bits & mask;
157  mask >>= rshift;
158  lshift -= rshift;
159  table[counter++] = value;
160  if (lshift < 16) {
161  if (bytestream2_get_bytes_left(gb) <= 0)
162  return AVERROR_INVALIDDATA;
163 
164  input = bytestream2_get_le16(gb);
165  mask += input << lshift;
166  lshift += 16;
167  }
168  if (left < half) {
169  half >>= 1;
170  bits >>= 1;
171  rshift--;
172  }
173  }
174 
175  for (; !table[counter - 1]; counter--)
176  if (counter <= 0)
177  return AVERROR_INVALIDDATA;
178 
179  *nb_elements = counter;
180 
181  if (counter < 256)
182  memset(&table[counter], 0, 4 * (256 - counter));
183 
184  if (lshift >= 16)
185  bytestream2_seek(gb, -2, SEEK_CUR);
186 
187  return 0;
188 }
189 
190 static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
191 {
192  unsigned table2[256] = { 0 };
193  unsigned x = 0;
194  int val0, val1, i, j = 2, k = 0;
195 
196  table2[0] = table0[0];
197  for (i = 0; i < nb_elements - 1; i++, table2[i] = val0) {
198  val0 = table0[i + 1] + table2[i];
199  }
200 
201  if (!table2[0]) {
202  do {
203  k++;
204  } while (!table2[k]);
205  }
206 
207  j = 2;
208  for (i = 1024; i > 0; i--) {
209  for (table1[x].val1 = k; k < 256 && j > table2[k]; k++);
210  x = (x - 383) & 0x3FF;
211  j++;
212  }
213 
214  if (nb_elements > 0)
215  memcpy(&table2[0], table0, 4 * nb_elements);
216 
217  for (i = 0; i < 1024; i++) {
218  val0 = table1[i].val1;
219  val1 = table2[val0];
220  table2[val0]++;
221  x = 31 - ff_clz(val1);
222  if (x > 10)
223  return AVERROR_INVALIDDATA;
224  table1[i].val2 = 10 - x;
225  table1[i].next = (val1 << table1[i].val2) - 1024;
226  }
227 
228  return 0;
229 }
230 
231 static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
232 {
233  OpcodeTable optable[1024];
234  int sum, x, val, lshift, rshift, ret, i, idx;
235  int64_t size_in_bits;
236  unsigned endoffset, newoffset, offset;
237  unsigned next;
238  const uint8_t *src = gb->buffer;
239 
240  ret = fill_optable(table, optable, nb_elements);
241  if (ret < 0)
242  return ret;
243 
244  size_in_bits = bytestream2_get_le32(gb);
245  endoffset = ((size_in_bits + 7) >> 3) - 4;
246  if ((int)endoffset <= 0 || bytestream2_get_bytes_left(gb) < endoffset)
247  return AVERROR_INVALIDDATA;
248 
249  offset = endoffset;
250  next = AV_RL32(src + endoffset);
251  rshift = (((size_in_bits & 0xFF) - 1) & 7) + 15;
252  lshift = 32 - rshift;
253  idx = (next >> rshift) & 0x3FF;
254  for (i = 0; i < op_size; i++) {
255  dst[i] = optable[idx].val1;
256  val = optable[idx].val2;
257  sum = val + lshift;
258  x = (next << lshift) >> 1 >> (31 - val);
259  newoffset = offset - (sum >> 3);
260  lshift = sum & 7;
261  idx = x + optable[idx].next;
262  offset = newoffset;
263  if (offset > endoffset)
264  return AVERROR_INVALIDDATA;
265  next = AV_RL32(src + offset);
266  }
267 
268  bytestream2_skip(gb, (size_in_bits + 7 >> 3) - 4);
269 
270  return 0;
271 }
272 
273 static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
274 {
275  int pos = bytestream2_tell(gb);
276  int flag = bytestream2_peek_byte(gb);
277 
278  if ((flag & 3) == 0) {
279  bytestream2_skip(gb, 1);
280  int read_size = bytestream2_get_buffer(gb, dstp, op_size);
281  if (read_size != op_size)
282  return AVERROR_INVALIDDATA;
283  } else if ((flag & 3) == 1) {
284  bytestream2_skip(gb, 1);
285  memset(dstp, bytestream2_get_byte(gb), op_size);
286  } else {
287  uint32_t table[256];
288  int ret, elements = 0;
289 
290  ret = fill_ltable(gb, table, &elements);
291  if (ret < 0)
292  return ret;
293  ret = get_opcodes(gb, table, dstp, op_size, elements);
294  if (ret < 0)
295  return ret;
296  }
297  return bytestream2_tell(gb) - pos;
298 }
299 
301  uint8_t *tex_data, int tex_size,
302  uint8_t *op_data, int *oindex,
303  int op_size,
304  uint8_t **dstp, int *statep,
305  uint8_t **tab0, uint8_t **tab1,
306  int offset)
307 {
308  uint8_t *dst = *dstp;
309  uint8_t *tptr0, *tptr1, *tptr3;
310  int oi = *oindex;
311  int state = *statep;
312  int opcode, v, vv;
313 
314  if (state <= 0) {
315  if (oi >= op_size)
316  return AVERROR_INVALIDDATA;
317  opcode = op_data[oi++];
318  if (!opcode) {
319  v = bytestream2_get_byte(gb);
320  if (v == 255) {
321  do {
322  if (bytestream2_get_bytes_left(gb) <= 0)
323  return AVERROR_INVALIDDATA;
324  opcode = bytestream2_get_le16(gb);
325  v += opcode;
326  } while (opcode == 0xFFFF);
327  }
328  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
329  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
330  state = v + 4;
331  goto done;
332  }
333 
334  switch (opcode) {
335  case 1:
336  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
337  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
338  break;
339  case 2:
340  vv = (8 + offset) * (bytestream2_get_le16(gb) + 1);
341  if (vv < 0 || vv > dst - tex_data)
342  return AVERROR_INVALIDDATA;
343  tptr0 = dst - vv;
344  v = AV_RL32(tptr0);
345  AV_WL32(dst, AV_RL32(tptr0));
346  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
347  tab0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
348  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
349  break;
350  case 3:
351  AV_WL32(dst, bytestream2_get_le32(gb));
352  AV_WL32(dst + 4, bytestream2_get_le32(gb));
353  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
354  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
355  break;
356  case 4:
357  tptr3 = tab1[bytestream2_get_byte(gb)];
358  if (!tptr3)
359  return AVERROR_INVALIDDATA;
360  AV_WL16(dst, bytestream2_get_le16(gb));
361  AV_WL16(dst + 2, AV_RL16(tptr3));
362  dst[4] = tptr3[2];
363  AV_WL16(dst + 5, bytestream2_get_le16(gb));
364  dst[7] = bytestream2_get_byte(gb);
365  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
366  break;
367  case 5:
368  tptr3 = tab1[bytestream2_get_byte(gb)];
369  if (!tptr3)
370  return AVERROR_INVALIDDATA;
371  AV_WL16(dst, bytestream2_get_le16(gb));
372  AV_WL16(dst + 2, bytestream2_get_le16(gb));
373  dst[4] = bytestream2_get_byte(gb);
374  AV_WL16(dst + 5, AV_RL16(tptr3));
375  dst[7] = tptr3[2];
376  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
377  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
378  break;
379  case 6:
380  tptr0 = tab1[bytestream2_get_byte(gb)];
381  if (!tptr0)
382  return AVERROR_INVALIDDATA;
383  tptr1 = tab1[bytestream2_get_byte(gb)];
384  if (!tptr1)
385  return AVERROR_INVALIDDATA;
386  AV_WL16(dst, bytestream2_get_le16(gb));
387  AV_WL16(dst + 2, AV_RL16(tptr0));
388  dst[4] = tptr0[2];
389  AV_WL16(dst + 5, AV_RL16(tptr1));
390  dst[7] = tptr1[2];
391  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
392  break;
393  case 7:
394  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
395  if (v < 0 || v > dst - tex_data)
396  return AVERROR_INVALIDDATA;
397  tptr0 = dst - v;
398  AV_WL16(dst, bytestream2_get_le16(gb));
399  AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
400  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
401  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
402  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
403  break;
404  case 8:
405  tptr1 = tab0[bytestream2_get_byte(gb)];
406  if (!tptr1)
407  return AVERROR_INVALIDDATA;
408  AV_WL16(dst, AV_RL16(tptr1));
409  AV_WL16(dst + 2, bytestream2_get_le16(gb));
410  AV_WL32(dst + 4, bytestream2_get_le32(gb));
411  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
412  break;
413  case 9:
414  tptr1 = tab0[bytestream2_get_byte(gb)];
415  if (!tptr1)
416  return AVERROR_INVALIDDATA;
417  tptr3 = tab1[bytestream2_get_byte(gb)];
418  if (!tptr3)
419  return AVERROR_INVALIDDATA;
420  AV_WL16(dst, AV_RL16(tptr1));
421  AV_WL16(dst + 2, AV_RL16(tptr3));
422  dst[4] = tptr3[2];
423  AV_WL16(dst + 5, bytestream2_get_le16(gb));
424  dst[7] = bytestream2_get_byte(gb);
425  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
426  break;
427  case 10:
428  tptr1 = tab0[bytestream2_get_byte(gb)];
429  if (!tptr1)
430  return AVERROR_INVALIDDATA;
431  tptr3 = tab1[bytestream2_get_byte(gb)];
432  if (!tptr3)
433  return AVERROR_INVALIDDATA;
434  AV_WL16(dst, AV_RL16(tptr1));
435  AV_WL16(dst + 2, bytestream2_get_le16(gb));
436  dst[4] = bytestream2_get_byte(gb);
437  AV_WL16(dst + 5, AV_RL16(tptr3));
438  dst[7] = tptr3[2];
439  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
440  break;
441  case 11:
442  tptr0 = tab0[bytestream2_get_byte(gb)];
443  if (!tptr0)
444  return AVERROR_INVALIDDATA;
445  tptr3 = tab1[bytestream2_get_byte(gb)];
446  if (!tptr3)
447  return AVERROR_INVALIDDATA;
448  tptr1 = tab1[bytestream2_get_byte(gb)];
449  if (!tptr1)
450  return AVERROR_INVALIDDATA;
451  AV_WL16(dst, AV_RL16(tptr0));
452  AV_WL16(dst + 2, AV_RL16(tptr3));
453  dst[4] = tptr3[2];
454  AV_WL16(dst + 5, AV_RL16(tptr1));
455  dst[7] = tptr1[2];
456  break;
457  case 12:
458  tptr1 = tab0[bytestream2_get_byte(gb)];
459  if (!tptr1)
460  return AVERROR_INVALIDDATA;
461  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
462  if (v < 0 || v > dst - tex_data)
463  return AVERROR_INVALIDDATA;
464  tptr0 = dst - v;
465  AV_WL16(dst, AV_RL16(tptr1));
466  AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
467  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
468  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
469  break;
470  case 13:
471  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
472  AV_WL16(dst + 2, bytestream2_get_le16(gb));
473  AV_WL32(dst + 4, bytestream2_get_le32(gb));
474  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
475  break;
476  case 14:
477  tptr3 = tab1[bytestream2_get_byte(gb)];
478  if (!tptr3)
479  return AVERROR_INVALIDDATA;
480  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
481  AV_WL16(dst + 2, AV_RL16(tptr3));
482  dst[4] = tptr3[2];
483  AV_WL16(dst + 5, bytestream2_get_le16(gb));
484  dst[7] = bytestream2_get_byte(gb);
485  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
486  break;
487  case 15:
488  tptr3 = tab1[bytestream2_get_byte(gb)];
489  if (!tptr3)
490  return AVERROR_INVALIDDATA;
491  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
492  AV_WL16(dst + 2, bytestream2_get_le16(gb));
493  dst[4] = bytestream2_get_byte(gb);
494  AV_WL16(dst + 5, AV_RL16(tptr3));
495  dst[7] = tptr3[2];
496  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
497  break;
498  case 16:
499  tptr3 = tab1[bytestream2_get_byte(gb)];
500  if (!tptr3)
501  return AVERROR_INVALIDDATA;
502  tptr1 = tab1[bytestream2_get_byte(gb)];
503  if (!tptr1)
504  return AVERROR_INVALIDDATA;
505  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
506  AV_WL16(dst + 2, AV_RL16(tptr3));
507  dst[4] = tptr3[2];
508  AV_WL16(dst + 5, AV_RL16(tptr1));
509  dst[7] = tptr1[2];
510  break;
511  case 17:
512  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
513  if (v < 0 || v > dst - tex_data)
514  return AVERROR_INVALIDDATA;
515  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
516  AV_WL16(dst + 2, AV_RL16(&dst[-v + 2]));
517  AV_WL32(dst + 4, AV_RL32(&dst[-v + 4]));
518  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
519  break;
520  default:
521  break;
522  }
523  } else {
524 done:
525  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
526  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
527  state--;
528  }
529  if (dst - tex_data + 8 > tex_size)
530  return AVERROR_INVALIDDATA;
531  dst += 8;
532 
533  *oindex = oi;
534  *dstp = dst;
535  *statep = state;
536 
537  return 0;
538 }
539 
541  uint8_t *tex_data, int tex_size,
542  uint8_t *op_data0, uint8_t *op_data1,
543  int max_op_size0, int max_op_size1)
544 {
545  uint8_t *dst, *tab2[256] = { 0 }, *tab0[256] = { 0 }, *tab3[256] = { 0 }, *tab1[256] = { 0 };
546  int op_offset = bytestream2_get_le32(gb);
547  unsigned op_size0 = bytestream2_get_le32(gb);
548  unsigned op_size1 = bytestream2_get_le32(gb);
549  int data_start = bytestream2_tell(gb);
550  int skip0, skip1, oi0 = 0, oi1 = 0;
551  int ret, state0 = 0, state1 = 0;
552 
553  if (op_offset < 12 || op_offset - 12 > bytestream2_get_bytes_left(gb))
554  return AVERROR_INVALIDDATA;
555 
556  dst = tex_data;
557  bytestream2_skip(gb, op_offset - 12);
558  if (op_size0 > max_op_size0)
559  return AVERROR_INVALIDDATA;
560  skip0 = dxv_decompress_opcodes(gb, op_data0, op_size0);
561  if (skip0 < 0)
562  return skip0;
563  if (op_size1 > max_op_size1)
564  return AVERROR_INVALIDDATA;
565  skip1 = dxv_decompress_opcodes(gb, op_data1, op_size1);
566  if (skip1 < 0)
567  return skip1;
568  bytestream2_seek(gb, data_start, SEEK_SET);
569 
570  AV_WL32(dst, bytestream2_get_le32(gb));
571  AV_WL32(dst + 4, bytestream2_get_le32(gb));
572  AV_WL32(dst + 8, bytestream2_get_le32(gb));
573  AV_WL32(dst + 12, bytestream2_get_le32(gb));
574 
575  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
576  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
577  tab2[0x9E3779B1 * AV_RL16(dst + 8) >> 24] = dst + 8;
578  tab3[0x9E3779B1 * (AV_RL32(dst + 10) & 0xFFFFFF) >> 24] = dst + 10;
579  dst += 16;
580  while (dst + 10 < tex_data + tex_size) {
581  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data0, &oi0, op_size0,
582  &dst, &state0, tab0, tab1, 8);
583  if (ret < 0)
584  return ret;
585  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data1, &oi1, op_size1,
586  &dst, &state1, tab2, tab3, 8);
587  if (ret < 0)
588  return ret;
589  }
590 
591  bytestream2_seek(gb, data_start - 12 + op_offset + skip0 + skip1, SEEK_SET);
592 
593  return 0;
594 }
595 
597  uint8_t *tex_data, int tex_size,
598  uint8_t *op_data, int max_op_size)
599 {
600  int op_offset = bytestream2_get_le32(gb);
601  unsigned op_size = bytestream2_get_le32(gb);
602  int data_start = bytestream2_tell(gb);
603  uint8_t *dst, *table0[256] = { 0 }, *table1[256] = { 0 };
604  int ret, state = 0, skip, oi = 0, v, vv;
605 
606  if (op_offset < 8 || op_offset - 8 > bytestream2_get_bytes_left(gb))
607  return AVERROR_INVALIDDATA;
608 
609  dst = tex_data;
610  bytestream2_skip(gb, op_offset - 8);
611  if (op_size > max_op_size)
612  return AVERROR_INVALIDDATA;
613  skip = dxv_decompress_opcodes(gb, op_data, op_size);
614  if (skip < 0)
615  return skip;
616  bytestream2_seek(gb, data_start, SEEK_SET);
617 
618  v = bytestream2_get_le32(gb);
619  AV_WL32(dst, v);
620  vv = bytestream2_get_le32(gb);
621  table0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
622  AV_WL32(dst + 4, vv);
623  table1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
624  dst += 8;
625 
626  while (dst < tex_data + tex_size) {
627  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data, &oi, op_size,
628  &dst, &state, table0, table1, 0);
629  if (ret < 0)
630  return ret;
631  }
632 
633  bytestream2_seek(gb, data_start + op_offset + skip - 8, SEEK_SET);
634 
635  return 0;
636 }
637 
639 {
640  DXVContext *ctx = avctx->priv_data;
641  GetByteContext *gb = &ctx->gbc;
642  int ret;
643 
644  ret = dxv_decompress_yo(ctx, gb, ctx->tex_data, ctx->tex_size,
645  ctx->op_data[0], ctx->op_size[0]);
646  if (ret < 0)
647  return ret;
648 
649  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
650  ctx->op_data[1], ctx->op_data[2],
651  ctx->op_size[1], ctx->op_size[2]);
652 }
653 
655 {
656  DXVContext *ctx = avctx->priv_data;
657  GetByteContext *gb = &ctx->gbc;
658  int ret;
659 
660  ret = dxv_decompress_cocg(ctx, gb, ctx->tex_data, ctx->tex_size,
661  ctx->op_data[0], ctx->op_data[3],
662  ctx->op_size[0], ctx->op_size[3]);
663  if (ret < 0)
664  return ret;
665 
666  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
667  ctx->op_data[1], ctx->op_data[2],
668  ctx->op_size[1], ctx->op_size[2]);
669 }
670 
672 {
673  DXVContext *ctx = avctx->priv_data;
674  GetByteContext *gbc = &ctx->gbc;
675  uint32_t value, op, prev;
676  int idx, state = 0;
677  int pos = 4;
678  int run = 0;
679  int probe, check;
680 
681  /* Copy the first four elements */
682  AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
683  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
684  AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
685  AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
686 
687  /* Process input until the whole texture has been filled */
688  while (pos + 2 <= ctx->tex_size / 4) {
689  if (run) {
690  run--;
691 
692  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
693  AV_WL32(ctx->tex_data + 4 * pos, prev);
694  pos++;
695  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
696  AV_WL32(ctx->tex_data + 4 * pos, prev);
697  pos++;
698  } else {
699  if (bytestream2_get_bytes_left(gbc) < 1)
700  return AVERROR_INVALIDDATA;
701  if (state == 0) {
702  value = bytestream2_get_le32(gbc);
703  state = 16;
704  }
705  op = value & 0x3;
706  value >>= 2;
707  state--;
708 
709  switch (op) {
710  case 0:
711  /* Long copy */
712  check = bytestream2_get_byte(gbc) + 1;
713  if (check == 256) {
714  do {
715  probe = bytestream2_get_le16(gbc);
716  check += probe;
717  } while (probe == 0xFFFF);
718  }
719  while (check && pos + 4 <= ctx->tex_size / 4) {
720  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
721  AV_WL32(ctx->tex_data + 4 * pos, prev);
722  pos++;
723 
724  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
725  AV_WL32(ctx->tex_data + 4 * pos, prev);
726  pos++;
727 
728  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
729  AV_WL32(ctx->tex_data + 4 * pos, prev);
730  pos++;
731 
732  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
733  AV_WL32(ctx->tex_data + 4 * pos, prev);
734  pos++;
735 
736  check--;
737  }
738 
739  /* Restart (or exit) the loop */
740  continue;
741  break;
742  case 1:
743  /* Load new run value */
744  run = bytestream2_get_byte(gbc);
745  if (run == 255) {
746  do {
747  probe = bytestream2_get_le16(gbc);
748  run += probe;
749  } while (probe == 0xFFFF);
750  }
751 
752  /* Copy two dwords from previous data */
753  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
754  AV_WL32(ctx->tex_data + 4 * pos, prev);
755  pos++;
756 
757  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
758  AV_WL32(ctx->tex_data + 4 * pos, prev);
759  pos++;
760  break;
761  case 2:
762  /* Copy two dwords from a previous index */
763  idx = 8 + 4 * bytestream2_get_le16(gbc);
764  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
765  return AVERROR_INVALIDDATA;
766  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
767  AV_WL32(ctx->tex_data + 4 * pos, prev);
768  pos++;
769 
770  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
771  AV_WL32(ctx->tex_data + 4 * pos, prev);
772  pos++;
773  break;
774  case 3:
775  /* Copy two dwords from input */
776  prev = bytestream2_get_le32(gbc);
777  AV_WL32(ctx->tex_data + 4 * pos, prev);
778  pos++;
779 
780  prev = bytestream2_get_le32(gbc);
781  AV_WL32(ctx->tex_data + 4 * pos, prev);
782  pos++;
783  break;
784  }
785  }
786 
787  CHECKPOINT(4);
788  if (pos + 2 > ctx->tex_size / 4)
789  return AVERROR_INVALIDDATA;
790 
791  /* Copy two elements from a previous offset or from the input buffer */
792  if (op) {
793  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
794  return AVERROR_INVALIDDATA;
795  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
796  AV_WL32(ctx->tex_data + 4 * pos, prev);
797  pos++;
798 
799  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
800  AV_WL32(ctx->tex_data + 4 * pos, prev);
801  pos++;
802  } else {
803  CHECKPOINT(4);
804 
805  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
806  return AVERROR_INVALIDDATA;
807  if (op)
808  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
809  else
810  prev = bytestream2_get_le32(gbc);
811  AV_WL32(ctx->tex_data + 4 * pos, prev);
812  pos++;
813 
814  CHECKPOINT(4);
815 
816  if (op)
817  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
818  else
819  prev = bytestream2_get_le32(gbc);
820  AV_WL32(ctx->tex_data + 4 * pos, prev);
821  pos++;
822  }
823  }
824 
825  return 0;
826 }
827 
829 {
830  DXVContext *ctx = avctx->priv_data;
831  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
832 }
833 
835 {
836  DXVContext *ctx = avctx->priv_data;
837  GetByteContext *gbc = &ctx->gbc;
838 
839  if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
840  return AVERROR_INVALIDDATA;
841 
842  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
843  return 0;
844 }
845 
847  int *got_frame, AVPacket *avpkt)
848 {
849  DXVContext *ctx = avctx->priv_data;
850  GetByteContext *gbc = &ctx->gbc;
851  TextureDSPThreadContext texdsp_ctx, ctexdsp_ctx;
852  int (*decompress_tex)(AVCodecContext *avctx);
853  const char *msgcomp, *msgtext;
854  uint32_t tag;
855  int version_major, version_minor = 0;
856  int size = 0, old_type = 0;
857  int ret;
858 
859  bytestream2_init(gbc, avpkt->data, avpkt->size);
860 
861  avctx->pix_fmt = AV_PIX_FMT_RGBA;
862  avctx->colorspace = AVCOL_SPC_RGB;
863 
864  tag = bytestream2_get_le32(gbc);
865  switch (tag) {
866  case DXV_FMT_DXT1:
867  decompress_tex = dxv_decompress_dxt1;
868  texdsp_ctx.tex_funct = ctx->texdsp.dxt1_block;
869  texdsp_ctx.tex_ratio = 8;
870  texdsp_ctx.raw_ratio = 16;
871  msgcomp = "DXTR1";
872  msgtext = "DXT1";
873  break;
874  case DXV_FMT_DXT5:
875  decompress_tex = dxv_decompress_dxt5;
876  /* DXV misnomers DXT5, alpha is premultiplied so use DXT4 instead */
877  texdsp_ctx.tex_funct = ctx->texdsp.dxt4_block;
878  texdsp_ctx.tex_ratio = 16;
879  texdsp_ctx.raw_ratio = 16;
880  msgcomp = "DXTR5";
881  msgtext = "DXT5";
882  break;
883  case DXV_FMT_YCG6:
884  decompress_tex = dxv_decompress_ycg6;
885  texdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
886  texdsp_ctx.tex_ratio = 8;
887  texdsp_ctx.raw_ratio = 4;
888  ctexdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
889  ctexdsp_ctx.tex_ratio = 16;
890  ctexdsp_ctx.raw_ratio = 4;
891  msgcomp = "YOCOCG6";
892  msgtext = "YCG6";
893  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
894  avctx->colorspace = AVCOL_SPC_YCOCG;
895  break;
896  case DXV_FMT_YG10:
897  decompress_tex = dxv_decompress_yg10;
898  texdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
899  texdsp_ctx.tex_ratio = 16;
900  texdsp_ctx.raw_ratio = 4;
901  ctexdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
902  ctexdsp_ctx.tex_ratio = 16;
903  ctexdsp_ctx.raw_ratio = 4;
904  msgcomp = "YAOCOCG10";
905  msgtext = "YG10";
906  avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
907  avctx->colorspace = AVCOL_SPC_YCOCG;
908  break;
909  default:
910  /* Old version does not have a real header, just size and type. */
911  size = tag & 0x00FFFFFF;
912  old_type = tag >> 24;
913  version_major = (old_type & 0x0F) - 1;
914 
915  if (old_type & 0x80) {
916  msgcomp = "RAW";
917  decompress_tex = dxv_decompress_raw;
918  } else {
919  msgcomp = "LZF";
920  decompress_tex = dxv_decompress_lzf;
921  }
922 
923  if (old_type & 0x40) {
924  tag = DXV_FMT_DXT5;
925  msgtext = "DXT5";
926 
927  texdsp_ctx.tex_funct = ctx->texdsp.dxt4_block;
928  texdsp_ctx.tex_ratio = 16;
929  texdsp_ctx.raw_ratio = 16;
930  } else if (old_type & 0x20 || version_major == 1) {
931  tag = DXV_FMT_DXT1;
932  msgtext = "DXT1";
933 
934  texdsp_ctx.tex_funct = ctx->texdsp.dxt1_block;
935  texdsp_ctx.tex_ratio = 8;
936  texdsp_ctx.raw_ratio = 16;
937  } else {
938  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
939  return AVERROR_INVALIDDATA;
940  }
941  break;
942  }
943 
944  texdsp_ctx.slice_count = av_clip(avctx->thread_count, 1,
945  avctx->coded_height / TEXTURE_BLOCK_H);
946  ctexdsp_ctx.slice_count = av_clip(avctx->thread_count, 1,
947  avctx->coded_height / 2 / TEXTURE_BLOCK_H);
948 
949  /* New header is 12 bytes long. */
950  if (!old_type) {
951  version_major = bytestream2_get_byte(gbc) - 1;
952  version_minor = bytestream2_get_byte(gbc);
953 
954  /* Encoder copies texture data when compression is not advantageous. */
955  if (bytestream2_get_byte(gbc)) {
956  msgcomp = "RAW";
957  decompress_tex = dxv_decompress_raw;
958  }
959 
960  bytestream2_skip(gbc, 1); // unknown
961  size = bytestream2_get_le32(gbc);
962  }
963  av_log(avctx, AV_LOG_DEBUG,
964  "%s compression with %s texture (version %d.%d)\n",
965  msgcomp, msgtext, version_major, version_minor);
966 
967  if (size != bytestream2_get_bytes_left(gbc)) {
968  av_log(avctx, AV_LOG_ERROR,
969  "Incomplete or invalid file (header %d, left %u).\n",
971  return AVERROR_INVALIDDATA;
972  }
973 
974  ctx->tex_size = avctx->coded_width / (texdsp_ctx.raw_ratio / (avctx->pix_fmt == AV_PIX_FMT_RGBA ? 4 : 1)) *
975  avctx->coded_height / TEXTURE_BLOCK_H *
976  texdsp_ctx.tex_ratio;
977  unsigned old_size = ctx->tex_data_size;
978  void *ptr = av_fast_realloc(ctx->tex_data, &ctx->tex_data_size, ctx->tex_size + AV_INPUT_BUFFER_PADDING_SIZE);
979  if (!ptr)
980  return AVERROR(ENOMEM);
981  ctx->tex_data = ptr;
982 
983  if (ctx->tex_data_size > old_size)
984  memset(ctx->tex_data + old_size, 0, ctx->tex_data_size - old_size);
985 
986  if (avctx->pix_fmt != AV_PIX_FMT_RGBA) {
987  int i;
988 
989  ctx->ctex_size = avctx->coded_width / 2 / ctexdsp_ctx.raw_ratio *
990  avctx->coded_height / 2 / TEXTURE_BLOCK_H *
991  ctexdsp_ctx.tex_ratio;
992 
993  ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
994  ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
995  ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
996  ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
997 
998  old_size = ctx->ctex_data_size;
999  ptr = av_fast_realloc(ctx->ctex_data, &ctx->ctex_data_size, ctx->ctex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1000  if (!ptr)
1001  return AVERROR(ENOMEM);
1002  ctx->ctex_data = ptr;
1003  if (old_size < ctx->ctex_data_size)
1004  memset(ctx->ctex_data + old_size, 0, ctx->ctex_data_size - old_size);
1005 
1006  for (i = 0; i < 4; i++) {
1007  old_size = ctx->op_data_size[i];
1008  ptr = av_fast_realloc(ctx->op_data[i], &ctx->op_data_size[i], ctx->op_size[i]);
1009  if (!ptr)
1010  return AVERROR(ENOMEM);
1011  ctx->op_data[i] = ptr;
1012  }
1013  }
1014 
1015  /* Decompress texture out of the intermediate compression. */
1016  ret = decompress_tex(avctx);
1017  if (ret < 0)
1018  return ret;
1019 
1020  ret = ff_thread_get_buffer(avctx, frame, 0);
1021  if (ret < 0)
1022  return ret;
1023 
1024  texdsp_ctx.width = avctx->coded_width;
1025  texdsp_ctx.height = avctx->coded_height;
1026  ctexdsp_ctx.width = avctx->coded_width / 2;
1027  ctexdsp_ctx.height = avctx->coded_height / 2;
1028  switch (tag) {
1029  case DXV_FMT_YG10:
1030  /* BC5 texture with alpha in the second half of each block */
1031  texdsp_ctx.tex_data.in = ctx->tex_data + texdsp_ctx.tex_ratio / 2;
1032  texdsp_ctx.frame_data.out = frame->data[3];
1033  texdsp_ctx.stride = frame->linesize[3];
1034  ret = ff_texturedsp_exec_decompress_threads(avctx, &texdsp_ctx);
1035  if (ret < 0)
1036  return ret;
1037  /* fallthrough */
1038  case DXV_FMT_YCG6:
1039  /* BC5 texture with Co in the first half of each block and Cg in the second */
1040  ctexdsp_ctx.tex_data.in = ctx->ctex_data;
1041  ctexdsp_ctx.frame_data.out = frame->data[2];
1042  ctexdsp_ctx.stride = frame->linesize[2];
1043  ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx);
1044  if (ret < 0)
1045  return ret;
1046  ctexdsp_ctx.tex_data.in = ctx->ctex_data + ctexdsp_ctx.tex_ratio / 2;
1047  ctexdsp_ctx.frame_data.out = frame->data[1];
1048  ctexdsp_ctx.stride = frame->linesize[1];
1049  ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx);
1050  if (ret < 0)
1051  return ret;
1052  /* fallthrough */
1053  case DXV_FMT_DXT1:
1054  case DXV_FMT_DXT5:
1055  /* For DXT1 and DXT5, self explanatory
1056  * For YCG6, BC4 texture for Y
1057  * For YG10, BC5 texture with Y in the first half of each block */
1058  texdsp_ctx.tex_data.in = ctx->tex_data;
1059  texdsp_ctx.frame_data.out = frame->data[0];
1060  texdsp_ctx.stride = frame->linesize[0];
1061  ret = ff_texturedsp_exec_decompress_threads(avctx, &texdsp_ctx);
1062  if (ret < 0)
1063  return ret;
1064  break;
1065  }
1066 
1067  /* Frame is ready to be output. */
1068  *got_frame = 1;
1069 
1070  return avpkt->size;
1071 }
1072 
1073 static av_cold int dxv_init(AVCodecContext *avctx)
1074 {
1075  DXVContext *ctx = avctx->priv_data;
1076  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1077 
1078  if (ret < 0) {
1079  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
1080  avctx->width, avctx->height);
1081  return ret;
1082  }
1083 
1084  /* Since codec is based on 4x4 blocks, size is aligned to 4 */
1085  avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W);
1086  avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
1087 
1088  ff_texturedsp_init(&ctx->texdsp);
1089 
1090  return 0;
1091 }
1092 
1094 {
1095  DXVContext *ctx = avctx->priv_data;
1096 
1097  av_freep(&ctx->tex_data);
1098  ctx->tex_data_size = 0;
1099 
1100  av_freep(&ctx->ctex_data);
1101  ctx->ctex_data_size = 0;
1102 
1103  av_freep(&ctx->op_data[0]);
1104  av_freep(&ctx->op_data[1]);
1105  av_freep(&ctx->op_data[2]);
1106  av_freep(&ctx->op_data[3]);
1107  memset(ctx->op_data_size, 0, sizeof(ctx->op_data_size));
1108 
1109  return 0;
1110 }
1111 
1113  .p.name = "dxv",
1114  CODEC_LONG_NAME("Resolume DXV"),
1115  .p.type = AVMEDIA_TYPE_VIDEO,
1116  .p.id = AV_CODEC_ID_DXV,
1117  .init = dxv_init,
1119  .close = dxv_close,
1120  .priv_data_size = sizeof(DXVContext),
1121  .p.capabilities = AV_CODEC_CAP_DR1 |
1124  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1125 };
DXV_FMT_DXT5
@ DXV_FMT_DXT5
Definition: dxv.h:29
DXVContext::op_data_size
unsigned op_data_size[4]
Definition: dxv.c:49
DXV_FMT_DXT1
@ DXV_FMT_DXT1
Definition: dxv.h:28
av_clip
#define av_clip
Definition: common.h:100
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:659
dxv_decompress_yg10
static int dxv_decompress_yg10(AVCodecContext *avctx)
Definition: dxv.c:654
TEXTURE_BLOCK_H
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:43
elements
static const ElemCat * elements[ELEMENT_COUNT]
Definition: signature.h:565
GetByteContext
Definition: bytestream.h:33
DXVContext::ctex_data
uint8_t * ctex_data
Definition: dxv.c:42
bytestream2_tell
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition: bytestream.h:192
dxv_decode
static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:846
fill_optable
static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
Definition: dxv.c:190
int64_t
long long int64_t
Definition: coverity.c:34
ff_clz
#define ff_clz
Definition: intmath.h:141
mask
int mask
Definition: mediacodecdec_common.c:154
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:421
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:212
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
AVCOL_SPC_YCOCG
@ AVCOL_SPC_YCOCG
Definition: pixfmt.h:700
AVPacket::data
uint8_t * data
Definition: packet.h:552
TextureDSPThreadContext::tex_ratio
int tex_ratio
Definition: texturedsp.h:80
table
static const uint16_t table[]
Definition: prosumer.c:203
half
static uint8_t half(int a, int b)
Definition: mobiclip.c:539
FFCodec
Definition: codec_internal.h:127
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:691
TextureDSPContext
Definition: texturedsp.h:45
DXVContext::gbc
GetByteContext gbc
Definition: dxv.c:38
OpcodeTable
Definition: dxv.c:140
thread.h
DXVContext::ctex_size
int64_t ctex_size
Definition: dxv.c:46
DXVContext::tex_data
uint8_t * tex_data
Definition: dxv.c:40
CHECKPOINT
#define CHECKPOINT(x)
Definition: dxv.c:59
dxv_decompress_ycg6
static int dxv_decompress_ycg6(AVCodecContext *avctx)
Definition: dxv.c:638
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
texturedsp.h
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
dxv_decompress_lzf
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:828
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1561
TextureDSPThreadContext::width
int width
Definition: texturedsp.h:75
val
static double val(void *priv, double ch)
Definition: aeval.c:77
DXVContext::op_data
uint8_t * op_data[4]
Definition: dxv.c:48
DXVContext::ctex_data_size
unsigned ctex_data_size
Definition: dxv.c:43
tab2
const int16_t * tab2
Definition: mace.c:145
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:607
dxv_decompress_cgo
static int dxv_decompress_cgo(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data, int *oindex, int op_size, uint8_t **dstp, int *statep, uint8_t **tab0, uint8_t **tab1, int offset)
Definition: dxv.c:300
tab1
const int16_t * tab1
Definition: mace.c:145
TextureDSPThreadContext
Definition: texturedsp.h:69
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:90
check
#define check(x, y, S, v)
Definition: motion_est_template.c:405
fill_ltable
static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
Definition: dxv.c:146
DXV_FMT_YG10
@ DXV_FMT_YG10
Definition: dxv.h:31
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:341
get_opcodes
static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
Definition: dxv.c:231
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
op
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
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1048
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
bits
uint8_t bits
Definition: vp3data.h:128
TextureDSPThreadContext::out
uint8_t * out
Definition: texturedsp.h:72
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_texturedsp_init
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:640
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
TextureDSPThreadContext::tex_data
union TextureDSPThreadContext::@263 tex_data
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:326
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
TextureDSPThreadContext::stride
ptrdiff_t stride
Definition: texturedsp.h:74
dxv_close
static av_cold int dxv_close(AVCodecContext *avctx)
Definition: dxv.c:1093
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:95
run
uint8_t run
Definition: svq3.c:207
dxv_decompress_dxt1
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition: dxv.c:91
TextureDSPThreadContext::height
int height
Definition: texturedsp.h:75
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
ff_texturedsp_exec_decompress_threads
int ff_texturedsp_exec_decompress_threads(struct AVCodecContext *avctx, TextureDSPThreadContext *ctx)
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:553
codec_internal.h
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
DXV_FMT_YCG6
@ DXV_FMT_YCG6
Definition: dxv.h:30
AV_CODEC_ID_DXV
@ AV_CODEC_ID_DXV
Definition: codec_id.h:245
size
int size
Definition: twinvq_data.h:10344
ff_lzf_uncompress
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
Definition: lzf.c:40
DXVContext::op_size
int64_t op_size[4]
Definition: dxv.c:50
OpcodeTable::val2
uint8_t val2
Definition: dxv.c:143
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:408
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:99
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
DXVContext
Definition: dxv.c:36
OpcodeTable::next
int16_t next
Definition: dxv.c:141
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_dxv_decoder
const FFCodec ff_dxv_decoder
Definition: dxv.c:1112
dxv_init
static av_cold int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:1073
TextureDSPThreadContext::slice_count
int slice_count
Definition: texturedsp.h:82
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
TextureDSPThreadContext::frame_data
union TextureDSPThreadContext::@262 frame_data
TEXTURE_BLOCK_W
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:42
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
dxv_decompress_yo
static int dxv_decompress_yo(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data, int max_op_size)
Definition: dxv.c:596
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
avcodec.h
tag
uint32_t tag
Definition: movenc.c:1957
ret
ret
Definition: filter_design.txt:187
DXVContext::tex_data_size
unsigned tex_data_size
Definition: dxv.c:41
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
DXVContext::tex_size
int64_t tex_size
Definition: dxv.c:45
pos
unsigned int pos
Definition: spdifenc.c:414
flag
#define flag(name)
Definition: cbs_av1.c:495
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVCodecContext
main external API structure.
Definition: avcodec.h:431
probe
static int probe(const AVProbeData *p)
Definition: act.c:39
dxv_decompress_opcodes
static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
Definition: dxv.c:273
OpcodeTable::val1
uint8_t val1
Definition: dxv.c:142
TextureDSPThreadContext::tex_funct
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:85
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:607
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
TextureDSPThreadContext::raw_ratio
int raw_ratio
Definition: texturedsp.h:81
dxv.h
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:529
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
TextureDSPThreadContext::in
const uint8_t * in
Definition: texturedsp.h:71
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
bytestream.h
imgutils.h
state
static struct @511 state
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
dxv_decompress_dxt5
static int dxv_decompress_dxt5(AVCodecContext *avctx)
Definition: dxv.c:671
dxv_decompress_cocg
static int dxv_decompress_cocg(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data0, uint8_t *op_data1, int max_op_size0, int max_op_size1)
Definition: dxv.c:540
av_image_check_size
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:318
dxv_decompress_raw
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:834
lzf.h
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:383
src
#define src
Definition: vp8dsp.c:248
DXVContext::texdsp
TextureDSPContext texdsp
Definition: dxv.c:37