FFmpeg
hapdec.c
Go to the documentation of this file.
1 /*
2  * Vidvox Hap decoder
3  * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
4  * Copyright (C) 2015 Tom Butterworth <bangnoise@gmail.com>
5  *
6  * HapQA and HAPAlphaOnly added by Jokyo Images
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 /**
26  * @file
27  * Hap decoder
28  *
29  * Fourcc: Hap1, Hap5, HapY, HapA, HapM
30  *
31  * https://github.com/Vidvox/hap/blob/master/documentation/HapVideoDRAFT.md
32  */
33 
34 #include <stdint.h>
35 
36 #include "libavutil/imgutils.h"
37 #include "libavutil/mem.h"
38 
39 #include "avcodec.h"
40 #include "bytestream.h"
41 #include "codec_internal.h"
42 #include "hap.h"
43 #include "snappy.h"
44 #include "texturedsp.h"
45 #include "thread.h"
46 
48 {
49  GetByteContext *gbc = &ctx->gbc;
50  int section_size;
51  enum HapSectionType section_type;
52  int is_first_table = 1, had_offsets = 0, had_compressors = 0, had_sizes = 0;
53  int i, ret;
54 
55  while (size > 0) {
56  int stream_remaining = bytestream2_get_bytes_left(gbc);
57  ret = ff_hap_parse_section_header(gbc, &section_size, &section_type);
58  if (ret != 0)
59  return ret;
60 
61  size -= stream_remaining - bytestream2_get_bytes_left(gbc);
62 
63  switch (section_type) {
65  ret = ff_hap_set_chunk_count(ctx, section_size, is_first_table);
66  if (ret != 0)
67  return ret;
68  for (i = 0; i < section_size; i++) {
69  ctx->chunks[i].compressor = bytestream2_get_byte(gbc) << 4;
70  }
71  had_compressors = 1;
72  is_first_table = 0;
73  break;
74  case HAP_ST_SIZE_TABLE:
75  ret = ff_hap_set_chunk_count(ctx, section_size / 4, is_first_table);
76  if (ret != 0)
77  return ret;
78  for (i = 0; i < section_size / 4; i++) {
79  ctx->chunks[i].compressed_size = bytestream2_get_le32(gbc);
80  }
81  had_sizes = 1;
82  is_first_table = 0;
83  break;
85  ret = ff_hap_set_chunk_count(ctx, section_size / 4, is_first_table);
86  if (ret != 0)
87  return ret;
88  for (i = 0; i < section_size / 4; i++) {
89  ctx->chunks[i].compressed_offset = bytestream2_get_le32(gbc);
90  }
91  had_offsets = 1;
92  is_first_table = 0;
93  break;
94  default:
95  break;
96  }
97  size -= section_size;
98  }
99 
100  if (!had_sizes || !had_compressors)
101  return AVERROR_INVALIDDATA;
102 
103  /* The offsets table is optional. If not present than calculate offsets by
104  * summing the sizes of preceding chunks. */
105  if (!had_offsets) {
106  size_t running_size = 0;
107  for (i = 0; i < ctx->chunk_count; i++) {
108  ctx->chunks[i].compressed_offset = running_size;
109  if (ctx->chunks[i].compressed_size > UINT32_MAX - running_size)
110  return AVERROR_INVALIDDATA;
111  running_size += ctx->chunks[i].compressed_size;
112  }
113  }
114 
115  return 0;
116 }
117 
119 {
120  int i;
121  size_t running_offset = 0;
122  for (i = 0; i < ctx->chunk_count; i++) {
123  if (ctx->chunks[i].compressed_offset != running_offset
124  || ctx->chunks[i].compressor != HAP_COMP_NONE)
125  return 0;
126  running_offset += ctx->chunks[i].compressed_size;
127  }
128  return 1;
129 }
130 
132 {
133  HapContext *ctx = avctx->priv_data;
134  GetByteContext *gbc = &ctx->gbc;
135  int section_size;
136  enum HapSectionType section_type;
137  const char *compressorstr;
138  int i, ret;
139 
140  ret = ff_hap_parse_section_header(gbc, &ctx->texture_section_size, &section_type);
141  if (ret != 0)
142  return ret;
143 
144  if ((avctx->codec_tag == MKTAG('H','a','p','1') && (section_type & 0x0F) != HAP_FMT_RGBDXT1) ||
145  (avctx->codec_tag == MKTAG('H','a','p','5') && (section_type & 0x0F) != HAP_FMT_RGBADXT5) ||
146  (avctx->codec_tag == MKTAG('H','a','p','Y') && (section_type & 0x0F) != HAP_FMT_YCOCGDXT5) ||
147  (avctx->codec_tag == MKTAG('H','a','p','A') && (section_type & 0x0F) != HAP_FMT_RGTC1) ||
148  ((avctx->codec_tag == MKTAG('H','a','p','M') && (section_type & 0x0F) != HAP_FMT_RGTC1) &&
149  (section_type & 0x0F) != HAP_FMT_YCOCGDXT5)) {
150  av_log(avctx, AV_LOG_ERROR,
151  "Invalid texture format %#04x.\n", section_type & 0x0F);
152  return AVERROR_INVALIDDATA;
153  }
154 
155  switch (section_type & 0xF0) {
156  case HAP_COMP_NONE:
157  case HAP_COMP_SNAPPY:
158  ret = ff_hap_set_chunk_count(ctx, 1, 1);
159  if (ret == 0) {
160  ctx->chunks[0].compressor = section_type & 0xF0;
161  ctx->chunks[0].compressed_offset = 0;
162  ctx->chunks[0].compressed_size = ctx->texture_section_size;
163  }
164  if (ctx->chunks[0].compressor == HAP_COMP_NONE) {
165  compressorstr = "none";
166  } else {
167  compressorstr = "snappy";
168  }
169  break;
170  case HAP_COMP_COMPLEX:
171  ret = ff_hap_parse_section_header(gbc, &section_size, &section_type);
172  if (ret == 0 && section_type != HAP_ST_DECODE_INSTRUCTIONS)
174  if (ret == 0)
175  ret = hap_parse_decode_instructions(ctx, section_size);
176  compressorstr = "complex";
177  break;
178  default:
180  break;
181  }
182 
183  if (ret != 0)
184  return ret;
185 
186  /* Check the frame is valid and read the uncompressed chunk sizes */
187  ctx->tex_size = 0;
188  for (i = 0; i < ctx->chunk_count; i++) {
189  HapChunk *chunk = &ctx->chunks[i];
190 
191  /* Check the compressed buffer is valid */
192  if (chunk->compressed_offset + (uint64_t)chunk->compressed_size > bytestream2_get_bytes_left(gbc))
193  return AVERROR_INVALIDDATA;
194 
195  /* Chunks are unpacked sequentially, ctx->tex_size is the uncompressed
196  * size thus far */
197  chunk->uncompressed_offset = ctx->tex_size;
198 
199  /* Fill out uncompressed size */
200  if (chunk->compressor == HAP_COMP_SNAPPY) {
201  GetByteContext gbc_tmp;
202  int64_t uncompressed_size;
203  bytestream2_init(&gbc_tmp, gbc->buffer + chunk->compressed_offset,
204  chunk->compressed_size);
205  uncompressed_size = ff_snappy_peek_uncompressed_length(&gbc_tmp);
206  if (uncompressed_size < 0) {
207  return uncompressed_size;
208  }
209  chunk->uncompressed_size = uncompressed_size;
210  } else if (chunk->compressor == HAP_COMP_NONE) {
211  chunk->uncompressed_size = chunk->compressed_size;
212  } else {
213  return AVERROR_INVALIDDATA;
214  }
215  ctx->tex_size += chunk->uncompressed_size;
216  }
217 
218  av_log(avctx, AV_LOG_DEBUG, "%s compressor\n", compressorstr);
219 
220  return ret;
221 }
222 
223 static int decompress_chunks_thread(AVCodecContext *avctx, void *arg,
224  int chunk_nb, int thread_nb)
225 {
226  HapContext *ctx = avctx->priv_data;
227 
228  HapChunk *chunk = &ctx->chunks[chunk_nb];
229  GetByteContext gbc;
230  uint8_t *dst = ctx->tex_buf + chunk->uncompressed_offset;
231 
232  bytestream2_init(&gbc, ctx->gbc.buffer + chunk->compressed_offset, chunk->compressed_size);
233 
234  if (chunk->compressor == HAP_COMP_SNAPPY) {
235  int ret;
236  int64_t uncompressed_size = ctx->tex_size;
237 
238  /* Uncompress the frame */
239  ret = ff_snappy_uncompress(&gbc, dst, &uncompressed_size);
240  if (ret < 0) {
241  av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n");
242  return ret;
243  }
244  } else if (chunk->compressor == HAP_COMP_NONE) {
246  }
247 
248  return 0;
249 }
250 
252  int *got_frame, AVPacket *avpkt)
253 {
254  HapContext *ctx = avctx->priv_data;
255  int ret, i, t;
256  int section_size;
257  enum HapSectionType section_type;
258  int start_texture_section = 0;
259 
260  bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
261 
262  /* check for multi texture header */
263  if (ctx->texture_count == 2) {
264  ret = ff_hap_parse_section_header(&ctx->gbc, &section_size, &section_type);
265  if (ret != 0)
266  return ret;
267  if ((section_type & 0x0F) != 0x0D) {
268  av_log(avctx, AV_LOG_ERROR, "Invalid section type in 2 textures mode %#04x.\n", section_type);
269  return AVERROR_INVALIDDATA;
270  }
271  start_texture_section = 4;
272  }
273 
274  /* Get the output frame ready to receive data */
275  ret = ff_thread_get_buffer(avctx, frame, 0);
276  if (ret < 0)
277  return ret;
278 
279  for (t = 0; t < ctx->texture_count; t++) {
280  bytestream2_seek(&ctx->gbc, start_texture_section, SEEK_SET);
281 
282  /* Check for section header */
283  ret = hap_parse_frame_header(avctx);
284  if (ret < 0)
285  return ret;
286 
287  if (ctx->tex_size != (avctx->coded_width / TEXTURE_BLOCK_W)
288  *(avctx->coded_height / TEXTURE_BLOCK_H)
289  *ctx->dec[t].tex_ratio) {
290  av_log(avctx, AV_LOG_ERROR, "uncompressed size mismatches\n");
291  return AVERROR_INVALIDDATA;
292  }
293 
294  start_texture_section += ctx->texture_section_size + 4;
295 
296  /* Unpack the DXT texture */
298  int tex_size;
299  /* Only DXTC texture compression in a contiguous block */
300  ctx->dec[t].tex_data.in = ctx->gbc.buffer;
301  tex_size = FFMIN(ctx->texture_section_size, bytestream2_get_bytes_left(&ctx->gbc));
302  if (tex_size < (avctx->coded_width / TEXTURE_BLOCK_W)
303  *(avctx->coded_height / TEXTURE_BLOCK_H)
304  *ctx->dec[t].tex_ratio) {
305  av_log(avctx, AV_LOG_ERROR, "Insufficient data\n");
306  return AVERROR_INVALIDDATA;
307  }
308  } else {
309  /* Perform the second-stage decompression */
310  ret = av_reallocp(&ctx->tex_buf, ctx->tex_size);
311  if (ret < 0)
312  return ret;
313 
314  avctx->execute2(avctx, decompress_chunks_thread, NULL,
315  ctx->chunk_results, ctx->chunk_count);
316 
317  for (i = 0; i < ctx->chunk_count; i++) {
318  if (ctx->chunk_results[i] < 0)
319  return ctx->chunk_results[i];
320  }
321 
322  ctx->dec[t].tex_data.in = ctx->tex_buf;
323  }
324 
325  ctx->dec[t].frame_data.out = frame->data[0];
326  ctx->dec[t].stride = frame->linesize[0];
327  ctx->dec[t].width = avctx->coded_width;
328  ctx->dec[t].height = avctx->coded_height;
330  }
331 
332  /* Frame is ready to be output */
333  *got_frame = 1;
334 
335  return avpkt->size;
336 }
337 
338 static av_cold int hap_init(AVCodecContext *avctx)
339 {
340  HapContext *ctx = avctx->priv_data;
341  TextureDSPContext dxtc;
342  const char *texture_name;
343  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
344 
345  if (ret < 0) {
346  av_log(avctx, AV_LOG_ERROR, "Invalid video size %dx%d.\n",
347  avctx->width, avctx->height);
348  return ret;
349  }
350 
351  /* Since codec is based on 4x4 blocks, size is aligned to 4 */
352  avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W);
353  avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
354 
355  ff_texturedsp_init(&dxtc);
356 
357  ctx->texture_count = 1;
358  ctx->dec[0].raw_ratio = 16;
359  ctx->dec[0].slice_count = av_clip(avctx->thread_count, 1,
360  avctx->coded_height / TEXTURE_BLOCK_H);
361 
362  switch (avctx->codec_tag) {
363  case MKTAG('H','a','p','1'):
364  texture_name = "DXT1";
365  ctx->dec[0].tex_ratio = 8;
366  ctx->dec[0].tex_funct = dxtc.dxt1_block;
367  avctx->pix_fmt = AV_PIX_FMT_RGB0;
368  break;
369  case MKTAG('H','a','p','5'):
370  texture_name = "DXT5";
371  ctx->dec[0].tex_ratio = 16;
372  ctx->dec[0].tex_funct = dxtc.dxt5_block;
373  avctx->pix_fmt = AV_PIX_FMT_RGBA;
374  break;
375  case MKTAG('H','a','p','Y'):
376  texture_name = "DXT5-YCoCg-scaled";
377  ctx->dec[0].tex_ratio = 16;
378  ctx->dec[0].tex_funct = dxtc.dxt5ys_block;
379  avctx->pix_fmt = AV_PIX_FMT_RGB0;
380  break;
381  case MKTAG('H','a','p','A'):
382  texture_name = "RGTC1";
383  ctx->dec[0].tex_ratio = 8;
384  ctx->dec[0].tex_funct = dxtc.rgtc1u_gray_block;
385  ctx->dec[0].raw_ratio = 4;
386  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
387  break;
388  case MKTAG('H','a','p','M'):
389  texture_name = "DXT5-YCoCg-scaled / RGTC1";
390  ctx->dec[0].tex_ratio = 16;
391  ctx->dec[1].tex_ratio = 8;
392  ctx->dec[0].tex_funct = dxtc.dxt5ys_block;
393  ctx->dec[1].tex_funct = dxtc.rgtc1u_alpha_block;
394  ctx->dec[1].raw_ratio = 16;
395  ctx->dec[1].slice_count = ctx->dec[0].slice_count;
396  avctx->pix_fmt = AV_PIX_FMT_RGBA;
397  ctx->texture_count = 2;
398  break;
399  default:
401  }
402 
403  av_log(avctx, AV_LOG_DEBUG, "%s texture\n", texture_name);
404 
405  return 0;
406 }
407 
408 static av_cold int hap_close(AVCodecContext *avctx)
409 {
410  HapContext *ctx = avctx->priv_data;
411 
413 
414  return 0;
415 }
416 
418  .p.name = "hap",
419  CODEC_LONG_NAME("Vidvox Hap"),
420  .p.type = AVMEDIA_TYPE_VIDEO,
421  .p.id = AV_CODEC_ID_HAP,
422  .init = hap_init,
424  .close = hap_close,
425  .priv_data_size = sizeof(HapContext),
428  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
429  .codec_tags = (const uint32_t []){
430  MKTAG('H','a','p','1'),
431  MKTAG('H','a','p','5'),
432  MKTAG('H','a','p','Y'),
433  MKTAG('H','a','p','A'),
434  MKTAG('H','a','p','M'),
436  },
437 };
HAP_FMT_YCOCGDXT5
@ HAP_FMT_YCOCGDXT5
Definition: hap.h:35
av_clip
#define av_clip
Definition: common.h:100
TextureDSPContext::dxt1_block
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
TextureDSPContext::rgtc1u_alpha_block
int(* rgtc1u_alpha_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:57
TextureDSPContext::rgtc1u_gray_block
int(* rgtc1u_gray_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:56
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:43
TEXTURE_BLOCK_H
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:43
GetByteContext
Definition: bytestream.h:33
int64_t
long long int64_t
Definition: coverity.c:34
TextureDSPContext::dxt5ys_block
int(* dxt5ys_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:53
HapChunk::compressed_size
size_t compressed_size
Definition: hap.h:55
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:212
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
AVPacket::data
uint8_t * data
Definition: packet.h:539
ff_hap_parse_section_header
int ff_hap_parse_section_header(GetByteContext *gbc, int *section_size, enum HapSectionType *section_type)
Definition: hap.c:58
FFCodec
Definition: codec_internal.h:127
TextureDSPContext
Definition: texturedsp.h:45
thread.h
HapContext
Definition: hap.h:60
texturedsp.h
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
hap_parse_decode_instructions
static int hap_parse_decode_instructions(HapContext *ctx, int size)
Definition: hapdec.c:47
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1593
hap.h
hap_decode
static int hap_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: hapdec.c:251
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:639
HAP_FMT_RGBADXT5
@ HAP_FMT_RGBADXT5
Definition: hap.h:34
HAP_COMP_SNAPPY
@ HAP_COMP_SNAPPY
Definition: hap.h:41
FF_CODEC_TAGS_END
#define FF_CODEC_TAGS_END
FFCodec.codec_tags termination value.
Definition: codec_internal.h:95
TextureDSPContext::dxt5_block
int(* dxt5_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:51
HAP_FMT_RGTC1
@ HAP_FMT_RGTC1
Definition: hap.h:36
hap_close
static av_cold int hap_close(AVCodecContext *avctx)
Definition: hapdec.c:408
HAP_COMP_NONE
@ HAP_COMP_NONE
Definition: hap.h:40
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_cold
#define av_cold
Definition: attributes.h:90
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:311
ff_hap_free_context
av_cold void ff_hap_free_context(HapContext *ctx)
Definition: hap.c:51
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:1049
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
HAP_ST_SIZE_TABLE
@ HAP_ST_SIZE_TABLE
Definition: hap.h:48
hap_init
static av_cold int hap_init(AVCodecContext *avctx)
Definition: hapdec.c:338
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_texturedsp_init
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:640
snappy.h
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:296
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
arg
const char * arg
Definition: jacosubdec.c:67
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:110
NULL
#define NULL
Definition: coverity.c:32
decompress_chunks_thread
static int decompress_chunks_thread(AVCodecContext *avctx, void *arg, int chunk_nb, int thread_nb)
Definition: hapdec.c:223
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
HAP_ST_DECODE_INSTRUCTIONS
@ HAP_ST_DECODE_INSTRUCTIONS
Definition: hap.h:46
HAP_COMP_COMPLEX
@ HAP_COMP_COMPLEX
Definition: hap.h:42
ff_hap_set_chunk_count
int ff_hap_set_chunk_count(HapContext *ctx, int count, int first_in_frame)
Definition: hap.c:29
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
HapChunk::uncompressed_size
size_t uncompressed_size
Definition: hap.h:57
ff_hap_decoder
const FFCodec ff_hap_decoder
Definition: hapdec.c:417
ff_texturedsp_exec_decompress_threads
int ff_texturedsp_exec_decompress_threads(struct AVCodecContext *avctx, TextureDSPThreadContext *ctx)
HapSectionType
HapSectionType
Definition: hap.h:45
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:540
codec_internal.h
HapChunk::compressor
enum HapCompressor compressor
Definition: hap.h:53
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
size
int size
Definition: twinvq_data.h:10344
av_reallocp
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:188
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:114
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
HAP_ST_COMPRESSOR_TABLE
@ HAP_ST_COMPRESSOR_TABLE
Definition: hap.h:47
HapChunk
Definition: hap.h:52
HapChunk::uncompressed_offset
int uncompressed_offset
Definition: hap.h:56
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
TEXTURE_BLOCK_W
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:42
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
AVCodecContext::height
int height
Definition: avcodec.h:624
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:663
avcodec.h
ret
ret
Definition: filter_design.txt:187
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:264
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AV_CODEC_ID_HAP
@ AV_CODEC_ID_HAP
Definition: codec_id.h:243
HAP_ST_OFFSET_TABLE
@ HAP_ST_OFFSET_TABLE
Definition: hap.h:49
HAP_FMT_RGBDXT1
@ HAP_FMT_RGBDXT1
Definition: hap.h:33
AVERROR_DECODER_NOT_FOUND
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:54
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:639
ff_snappy_peek_uncompressed_length
int64_t ff_snappy_peek_uncompressed_length(GetByteContext *gb)
Get the uncompressed length of an input buffer compressed using the Snappy algorithm.
Definition: snappy.c:131
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
hap_can_use_tex_in_place
static int hap_can_use_tex_in_place(HapContext *ctx)
Definition: hapdec.c:118
AVCodecContext::codec_tag
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:476
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
ff_snappy_uncompress
int ff_snappy_uncompress(GetByteContext *gb, uint8_t *buf, int64_t *size)
Decompress an input buffer using Snappy algorithm.
Definition: snappy.c:141
HapChunk::compressed_offset
uint32_t compressed_offset
Definition: hap.h:54
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
bytestream.h
imgutils.h
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
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
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
AVCodecContext::execute2
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:1642
hap_parse_frame_header
static int hap_parse_frame_header(AVCodecContext *avctx)
Definition: hapdec.c:131