diff options
author | Tom Butterworth <bangnoise@gmail.com> | 2016-11-07 23:58:48 +0000 |
---|---|---|
committer | Tom Butterworth <bangnoise@gmail.com> | 2016-11-10 14:27:38 +0000 |
commit | bd6fa80d56fcda385da1c8f21eb83282a7930899 (patch) | |
tree | 7223761a5514ea3606c2eed012601f6810d061e6 /libavcodec | |
parent | 08be65a07557686bd2f0a8b318145802d419e79b (diff) | |
download | ffmpeg-bd6fa80d56fcda385da1c8f21eb83282a7930899.tar.gz |
avcodec/hap: add "compressor" option to Hap encoder to disable secondary compression
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.
Reviewed-by: Martin Vignali <martin.vignali@gmail.com>
Signed-off-by: Tom Butterworth <bangnoise@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/hap.h | 1 | ||||
-rw-r--r-- | libavcodec/hapenc.c | 65 |
2 files changed, 47 insertions, 19 deletions
diff --git a/libavcodec/hap.h b/libavcodec/hap.h index e4762ee438..f39e621805 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 79b6074844..3a1bc870b1 100644 --- a/libavcodec/hapenc.c +++ b/libavcodec/hapenc.c @@ -204,15 +204,25 @@ static int hap_encode(AVCodecContext *avctx, AVPacket *pkt, if (ret < 0) return ret; - /* DXTC compression. */ - ret = compress_texture(avctx, ctx->tex_buf, ctx->tex_size, frame); - if (ret < 0) - return ret; - - /* 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. */ + ret = compress_texture(avctx, pkt->data + header_length, pkt->size - header_length, frame); + if (ret < 0) + return ret; + + ctx->chunks[0].compressor = HAP_COMP_NONE; + final_data_size = ctx->tex_size; + } else { + /* DXTC compression. */ + ret = compress_texture(avctx, ctx->tex_buf, ctx->tex_size, frame); + if (ret < 0) + return ret; + + /* 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); @@ -273,10 +283,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", @@ -286,12 +316,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; } @@ -312,6 +336,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 }, }; |