[FFmpeg-devel] [PATCH 2/2] avcodec/hap: add "compressor" option to Hap encoder to disable secondary compression
Tom Butterworth
bangnoise at gmail.com
Tue Nov 8 02:21:53 EET 2016
The secondary compression in Hap is optional, this change exposes that option to
the user as some use-cases favour higher bitrate files to reduce workload
decoding.
Adds "none" or "snappy" as options for "compressor". Selecting "none" disregards
"chunks" option: chunking is only of benefit decompressing Snappy.
---
libavcodec/hap.h | 1 +
libavcodec/hapenc.c | 57 +++++++++++++++++++++++++++++++++++++----------------
2 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/libavcodec/hap.h b/libavcodec/hap.h
index e4762ee..f39e621 100644
--- a/libavcodec/hap.h
+++ b/libavcodec/hap.h
@@ -65,6 +65,7 @@ typedef struct HapContext {
enum HapTextureFormat opt_tex_fmt; /* Texture type (encoder only) */
int opt_chunk_count; /* User-requested chunk count (encoder only) */
+ int opt_compressor; /* User-requested compressor (encoder only) */
int chunk_count;
HapChunk *chunks;
diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c
index 7056b62..d44ef92 100644
--- a/libavcodec/hapenc.c
+++ b/libavcodec/hapenc.c
@@ -199,13 +199,19 @@ static int hap_encode(AVCodecContext *avctx, AVPacket *pkt,
if (ret < 0)
return ret;
- /* DXTC compression. */
- compress_texture(avctx, ctx->tex_buf, frame);
-
- /* Compress (using Snappy) the frame */
- final_data_size = hap_compress_frame(avctx, pkt->data + header_length);
- if (final_data_size < 0)
- return final_data_size;
+ if (ctx->opt_compressor == HAP_COMP_NONE) {
+ /* DXTC compression directly to the packet buffer. */
+ compress_texture(avctx, pkt->data + header_length, frame);
+ ctx->chunks[0].compressor = HAP_COMP_NONE;
+ final_data_size = ctx->tex_size;
+ } else {
+ /* DXTC compression. */
+ compress_texture(avctx, ctx->tex_buf, frame);
+ /* Compress (using Snappy) the frame */
+ final_data_size = hap_compress_frame(avctx, pkt->data + header_length);
+ if (final_data_size < 0)
+ return final_data_size;
+ }
/* Write header at the start. */
hap_write_frame_header(ctx, pkt->data, final_data_size + header_length);
@@ -266,10 +272,30 @@ static av_cold int hap_init(AVCodecContext *avctx)
ctx->tex_size = FFALIGN(avctx->width, TEXTURE_BLOCK_W) *
FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;
- /* Round the chunk count to divide evenly on DXT block edges */
- corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, HAP_MAX_CHUNKS);
- while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {
- corrected_chunk_count--;
+ switch (ctx->opt_compressor) {
+ case HAP_COMP_NONE:
+ /* No benefit chunking uncompressed data */
+ corrected_chunk_count = 1;
+
+ ctx->max_snappy = ctx->tex_size;
+ ctx->tex_buf = NULL;
+ break;
+ case HAP_COMP_SNAPPY:
+ /* Round the chunk count to divide evenly on DXT block edges */
+ corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, HAP_MAX_CHUNKS);
+ while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {
+ corrected_chunk_count--;
+ }
+
+ ctx->max_snappy = snappy_max_compressed_length(ctx->tex_size / corrected_chunk_count);
+ ctx->tex_buf = av_malloc(ctx->tex_size);
+ if (!ctx->tex_buf) {
+ return AVERROR(ENOMEM);
+ }
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid compresor %02X\n", ctx->opt_compressor);
+ return AVERROR_INVALIDDATA;
}
if (corrected_chunk_count != ctx->opt_chunk_count) {
av_log(avctx, AV_LOG_INFO, "%d chunks requested but %d used.\n",
@@ -279,12 +305,6 @@ static av_cold int hap_init(AVCodecContext *avctx)
if (ret != 0)
return ret;
- ctx->max_snappy = snappy_max_compressed_length(ctx->tex_size / corrected_chunk_count);
-
- ctx->tex_buf = av_malloc(ctx->tex_size);
- if (!ctx->tex_buf)
- return AVERROR(ENOMEM);
-
return 0;
}
@@ -305,6 +325,9 @@ static const AVOption options[] = {
{ "hap_alpha", "Hap Alpha (DXT5 textures)", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_FMT_RGBADXT5 }, 0, 0, FLAGS, "format" },
{ "hap_q", "Hap Q (DXT5-YCoCg textures)", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_FMT_YCOCGDXT5 }, 0, 0, FLAGS, "format" },
{ "chunks", "chunk count", OFFSET(opt_chunk_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, HAP_MAX_CHUNKS, FLAGS, },
+ { "compressor", "second-stage compressor", OFFSET(opt_compressor), AV_OPT_TYPE_INT, { .i64 = HAP_COMP_SNAPPY }, HAP_COMP_NONE, HAP_COMP_SNAPPY, FLAGS, "compressor" },
+ { "none", "None", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_COMP_NONE }, 0, 0, FLAGS, "compressor" },
+ { "snappy", "Snappy", 0, AV_OPT_TYPE_CONST, { .i64 = HAP_COMP_SNAPPY }, 0, 0, FLAGS, "compressor" },
{ NULL },
};
--
2.9.3 (Apple Git-75)
More information about the ffmpeg-devel
mailing list