This option is only used by ffv1 and ffvhuff. It is a very codec-specific option, so deprecate the global variant. Improve documentation a little. Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>tags/n3.0
| @@ -2341,12 +2341,11 @@ typedef struct AVCodecContext { | |||||
| int coder_type; | int coder_type; | ||||
| #endif /* FF_API_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; | int context_model; | ||||
| #endif | |||||
| #if FF_API_MPV_OPT | #if FF_API_MPV_OPT | ||||
| /** | /** | ||||
| @@ -103,6 +103,7 @@ typedef struct FFV1Context { | |||||
| int ec; | int ec; | ||||
| int slice_damaged; | int slice_damaged; | ||||
| int key_frame_ok; | int key_frame_ok; | ||||
| int context_model; | |||||
| int bits_per_raw_sample; | int bits_per_raw_sample; | ||||
| int packed_at_lsb; | int packed_at_lsb; | ||||
| @@ -261,7 +261,7 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, | |||||
| int stride, int plane_index) | int stride, int plane_index) | ||||
| { | { | ||||
| int x, y, i; | 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]; | int16_t *sample[3]; | ||||
| s->run_index = 0; | 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 w, int h, const int stride[3]) | ||||
| { | { | ||||
| int x, y, p, i; | 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]; | int16_t *sample[MAX_PLANES][3]; | ||||
| int lbd = s->avctx->bits_per_raw_sample <= 8; | int lbd = s->avctx->bits_per_raw_sample <= 8; | ||||
| int bits = s->avctx->bits_per_raw_sample > 0 | int bits = s->avctx->bits_per_raw_sample > 0 | ||||
| @@ -418,7 +418,7 @@ static void write_header(FFV1Context *f) | |||||
| 0); | 0); | ||||
| for (j = 0; j < f->plane_count; j++) { | for (j = 0; j < f->plane_count; j++) { | ||||
| put_symbol(c, state, f->plane[j].quant_table_index, 0); | 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, | avctx, AV_LOG_WARNING, | ||||
| "Storing alpha plane, this will require a recent FFV1 decoder to playback!\n"); | "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) { | if (avctx->context_model > 1U) { | ||||
| av_log(avctx, AV_LOG_ERROR, | av_log(avctx, AV_LOG_ERROR, | ||||
| "Invalid context model %d, valid values are 0 and 1\n", | "Invalid context model %d, valid values are 0 and 1\n", | ||||
| avctx->context_model); | avctx->context_model); | ||||
| return AVERROR(EINVAL); | return AVERROR(EINVAL); | ||||
| } | } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | |||||
| #endif | |||||
| if (s->ac == AC_RANGE_CUSTOM_TAB) | if (s->ac == AC_RANGE_CUSTOM_TAB) | ||||
| for (i = 1; i < 256; i++) | 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[0] = (11 * 11 * 11 + 1) / 2; | ||||
| s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 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)); | sizeof(s->quant_table)); | ||||
| for (i = 0; i < s->plane_count; i++) { | for (i = 0; i < s->plane_count; i++) { | ||||
| PlaneContext *const p = &s->plane[i]; | PlaneContext *const p = &s->plane[i]; | ||||
| memcpy(p->quant_table, s->quant_table, sizeof(p->quant_table)); | 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]; | p->context_count = s->context_count[p->quant_table_index]; | ||||
| } | } | ||||
| @@ -860,7 +866,7 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs) | |||||
| 0); | 0); | ||||
| for (j = 0; j < f->plane_count; j++) { | for (j = 0; j < f->plane_count; j++) { | ||||
| put_symbol(c, state, f->plane[j].quant_table_index, 0); | 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) | if (!f->frame->interlaced_frame) | ||||
| put_symbol(c, state, 3, 0); | 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" }, | { .i64 = AC_RANGE_DEFAULT_TAB }, INT_MIN, INT_MAX, VE, "coder" }, | ||||
| { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST, | { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST, | ||||
| { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, "coder" }, | { .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 } | { NULL } | ||||
| }; | }; | ||||
| @@ -26,6 +26,8 @@ | |||||
| * huffyuv encoder | * huffyuv encoder | ||||
| */ | */ | ||||
| #include "libavutil/opt.h" | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "huffyuv.h" | #include "huffyuv.h" | ||||
| #include "huffman.h" | #include "huffman.h" | ||||
| @@ -162,6 +164,12 @@ FF_DISABLE_DEPRECATION_WARNINGS | |||||
| avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; | avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; | ||||
| avctx->coded_frame->key_frame = 1; | avctx->coded_frame->key_frame = 1; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | 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 | #endif | ||||
| switch (avctx->pix_fmt) { | switch (avctx->pix_fmt) { | ||||
| @@ -187,15 +195,14 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||
| s->decorrelate = s->bitstream_bpp >= 24; | s->decorrelate = s->bitstream_bpp >= 24; | ||||
| s->predictor = avctx->prediction_method; | s->predictor = avctx->prediction_method; | ||||
| s->interlaced = avctx->flags & AV_CODEC_FLAG_INTERLACED_ME ? 1 : 0; | 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)) { | if (s->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) { | ||||
| av_log(avctx, AV_LOG_ERROR, | av_log(avctx, AV_LOG_ERROR, | ||||
| "context=1 is not compatible with " | "context=1 is not compatible with " | ||||
| "2 pass huffyuv encoding\n"); | "2 pass huffyuv encoding\n"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| }else s->context= 0; | |||||
| } | |||||
| if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) { | if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) { | ||||
| if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { | if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { | ||||
| @@ -204,12 +211,14 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||
| "vcodec=ffvhuff or format=422p\n"); | "vcodec=ffvhuff or format=422p\n"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| if (avctx->context_model) { | |||||
| #if FF_API_PRIVATE_OPT | |||||
| if (s->context) { | |||||
| av_log(avctx, AV_LOG_ERROR, | av_log(avctx, AV_LOG_ERROR, | ||||
| "Error: per-frame huffman tables are not supported " | "Error: per-frame huffman tables are not supported " | ||||
| "by huffyuv; use vcodec=ffvhuff\n"); | "by huffyuv; use vcodec=ffvhuff\n"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| #endif | |||||
| if (s->interlaced != ( s->height > 288 )) | if (s->interlaced != ( s->height > 288 )) | ||||
| av_log(avctx, AV_LOG_INFO, | av_log(avctx, AV_LOG_INFO, | ||||
| "using huffyuv 2.2.0 or newer interlacing flag\n"); | "using huffyuv 2.2.0 or newer interlacing flag\n"); | ||||
| @@ -686,6 +695,9 @@ static av_cold int encode_end(AVCodecContext *avctx) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #define OFFSET(x) offsetof(HYuvContext, x) | |||||
| #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | |||||
| AVCodec ff_huffyuv_encoder = { | AVCodec ff_huffyuv_encoder = { | ||||
| .name = "huffyuv", | .name = "huffyuv", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), | ||||
| @@ -704,12 +716,25 @@ AVCodec ff_huffyuv_encoder = { | |||||
| }; | }; | ||||
| #if CONFIG_FFVHUFF_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 = { | AVCodec ff_ffvhuff_encoder = { | ||||
| .name = "ffvhuff", | .name = "ffvhuff", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), | ||||
| .type = AVMEDIA_TYPE_VIDEO, | .type = AVMEDIA_TYPE_VIDEO, | ||||
| .id = AV_CODEC_ID_FFVHUFF, | .id = AV_CODEC_ID_FFVHUFF, | ||||
| .priv_data_size = sizeof(HYuvContext), | .priv_data_size = sizeof(HYuvContext), | ||||
| .priv_class = &ffhuffyuv_class, | |||||
| .init = encode_init, | .init = encode_init, | ||||
| .encode2 = encode_frame, | .encode2 = encode_frame, | ||||
| .close = encode_end, | .close = encode_end, | ||||
| @@ -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"}, | {"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_UNUSED_MEMBERS */ | ||||
| #endif /* FF_API_CODER_TYPE */ | #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}, | {"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}, | {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, | ||||
| #if FF_API_XVMC | #if FF_API_XVMC | ||||
| {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, | {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, | ||||