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 
38 #include "avcodec.h"
39 #include "bytestream.h"
40 #include "codec_internal.h"
41 #include "hap.h"
42 #include "snappy.h"
43 #include "texturedsp.h"
44 #include "thread.h"
45 
47 {
48  GetByteContext *gbc = &ctx->gbc;
49  int section_size;
50  enum HapSectionType section_type;
51  int is_first_table = 1, had_offsets = 0, had_compressors = 0, had_sizes = 0;
52  int i, ret;
53 
54  while (size > 0) {
55  int stream_remaining = bytestream2_get_bytes_left(gbc);
56  ret = ff_hap_parse_section_header(gbc, &section_size, &section_type);
57  if (ret != 0)
58  return ret;
59 
60  size -= stream_remaining - bytestream2_get_bytes_left(gbc);
61 
62  switch (section_type) {
64  ret = ff_hap_set_chunk_count(ctx, section_size, is_first_table);
65  if (ret != 0)
66  return ret;
67  for (i = 0; i < section_size; i++) {
68  ctx->chunks[i].compressor = bytestream2_get_byte(gbc) << 4;
69  }
70  had_compressors = 1;
71  is_first_table = 0;
72  break;
73  case HAP_ST_SIZE_TABLE:
74  ret = ff_hap_set_chunk_count(ctx, section_size / 4, is_first_table);
75  if (ret != 0)
76  return ret;
77  for (i = 0; i < section_size / 4; i++) {
78  ctx->chunks[i].compressed_size = bytestream2_get_le32(gbc);
79  }
80  had_sizes = 1;
81  is_first_table = 0;
82  break;
84  ret = ff_hap_set_chunk_count(ctx, section_size / 4, is_first_table);
85  if (ret != 0)
86  return ret;
87  for (i = 0; i < section_size / 4; i++) {
88  ctx->chunks[i].compressed_offset = bytestream2_get_le32(gbc);
89  }
90  had_offsets = 1;
91  is_first_table = 0;
92  break;
93  default:
94  break;
95  }
96  size -= section_size;
97  }
98 
99  if (!had_sizes || !had_compressors)
100  return AVERROR_INVALIDDATA;
101 
102  /* The offsets table is optional. If not present than calculate offsets by
103  * summing the sizes of preceding chunks. */
104  if (!had_offsets) {
105  size_t running_size = 0;
106  for (i = 0; i < ctx->chunk_count; i++) {
107  ctx->chunks[i].compressed_offset = running_size;
108  if (ctx->chunks[i].compressed_size > UINT32_MAX - running_size)
109  return AVERROR_INVALIDDATA;
110  running_size += ctx->chunks[i].compressed_size;
111  }
112  }
113 
114  return 0;
115 }
116 
118 {
119  int i;
120  size_t running_offset = 0;
121  for (i = 0; i < ctx->chunk_count; i++) {
122  if (ctx->chunks[i].compressed_offset != running_offset
123  || ctx->chunks[i].compressor != HAP_COMP_NONE)
124  return 0;
125  running_offset += ctx->chunks[i].compressed_size;
126  }
127  return 1;
128 }
129 
131 {
132  HapContext *ctx = avctx->priv_data;
133  GetByteContext *gbc = &ctx->gbc;
134  int section_size;
135  enum HapSectionType section_type;
136  const char *compressorstr;
137  int i, ret;
138 
139  ret = ff_hap_parse_section_header(gbc, &ctx->texture_section_size, &section_type);
140  if (ret != 0)
141  return ret;
142 
143  if ((avctx->codec_tag == MKTAG('H','a','p','1') && (section_type & 0x0F) != HAP_FMT_RGBDXT1) ||
144  (avctx->codec_tag == MKTAG('H','a','p','5') && (section_type & 0x0F) != HAP_FMT_RGBADXT5) ||
145  (avctx->codec_tag == MKTAG('H','a','p','Y') && (section_type & 0x0F) != HAP_FMT_YCOCGDXT5) ||
146  (avctx->codec_tag == MKTAG('H','a','p','A') && (section_type & 0x0F) != HAP_FMT_RGTC1) ||
147  ((avctx->codec_tag == MKTAG('H','a','p','M') && (section_type & 0x0F) != HAP_FMT_RGTC1) &&
148  (section_type & 0x0F) != HAP_FMT_YCOCGDXT5)) {
149  av_log(avctx, AV_LOG_ERROR,
150  "Invalid texture format %#04x.\n", section_type & 0x0F);
151  return AVERROR_INVALIDDATA;
152  }
153 
154  switch (section_type & 0xF0) {
155  case HAP_COMP_NONE:
156  case HAP_COMP_SNAPPY:
157  ret = ff_hap_set_chunk_count(ctx, 1, 1);
158  if (ret == 0) {
159  ctx->chunks[0].compressor = section_type & 0xF0;
160  ctx->chunks[0].compressed_offset = 0;
161  ctx->chunks[0].compressed_size = ctx->texture_section_size;
162  }
163  if (ctx->chunks[0].compressor == HAP_COMP_NONE) {
164  compressorstr = "none";
165  } else {
166  compressorstr = "snappy";
167  }
168  break;
169  case HAP_COMP_COMPLEX:
170  ret = ff_hap_parse_section_header(gbc, &section_size, &section_type);
171  if (ret == 0 && section_type != HAP_ST_DECODE_INSTRUCTIONS)
173  if (ret == 0)
174  ret = hap_parse_decode_instructions(ctx, section_size);
175  compressorstr = "complex";
176  break;
177  default:
179  break;
180  }
181 
182  if (ret != 0)
183  return ret;
184 
185  /* Check the frame is valid and read the uncompressed chunk sizes */
186  ctx->tex_size = 0;
187  for (i = 0; i < ctx->chunk_count; i++) {
188  HapChunk *chunk = &ctx->chunks[i];
189 
190  /* Check the compressed buffer is valid */
191  if (chunk->compressed_offset + (uint64_t)chunk->compressed_size > bytestream2_get_bytes_left(gbc))
192  return AVERROR_INVALIDDATA;
193 
194  /* Chunks are unpacked sequentially, ctx->tex_size is the uncompressed
195  * size thus far */
196  chunk->uncompressed_offset = ctx->tex_size;
197 
198  /* Fill out uncompressed size */
199  if (chunk->compressor == HAP_COMP_SNAPPY) {
200  GetByteContext gbc_tmp;
201  int64_t uncompressed_size;
202  bytestream2_init(&gbc_tmp, gbc->buffer + chunk->compressed_offset,
203  chunk->compressed_size);
204  uncompressed_size = ff_snappy_peek_uncompressed_length(&gbc_tmp);
205  if (uncompressed_size < 0) {
206  return uncompressed_size;
207  }
208  chunk->uncompressed_size = uncompressed_size;
209  } else if (chunk->compressor == HAP_COMP_NONE) {
210  chunk->uncompressed_size = chunk->compressed_size;
211  } else {
212  return AVERROR_INVALIDDATA;
213  }
214  ctx->tex_size += chunk->uncompressed_size;
215  }
216 
217  av_log(avctx, AV_LOG_DEBUG, "%s compressor\n", compressorstr);
218 
219  return ret;
220 }
221 
222 static int decompress_chunks_thread(AVCodecContext *avctx, void *arg,
223  int chunk_nb, int thread_nb)
224 {
225  HapContext *ctx = avctx->priv_data;
226 
227  HapChunk *chunk = &ctx->chunks[chunk_nb];
228  GetByteContext gbc;
229  uint8_t *dst = ctx->tex_buf + chunk->uncompressed_offset;
230 
231  bytestream2_init(&gbc, ctx->gbc.buffer + chunk->compressed_offset, chunk->compressed_size);
232 
233  if (chunk->compressor == HAP_COMP_SNAPPY) {
234  int ret;
235  int64_t uncompressed_size = ctx->tex_size;
236 
237  /* Uncompress the frame */
238  ret = ff_snappy_uncompress(&gbc, dst, &uncompressed_size);
239  if (ret < 0) {
240  av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n");
241  return ret;
242  }
243  } else if (chunk->compressor == HAP_COMP_NONE) {
244  bytestream2_get_buffer(&gbc, dst, chunk->compressed_size);
245  }
246 
247  return 0;
248 }
249 
251  int *got_frame, AVPacket *avpkt)
252 {
253  HapContext *ctx = avctx->priv_data;
254  int ret, i, t;
255  int section_size;
256  enum HapSectionType section_type;
257  int start_texture_section = 0;
258 
259  bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
260 
261  /* check for multi texture header */
262  if (ctx->texture_count == 2) {
263  ret = ff_hap_parse_section_header(&ctx->gbc, &section_size, &section_type);
264  if (ret != 0)
265  return ret;
266  if ((section_type & 0x0F) != 0x0D) {
267  av_log(avctx, AV_LOG_ERROR, "Invalid section type in 2 textures mode %#04x.\n", section_type);
268  return AVERROR_INVALIDDATA;
269  }
270  start_texture_section = 4;
271  }
272 
273  /* Get the output frame ready to receive data */
274  ret = ff_thread_get_buffer(avctx, frame, 0);
275  if (ret < 0)
276  return ret;
277 
278  for (t = 0; t < ctx->texture_count; t++) {
279  bytestream2_seek(&ctx->gbc, start_texture_section, SEEK_SET);
280 
281  /* Check for section header */
282  ret = hap_parse_frame_header(avctx);
283  if (ret < 0)
284  return ret;
285 
286  if (ctx->tex_size != (avctx->coded_width / TEXTURE_BLOCK_W)
287  *(avctx->coded_height / TEXTURE_BLOCK_H)
288  *ctx->dec[t].tex_ratio) {
289  av_log(avctx, AV_LOG_ERROR, "uncompressed size mismatches\n");
290  return AVERROR_INVALIDDATA;
291  }
292 
293  start_texture_section += ctx->texture_section_size + 4;
294 
295  /* Unpack the DXT texture */
297  int tex_size;
298  /* Only DXTC texture compression in a contiguous block */
299  ctx->dec[t].tex_data.in = ctx->gbc.buffer;
300  tex_size = FFMIN(ctx->texture_section_size, bytestream2_get_bytes_left(&ctx->gbc));
301  if (tex_size < (avctx->coded_width / TEXTURE_BLOCK_W)
302  *(avctx->coded_height / TEXTURE_BLOCK_H)
303  *ctx->dec[t].tex_ratio) {
304  av_log(avctx, AV_LOG_ERROR, "Insufficient data\n");
305  return AVERROR_INVALIDDATA;
306  }
307  } else {
308  /* Perform the second-stage decompression */
309  ret = av_reallocp(&ctx->tex_buf, ctx->tex_size);
310  if (ret < 0)
311  return ret;
312 
313  avctx->execute2(avctx, decompress_chunks_thread, NULL,
314  ctx->chunk_results, ctx->chunk_count);
315 
316  for (i = 0; i < ctx->chunk_count; i++) {
317  if (ctx->chunk_results[i] < 0)
318  return ctx->chunk_results[i];
319  }
320 
321  ctx->dec[t].tex_data.in = ctx->tex_buf;
322  }
323 
324  ctx->dec[t].frame_data.out = frame->data[0];
325  ctx->dec[t].stride = frame->linesize[0];
326  avctx->execute2(avctx, ff_texturedsp_decompress_thread, &ctx->dec[t], NULL, ctx->dec[t].slice_count);
327  }
328 
329  /* Frame is ready to be output */
330  frame->pict_type = AV_PICTURE_TYPE_I;
331  frame->key_frame = 1;
332  *got_frame = 1;
333 
334  return avpkt->size;
335 }
336 
337 static av_cold int hap_init(AVCodecContext *avctx)
338 {
339  HapContext *ctx = avctx->priv_data;
340  const char *texture_name;
341  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
342 
343  if (ret < 0) {
344  av_log(avctx, AV_LOG_ERROR, "Invalid video size %dx%d.\n",
345  avctx->width, avctx->height);
346  return ret;
347  }
348 
349  /* Since codec is based on 4x4 blocks, size is aligned to 4 */
350  avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W);
351  avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
352 
353  ff_texturedsp_init(&ctx->dxtc);
354 
355  ctx->texture_count = 1;
356  ctx->dec[0].raw_ratio = 16;
357  ctx->dec[0].slice_count = av_clip(avctx->thread_count, 1,
358  avctx->coded_height / TEXTURE_BLOCK_H);
359 
360  switch (avctx->codec_tag) {
361  case MKTAG('H','a','p','1'):
362  texture_name = "DXT1";
363  ctx->dec[0].tex_ratio = 8;
364  ctx->dec[0].tex_funct = ctx->dxtc.dxt1_block;
365  avctx->pix_fmt = AV_PIX_FMT_RGB0;
366  break;
367  case MKTAG('H','a','p','5'):
368  texture_name = "DXT5";
369  ctx->dec[0].tex_ratio = 16;
370  ctx->dec[0].tex_funct = ctx->dxtc.dxt5_block;
371  avctx->pix_fmt = AV_PIX_FMT_RGBA;
372  break;
373  case MKTAG('H','a','p','Y'):
374  texture_name = "DXT5-YCoCg-scaled";
375  ctx->dec[0].tex_ratio = 16;
376  ctx->dec[0].tex_funct = ctx->dxtc.dxt5ys_block;
377  avctx->pix_fmt = AV_PIX_FMT_RGB0;
378  break;
379  case MKTAG('H','a','p','A'):
380  texture_name = "RGTC1";
381  ctx->dec[0].tex_ratio = 8;
382  ctx->dec[0].tex_funct = ctx->dxtc.rgtc1u_gray_block;
383  ctx->dec[0].raw_ratio = 4;
384  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
385  break;
386  case MKTAG('H','a','p','M'):
387  texture_name = "DXT5-YCoCg-scaled / RGTC1";
388  ctx->dec[0].tex_ratio = 16;
389  ctx->dec[1].tex_ratio = 8;
390  ctx->dec[0].tex_funct = ctx->dxtc.dxt5ys_block;
391  ctx->dec[1].tex_funct = ctx->dxtc.rgtc1u_alpha_block;
392  ctx->dec[1].raw_ratio = 16;
393  ctx->dec[1].slice_count = ctx->dec[0].slice_count;
394  avctx->pix_fmt = AV_PIX_FMT_RGBA;
395  ctx->texture_count = 2;
396  break;
397  default:
399  }
400 
401  av_log(avctx, AV_LOG_DEBUG, "%s texture\n", texture_name);
402 
403  return 0;
404 }
405 
406 static av_cold int hap_close(AVCodecContext *avctx)
407 {
408  HapContext *ctx = avctx->priv_data;
409 
411 
412  return 0;
413 }
414 
416  .p.name = "hap",
417  .p.long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"),
418  .p.type = AVMEDIA_TYPE_VIDEO,
419  .p.id = AV_CODEC_ID_HAP,
420  .init = hap_init,
422  .close = hap_close,
423  .priv_data_size = sizeof(HapContext),
426  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
428  .codec_tags = (const uint32_t []){
429  MKTAG('H','a','p','1'),
430  MKTAG('H','a','p','5'),
431  MKTAG('H','a','p','Y'),
432  MKTAG('H','a','p','A'),
433  MKTAG('H','a','p','M'),
435  },
436 };
HAP_FMT_YCOCGDXT5
@ HAP_FMT_YCOCGDXT5
Definition: hap.h:36
av_clip
#define av_clip
Definition: common.h:95
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:39
TEXTURE_BLOCK_H
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:45
GetByteContext
Definition: bytestream.h:33
HapChunk::compressed_size
size_t compressed_size
Definition: hap.h:56
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:325
AVPacket::data
uint8_t * data
Definition: packet.h:374
ff_hap_parse_section_header
int ff_hap_parse_section_header(GetByteContext *gbc, int *section_size, enum HapSectionType *section_type)
Definition: hap.c:57
FFCodec
Definition: codec_internal.h:112
ff_texturedsp_decompress_thread
int ff_texturedsp_decompress_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb)
thread.h
HapContext
Definition: hap.h:61
texturedsp.h
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
hap_parse_decode_instructions
static int hap_parse_decode_instructions(HapContext *ctx, int size)
Definition: hapdec.c:46
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1463
hap.h
ff_thread_get_buffer
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames. The frames must then be freed with ff_thread_release_buffer(). Otherwise decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
hap_decode
static int hap_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: hapdec.c:250
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:577
HAP_FMT_RGBADXT5
@ HAP_FMT_RGBADXT5
Definition: hap.h:35
HAP_COMP_SNAPPY
@ HAP_COMP_SNAPPY
Definition: hap.h:42
FF_CODEC_TAGS_END
#define FF_CODEC_TAGS_END
FFCodec.codec_tags termination value.
Definition: codec_internal.h:80
HAP_FMT_RGTC1
@ HAP_FMT_RGTC1
Definition: hap.h:37
hap_close
static av_cold int hap_close(AVCodecContext *avctx)
Definition: hapdec.c:406
HAP_COMP_NONE
@ HAP_COMP_NONE
Definition: hap.h:41
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:254
ff_hap_free_context
av_cold void ff_hap_free_context(HapContext *ctx)
Definition: hap.c:50
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
HAP_ST_SIZE_TABLE
@ HAP_ST_SIZE_TABLE
Definition: hap.h:49
hap_init
static av_cold int hap_init(AVCodecContext *avctx)
Definition: hapdec.c:337
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_texturedsp_init
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:637
snappy.h
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
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:113
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:222
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
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:47
HAP_COMP_COMPLEX
@ HAP_COMP_COMPLEX
Definition: hap.h:43
ff_hap_set_chunk_count
int ff_hap_set_chunk_count(HapContext *ctx, int count, int first_in_frame)
Definition: hap.c:28
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
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:58
ff_hap_decoder
const FFCodec ff_hap_decoder
Definition: hapdec.c:415
HapSectionType
HapSectionType
Definition: hap.h:46
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:375
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
codec_internal.h
HapChunk::compressor
enum HapCompressor compressor
Definition: hap.h:54
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:186
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:117
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:228
HAP_ST_COMPRESSOR_TABLE
@ HAP_ST_COMPRESSOR_TABLE
Definition: hap.h:48
HapChunk
Definition: hap.h:53
HapChunk::uncompressed_offset
int uncompressed_offset
Definition: hap.h:57
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FF_CODEC_CAP_INIT_THREADSAFE
#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: codec_internal.h:31
TEXTURE_BLOCK_W
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:44
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
AVCodecContext::height
int height
Definition: avcodec.h:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
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:389
AV_CODEC_ID_HAP
@ AV_CODEC_ID_HAP
Definition: codec_id.h:239
HAP_ST_OFFSET_TABLE
@ HAP_ST_OFFSET_TABLE
Definition: hap.h:50
HAP_FMT_RGBDXT1
@ HAP_FMT_RGBDXT1
Definition: hap.h:34
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:577
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
hap_can_use_tex_in_place
static int hap_can_use_tex_in_place(HapContext *ctx)
Definition: hapdec.c:117
AVCodecContext::codec_tag
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:414
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
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:55
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
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:1533
hap_parse_frame_header
static int hap_parse_frame_header(AVCodecContext *avctx)
Definition: hapdec.c:130