mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 21:40:34 +00:00
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>
This commit is contained in:
parent
08be65a075
commit
bd6fa80d56
@ -65,6 +65,7 @@ typedef struct HapContext {
|
|||||||
|
|
||||||
enum HapTextureFormat opt_tex_fmt; /* Texture type (encoder only) */
|
enum HapTextureFormat opt_tex_fmt; /* Texture type (encoder only) */
|
||||||
int opt_chunk_count; /* User-requested chunk count (encoder only) */
|
int opt_chunk_count; /* User-requested chunk count (encoder only) */
|
||||||
|
int opt_compressor; /* User-requested compressor (encoder only) */
|
||||||
|
|
||||||
int chunk_count;
|
int chunk_count;
|
||||||
HapChunk *chunks;
|
HapChunk *chunks;
|
||||||
|
@ -204,15 +204,25 @@ static int hap_encode(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* DXTC compression. */
|
if (ctx->opt_compressor == HAP_COMP_NONE) {
|
||||||
ret = compress_texture(avctx, ctx->tex_buf, ctx->tex_size, frame);
|
/* DXTC compression directly to the packet buffer. */
|
||||||
if (ret < 0)
|
ret = compress_texture(avctx, pkt->data + header_length, pkt->size - header_length, frame);
|
||||||
return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Compress (using Snappy) the frame */
|
ctx->chunks[0].compressor = HAP_COMP_NONE;
|
||||||
final_data_size = hap_compress_frame(avctx, pkt->data + header_length);
|
final_data_size = ctx->tex_size;
|
||||||
if (final_data_size < 0)
|
} else {
|
||||||
return final_data_size;
|
/* 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. */
|
/* Write header at the start. */
|
||||||
hap_write_frame_header(ctx, pkt->data, final_data_size + header_length);
|
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) *
|
ctx->tex_size = FFALIGN(avctx->width, TEXTURE_BLOCK_W) *
|
||||||
FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;
|
FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;
|
||||||
|
|
||||||
/* Round the chunk count to divide evenly on DXT block edges */
|
switch (ctx->opt_compressor) {
|
||||||
corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, HAP_MAX_CHUNKS);
|
case HAP_COMP_NONE:
|
||||||
while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {
|
/* No benefit chunking uncompressed data */
|
||||||
corrected_chunk_count--;
|
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) {
|
if (corrected_chunk_count != ctx->opt_chunk_count) {
|
||||||
av_log(avctx, AV_LOG_INFO, "%d chunks requested but %d used.\n",
|
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)
|
if (ret != 0)
|
||||||
return ret;
|
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;
|
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_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" },
|
{ "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, },
|
{ "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 },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user