diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fab554cd7a63b3fd30cf2d50a124d559071fecc5..695f5349d7af75cc66ccb795b0557c71772a148f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2341,12 +2341,11 @@ typedef struct AVCodecContext { int coder_type; #endif /* FF_API_CODER_TYPE */ - /** - * context model - * - encoding: Set by user. - * - decoding: unused - */ +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated int context_model; +#endif #if FF_API_MPV_OPT /** diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index b44253e94c4424ec1e167c9e9d90899e02984925..34370fa143b7e778e7c34b8d2968763bae389da3 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -103,6 +103,7 @@ typedef struct FFV1Context { int ec; int slice_damaged; int key_frame_ok; + int context_model; int bits_per_raw_sample; int packed_at_lsb; diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 061e90829f0577ad0a94756672d2162ade04ccce..9c2e463e6c5ca8e69018a3b54484d1541d461453 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -261,7 +261,7 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index) { int x, y, i; - const int ring_size = s->avctx->context_model ? 3 : 2; + const int ring_size = s->context_model ? 3 : 2; int16_t *sample[3]; s->run_index = 0; @@ -297,7 +297,7 @@ static void encode_rgb_frame(FFV1Context *s, const uint8_t *src[3], int w, int h, const int stride[3]) { int x, y, p, i; - const int ring_size = s->avctx->context_model ? 3 : 2; + const int ring_size = s->context_model ? 3 : 2; int16_t *sample[MAX_PLANES][3]; int lbd = s->avctx->bits_per_raw_sample <= 8; int bits = s->avctx->bits_per_raw_sample > 0 @@ -418,7 +418,7 @@ static void write_header(FFV1Context *f) 0); for (j = 0; j < f->plane_count; j++) { put_symbol(c, state, f->plane[j].quant_table_index, 0); - av_assert0(f->plane[j].quant_table_index == f->avctx->context_model); + av_assert0(f->plane[j].quant_table_index == f->context_model); } } } @@ -671,12 +671,18 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx, AV_LOG_WARNING, "Storing alpha plane, this will require a recent FFV1 decoder to playback!\n"); } +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->context_model) + s->context_model = avctx->context_model; if (avctx->context_model > 1U) { av_log(avctx, AV_LOG_ERROR, "Invalid context model %d, valid values are 0 and 1\n", avctx->context_model); return AVERROR(EINVAL); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (s->ac == AC_RANGE_CUSTOM_TAB) for (i = 1; i < 256; i++) @@ -706,14 +712,14 @@ FF_ENABLE_DEPRECATION_WARNINGS } s->context_count[0] = (11 * 11 * 11 + 1) / 2; s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 1) / 2; - memcpy(s->quant_table, s->quant_tables[avctx->context_model], + memcpy(s->quant_table, s->quant_tables[s->context_model], sizeof(s->quant_table)); for (i = 0; i < s->plane_count; i++) { PlaneContext *const p = &s->plane[i]; memcpy(p->quant_table, s->quant_table, sizeof(p->quant_table)); - p->quant_table_index = avctx->context_model; + p->quant_table_index = s->context_model; p->context_count = s->context_count[p->quant_table_index]; } @@ -860,7 +866,7 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs) 0); for (j = 0; j < f->plane_count; j++) { put_symbol(c, state, f->plane[j].quant_table_index, 0); - av_assert0(f->plane[j].quant_table_index == f->avctx->context_model); + av_assert0(f->plane[j].quant_table_index == f->context_model); } if (!f->frame->interlaced_frame) put_symbol(c, state, 3, 0); @@ -1081,6 +1087,8 @@ static const AVOption options[] = { { .i64 = AC_RANGE_DEFAULT_TAB }, INT_MIN, INT_MAX, VE, "coder" }, { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST, { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, "coder" }, + { "context", "Context model", OFFSET(context_model), AV_OPT_TYPE_INT, + { .i64 = 0 }, 0, 1, VE }, { NULL } }; diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c index c18b38c4c16ba34a291aa616ebd121d693569c0c..bd3690162d85ffe0c655a82caf9ccb32ba26f4be 100644 --- a/libavcodec/huffyuvenc.c +++ b/libavcodec/huffyuvenc.c @@ -26,6 +26,8 @@ * huffyuv encoder */ +#include "libavutil/opt.h" + #include "avcodec.h" #include "huffyuv.h" #include "huffman.h" @@ -162,6 +164,12 @@ FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; FF_ENABLE_DEPRECATION_WARNINGS +#endif +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->context_model == 1) + s->context = avctx->context_model; +FF_ENABLE_DEPRECATION_WARNINGS #endif switch (avctx->pix_fmt) { @@ -187,15 +195,14 @@ FF_ENABLE_DEPRECATION_WARNINGS s->decorrelate = s->bitstream_bpp >= 24; s->predictor = avctx->prediction_method; s->interlaced = avctx->flags & AV_CODEC_FLAG_INTERLACED_ME ? 1 : 0; - if (avctx->context_model == 1) { - s->context = avctx->context_model; + if (s->context) { if (s->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) { av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with " "2 pass huffyuv encoding\n"); return -1; } - }else s->context= 0; + } if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) { if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { @@ -204,12 +211,14 @@ FF_ENABLE_DEPRECATION_WARNINGS "vcodec=ffvhuff or format=422p\n"); return -1; } - if (avctx->context_model) { +#if FF_API_PRIVATE_OPT + if (s->context) { av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported " "by huffyuv; use vcodec=ffvhuff\n"); return -1; } +#endif if (s->interlaced != ( s->height > 288 )) av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); @@ -686,6 +695,9 @@ static av_cold int encode_end(AVCodecContext *avctx) return 0; } +#define OFFSET(x) offsetof(HYuvContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM + AVCodec ff_huffyuv_encoder = { .name = "huffyuv", .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), @@ -704,12 +716,25 @@ AVCodec ff_huffyuv_encoder = { }; #if CONFIG_FFVHUFF_ENCODER +static const AVOption ffhuffyuv_options[] = { + { "context", "Set per-frame huffman tables", OFFSET(context), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { NULL } +}; + +static const AVClass ffhuffyuv_class = { + .class_name = "ffhuffyuv encoder", + .item_name = av_default_item_name, + .option = ffhuffyuv_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_ffvhuff_encoder = { .name = "ffvhuff", .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FFVHUFF, .priv_data_size = sizeof(HYuvContext), + .priv_class = &ffhuffyuv_class, .init = encode_init, .encode2 = encode_frame, .close = encode_end, diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 93b56fad722d486a1f9000818da7ca43122e25e1..afc5c1dfc9e7d8fc498c0f6520b4e28ecf648593 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -313,7 +313,9 @@ static const AVOption avcodec_options[] = { {"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"}, #endif /* FF_API_UNUSED_MEMBERS */ #endif /* FF_API_CODER_TYPE */ +#if FF_API_PRIVATE_OPT {"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, #if FF_API_XVMC {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},