FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hapenc.c
Go to the documentation of this file.
1 /*
2  * Vidvox Hap encoder
3  * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
4  * Copyright (C) 2015 Tom Butterworth <bangnoise@gmail.com>
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 /**
24  * @file
25  * Hap encoder
26  *
27  * Fourcc: Hap1, Hap5, HapY
28  *
29  * https://github.com/Vidvox/hap/blob/master/documentation/HapVideoDRAFT.md
30  */
31 
32 #include <stdint.h>
33 #include "snappy-c.h"
34 
35 #include "libavutil/frame.h"
36 #include "libavutil/imgutils.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/opt.h"
39 
40 #include "avcodec.h"
41 #include "bytestream.h"
42 #include "hap.h"
43 #include "internal.h"
44 #include "texturedsp.h"
45 
46 #define HAP_MAX_CHUNKS 64
47 
49  /* Short header: four bytes with a 24 bit size value */
51  /* Long header: eight bytes with a 32 bit size value */
53 };
54 
55 static void compress_texture(AVCodecContext *avctx, const AVFrame *f)
56 {
57  HapContext *ctx = avctx->priv_data;
58  uint8_t *out = ctx->tex_buf;
59  int i, j;
60 
61  for (j = 0; j < avctx->height; j += 4) {
62  for (i = 0; i < avctx->width; i += 4) {
63  uint8_t *p = f->data[0] + i * 4 + j * f->linesize[0];
64  const int step = ctx->tex_fun(out, f->linesize[0], p);
65  out += step;
66  }
67  }
68 }
69 
70 /* section_length does not include the header */
72  enum HapHeaderLength header_length,
73  int section_length,
74  enum HapSectionType section_type)
75 {
76  /* The first three bytes are the length of the section (not including the
77  * header) or zero if using an eight-byte header.
78  * For an eight-byte header, the length is in the last four bytes.
79  * The fourth byte stores the section type. */
80  bytestream2_put_le24(pbc, header_length == HAP_HDR_LONG ? 0 : section_length);
81  bytestream2_put_byte(pbc, section_type);
82 
83  if (header_length == HAP_HDR_LONG) {
84  bytestream2_put_le32(pbc, section_length);
85  }
86 }
87 
88 static int hap_compress_frame(AVCodecContext *avctx, uint8_t *dst)
89 {
90  HapContext *ctx = avctx->priv_data;
91  int i, final_size = 0;
92 
93  for (i = 0; i < ctx->chunk_count; i++) {
94  HapChunk *chunk = &ctx->chunks[i];
95  uint8_t *chunk_src, *chunk_dst;
96  int ret;
97 
98  if (i == 0) {
99  chunk->compressed_offset = 0;
100  } else {
101  chunk->compressed_offset = ctx->chunks[i-1].compressed_offset
102  + ctx->chunks[i-1].compressed_size;
103  }
104  chunk->uncompressed_size = ctx->tex_size / ctx->chunk_count;
105  chunk->uncompressed_offset = i * chunk->uncompressed_size;
106  chunk->compressed_size = ctx->max_snappy;
107  chunk_src = ctx->tex_buf + chunk->uncompressed_offset;
108  chunk_dst = dst + chunk->compressed_offset;
109 
110  /* Compress with snappy too, write directly on packet buffer. */
111  ret = snappy_compress(chunk_src, chunk->uncompressed_size,
112  chunk_dst, &chunk->compressed_size);
113  if (ret != SNAPPY_OK) {
114  av_log(avctx, AV_LOG_ERROR, "Snappy compress error.\n");
115  return AVERROR_BUG;
116  }
117 
118  /* If there is no gain from snappy, just use the raw texture. */
119  if (chunk->compressed_size >= chunk->uncompressed_size) {
120  av_log(avctx, AV_LOG_VERBOSE,
121  "Snappy buffer bigger than uncompressed (%lu >= %lu bytes).\n",
122  chunk->compressed_size, chunk->uncompressed_size);
123  memcpy(chunk_dst, chunk_src, chunk->uncompressed_size);
124  chunk->compressor = HAP_COMP_NONE;
125  chunk->compressed_size = chunk->uncompressed_size;
126  } else {
127  chunk->compressor = HAP_COMP_SNAPPY;
128  }
129 
130  final_size += chunk->compressed_size;
131  }
132 
133  return final_size;
134 }
135 
137 {
138  /* Second-Stage Compressor Table (one byte per entry)
139  * + Chunk Size Table (four bytes per entry)
140  * + headers for both sections (short versions)
141  * = chunk_count + (4 * chunk_count) + 4 + 4 */
142  return (5 * ctx->chunk_count) + 8;
143 }
144 
146 {
147  /* Top section header (long version) */
148  int length = HAP_HDR_LONG;
149 
150  if (ctx->chunk_count > 1) {
151  /* Decode Instructions header (short) + Decode Instructions Container */
153  }
154 
155  return length;
156 }
157 
158 static void hap_write_frame_header(HapContext *ctx, uint8_t *dst, int frame_length)
159 {
160  PutByteContext pbc;
161  int i;
162 
163  bytestream2_init_writer(&pbc, dst, frame_length);
164  if (ctx->chunk_count == 1) {
165  /* Write a simple header */
166  hap_write_section_header(&pbc, HAP_HDR_LONG, frame_length - 8,
167  ctx->chunks[0].compressor | ctx->opt_tex_fmt);
168  } else {
169  /* Write a complex header with Decode Instructions Container */
170  hap_write_section_header(&pbc, HAP_HDR_LONG, frame_length - 8,
176 
177  for (i = 0; i < ctx->chunk_count; i++) {
178  bytestream2_put_byte(&pbc, ctx->chunks[i].compressor >> 4);
179  }
180 
183 
184  for (i = 0; i < ctx->chunk_count; i++) {
185  bytestream2_put_le32(&pbc, ctx->chunks[i].compressed_size);
186  }
187  }
188 }
189 
190 static int hap_encode(AVCodecContext *avctx, AVPacket *pkt,
191  const AVFrame *frame, int *got_packet)
192 {
193  HapContext *ctx = avctx->priv_data;
194  int header_length = hap_header_length(ctx);
195  int final_data_size, ret;
196  int pktsize = FFMAX(ctx->tex_size, ctx->max_snappy * ctx->chunk_count) + header_length;
197 
198  /* Allocate maximum size packet, shrink later. */
199  ret = ff_alloc_packet2(avctx, pkt, pktsize, header_length);
200  if (ret < 0)
201  return ret;
202 
203  /* DXTC compression. */
204  compress_texture(avctx, frame);
205 
206  /* Compress (using Snappy) the frame */
207  final_data_size = hap_compress_frame(avctx, pkt->data + header_length);
208  if (final_data_size < 0)
209  return final_data_size;
210 
211  /* Write header at the start. */
212  hap_write_frame_header(ctx, pkt->data, final_data_size + header_length);
213 
214  av_shrink_packet(pkt, final_data_size + header_length);
215  pkt->flags |= AV_PKT_FLAG_KEY;
216  *got_packet = 1;
217  return 0;
218 }
219 
220 static av_cold int hap_init(AVCodecContext *avctx)
221 {
222  HapContext *ctx = avctx->priv_data;
223  int ratio;
224  int corrected_chunk_count;
225  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
226 
227  if (ret < 0) {
228  av_log(avctx, AV_LOG_ERROR, "Invalid video size %dx%d.\n",
229  avctx->width, avctx->height);
230  return ret;
231  }
232 
233  if (avctx->width % 4 || avctx->height % 4) {
234  av_log(avctx, AV_LOG_ERROR, "Video size %dx%d is not multiple of 4.\n",
235  avctx->width, avctx->height);
236  return AVERROR_INVALIDDATA;
237  }
238 
240 
241  switch (ctx->opt_tex_fmt) {
242  case HAP_FMT_RGBDXT1:
243  ratio = 8;
244  avctx->codec_tag = MKTAG('H', 'a', 'p', '1');
245  ctx->tex_fun = ctx->dxtc.dxt1_block;
246  break;
247  case HAP_FMT_RGBADXT5:
248  ratio = 4;
249  avctx->codec_tag = MKTAG('H', 'a', 'p', '5');
250  ctx->tex_fun = ctx->dxtc.dxt5_block;
251  break;
252  case HAP_FMT_YCOCGDXT5:
253  ratio = 4;
254  avctx->codec_tag = MKTAG('H', 'a', 'p', 'Y');
255  ctx->tex_fun = ctx->dxtc.dxt5ys_block;
256  break;
257  default:
258  av_log(avctx, AV_LOG_ERROR, "Invalid format %02X\n", ctx->opt_tex_fmt);
259  return AVERROR_INVALIDDATA;
260  }
261 
262  /* Texture compression ratio is constant, so can we computer
263  * beforehand the final size of the uncompressed buffer. */
264  ctx->tex_size = FFALIGN(avctx->width, TEXTURE_BLOCK_W) *
265  FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;
266 
267  /* Round the chunk count to divide evenly on DXT block edges */
268  corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, HAP_MAX_CHUNKS);
269  while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {
270  corrected_chunk_count--;
271  }
272  if (corrected_chunk_count != ctx->opt_chunk_count) {
273  av_log(avctx, AV_LOG_INFO, "%d chunks requested but %d used.\n",
274  ctx->opt_chunk_count, corrected_chunk_count);
275  }
276  ret = ff_hap_set_chunk_count(ctx, corrected_chunk_count, 1);
277  if (ret != 0)
278  return ret;
279 
280  ctx->max_snappy = snappy_max_compressed_length(ctx->tex_size / corrected_chunk_count);
281 
282  ctx->tex_buf = av_malloc(ctx->tex_size);
283  if (!ctx->tex_buf)
284  return AVERROR(ENOMEM);
285 
286  return 0;
287 }
288 
289 static av_cold int hap_close(AVCodecContext *avctx)
290 {
291  HapContext *ctx = avctx->priv_data;
292 
293  ff_hap_free_context(ctx);
294 
295  return 0;
296 }
297 
298 #define OFFSET(x) offsetof(HapContext, x)
299 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
300 static const AVOption options[] = {
301  { "format", NULL, OFFSET(opt_tex_fmt), AV_OPT_TYPE_INT, { .i64 = HAP_FMT_RGBDXT1 }, HAP_FMT_RGBDXT1, HAP_FMT_YCOCGDXT5, FLAGS, "format" },
302  { "hap", "Hap 1 (DXT1 textures)", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_FMT_RGBDXT1 }, 0, 0, FLAGS, "format" },
303  { "hap_alpha", "Hap Alpha (DXT5 textures)", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_FMT_RGBADXT5 }, 0, 0, FLAGS, "format" },
304  { "hap_q", "Hap Q (DXT5-YCoCg textures)", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_FMT_YCOCGDXT5 }, 0, 0, FLAGS, "format" },
305  { "chunks", "chunk count", OFFSET(opt_chunk_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, HAP_MAX_CHUNKS, FLAGS, },
306  { NULL },
307 };
308 
309 static const AVClass hapenc_class = {
310  .class_name = "Hap encoder",
311  .item_name = av_default_item_name,
312  .option = options,
313  .version = LIBAVUTIL_VERSION_INT,
314 };
315 
317  .name = "hap",
318  .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap encoder"),
319  .type = AVMEDIA_TYPE_VIDEO,
320  .id = AV_CODEC_ID_HAP,
321  .priv_data_size = sizeof(HapContext),
322  .priv_class = &hapenc_class,
323  .init = hap_init,
324  .encode2 = hap_encode,
325  .close = hap_close,
326  .pix_fmts = (const enum AVPixelFormat[]) {
328  },
329  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
331 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
Definition: hap.h:60
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define HAP_MAX_CHUNKS
Definition: hapenc.c:46
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
HapChunk * chunks
Definition: hap.h:70
AVOption.
Definition: opt.h:255
HapSectionType
Definition: hap.h:45
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
misc image utilities
#define LIBAVUTIL_VERSION_INT
Definition: version.h:62
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: avpacket.c:103
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int(* tex_fun)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: hap.h:83
Texture block (4x4) module.
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
static av_cold int hap_init(AVCodecContext *avctx)
Definition: hapenc.c:220
static AVPacket pkt
size_t compressed_size
Definition: hap.h:55
int compressed_offset
Definition: hap.h:54
AVCodec.
Definition: avcodec.h:3472
#define FFALIGN(x, a)
Definition: common.h:86
size_t uncompressed_size
Definition: hap.h:57
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
uint8_t
#define av_cold
Definition: attributes.h:74
#define av_malloc(s)
HapHeaderLength
Definition: hapenc.c:48
static void hap_write_section_header(PutByteContext *pbc, enum HapHeaderLength header_length, int section_length, enum HapSectionType section_type)
Definition: hapenc.c:71
AVOptions.
static const AVClass hapenc_class
Definition: hapenc.c:309
int ff_hap_set_chunk_count(HapContext *ctx, int count, int first_in_frame)
Definition: hap.c:28
static AVFrame * frame
#define TEXTURE_BLOCK_H
Definition: texturedsp.h:43
TextureDSPContext dxtc
Definition: hap.h:63
uint8_t * data
Definition: avcodec.h:1423
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1469
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
GLsizei GLsizei * length
Definition: opengl_enc.c:115
const char * name
Name of the codec implementation.
Definition: avcodec.h:3479
static av_cold int hap_close(AVCodecContext *avctx)
Definition: hapenc.c:289
int(* dxt5_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:51
int opt_chunk_count
Definition: hap.h:67
#define FFMAX(a, b)
Definition: common.h:79
Libavcodec external API header.
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:95
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1429
reference-counted frame API
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:241
#define FLAGS
Definition: hapenc.c:299
int uncompressed_offset
Definition: hap.h:56
static void hap_write_frame_header(HapContext *ctx, uint8_t *dst, int frame_length)
Definition: hapenc.c:158
int width
picture width / height.
Definition: avcodec.h:1681
static const AVOption options[]
Definition: hapenc.c:300
size_t max_snappy
Definition: hap.h:78
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
av_cold void ff_hap_free_context(HapContext *ctx)
Definition: hap.c:50
main external API structure.
Definition: avcodec.h:1502
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1534
int chunk_count
Definition: hap.h:69
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
AVCodec ff_hap_encoder
Definition: hapenc.c:316
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: utils.c:1782
enum HapTextureFormat opt_tex_fmt
Definition: hap.h:66
void ff_texturedspenc_init(TextureDSPContext *c)
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:209
uint8_t * tex_buf
Definition: hap.h:75
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
static int hap_encode(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: hapenc.c:190
common internal api header.
#define OFFSET(x)
Definition: hapenc.c:298
size_t tex_size
Definition: hap.h:76
Definition: hap.h:52
static int hap_decode_instructions_length(HapContext *ctx)
Definition: hapenc.c:136
static void compress_texture(AVCodecContext *avctx, const AVFrame *f)
Definition: hapenc.c:55
void * priv_data
Definition: avcodec.h:1544
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
static int hap_compress_frame(AVCodecContext *avctx, uint8_t *dst)
Definition: hapenc.c:88
enum HapCompressor compressor
Definition: hap.h:53
#define MKTAG(a, b, c, d)
Definition: common.h:330
#define TEXTURE_BLOCK_W
Definition: texturedsp.h:42
AVPixelFormat
Pixel format.
Definition: pixfmt.h:61
This structure stores compressed data.
Definition: avcodec.h:1400
int(* dxt5ys_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:53
static int hap_header_length(HapContext *ctx)
Definition: hapenc.c:145