From 2862b63783b5556f7f3fb2d097629bc6879f833a Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 9 Nov 2015 03:15:06 +0100 Subject: [PATCH] lavc: Move prediction_method to codec private options This options is only used by huffyuv, ffvhuv, jpegls, mjpeg, mpegvideoenc, png, utvideo. It is a very codec-specific options, so deprecate the global variant. Set proper limits to the maximum allowed values, and update utvideoenc tests to use the new option name. Signed-off-by: Vittorio Giovara --- libavcodec/avcodec.h | 10 ++++----- libavcodec/huffyuvenc.c | 37 +++++++++++++++++++++++++------ libavcodec/jpeglsenc.c | 39 +++++++++++++++++++++++++++++--- libavcodec/ljpegenc.c | 43 +++++++++++++++++++++++++++++++----- libavcodec/mjpegenc.c | 19 ++++++++++++++++ libavcodec/mjpegenc_common.c | 4 ++-- libavcodec/mjpegenc_common.h | 2 +- libavcodec/mpegvideo.h | 1 + libavcodec/mpegvideo_enc.c | 5 ++++- libavcodec/options_table.h | 2 ++ libavcodec/pngenc.c | 35 ++++++++++++++++++++++++++--- libavcodec/utvideo.c | 2 ++ libavcodec/utvideoenc.c | 29 +++++++++++++++++++++++- tests/fate/utvideo.mak | 8 +++---- 14 files changed, 204 insertions(+), 32 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e997129194..04617fecac 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1678,15 +1678,15 @@ typedef struct AVCodecContext { * - decoding: Set by user (or 0). */ int slice_count; - /** - * prediction method (needed for huffyuv) - * - encoding: Set by user. - * - decoding: unused - */ + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated int prediction_method; #define FF_PRED_LEFT 0 #define FF_PRED_PLANE 1 #define FF_PRED_MEDIAN 2 +#endif /** * slice offsets in the frame in bytes diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c index bd3690162d..a6ffd24017 100644 --- a/libavcodec/huffyuvenc.c +++ b/libavcodec/huffyuvenc.c @@ -193,7 +193,12 @@ FF_ENABLE_DEPRECATION_WARNINGS } avctx->bits_per_coded_sample = s->bitstream_bpp; s->decorrelate = s->bitstream_bpp >= 24; - s->predictor = avctx->prediction_method; +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->prediction_method) + s->predictor = avctx->prediction_method; +FF_ENABLE_DEPRECATION_WARNINGS +#endif s->interlaced = avctx->flags & AV_CODEC_FLAG_INTERLACED_ME ? 1 : 0; if (s->context) { if (s->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) { @@ -698,12 +703,34 @@ static av_cold int encode_end(AVCodecContext *avctx) #define OFFSET(x) offsetof(HYuvContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +#define HUFF_CLASS(variant) \ +static const AVClass variant ## _class = { \ + .class_name = # variant, \ + .item_name = av_default_item_name, \ + .option = variant ## _options, \ + .version = LIBAVUTIL_VERSION_INT, \ +} + +#define FF_HUFFYUV_COMMON_OPTS \ +{ "pred", "Prediction method", OFFSET(predictor), AV_OPT_TYPE_INT, { .i64 = LEFT }, LEFT, MEDIAN, VE, "pred" }, \ + { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LEFT }, INT_MIN, INT_MAX, VE, "pred" }, \ + { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PLANE }, INT_MIN, INT_MAX, VE, "pred" }, \ + { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MEDIAN }, INT_MIN, INT_MAX, VE, "pred" } + +static const AVOption huffyuv_options[] = { + FF_HUFFYUV_COMMON_OPTS, + { NULL}, +}; + +HUFF_CLASS(huffyuv); + AVCodec ff_huffyuv_encoder = { .name = "huffyuv", .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HUFFYUV, .priv_data_size = sizeof(HYuvContext), + .priv_class = &huffyuv_class, .init = encode_init, .encode2 = encode_frame, .close = encode_end, @@ -717,16 +744,12 @@ AVCodec ff_huffyuv_encoder = { #if CONFIG_FFVHUFF_ENCODER static const AVOption ffhuffyuv_options[] = { + FF_HUFFYUV_COMMON_OPTS, { "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, -}; +HUFF_CLASS(ffhuffyuv); AVCodec ff_ffvhuff_encoder = { .name = "ffvhuff", diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index 1f32928cb3..8131d27311 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -34,6 +34,12 @@ #include "mjpegenc.h" #include "jpegls.h" +typedef struct JPEGLSContext { + AVClass *class; + + int pred; +} JPEGLSContext; + /** * Encode error from regular symbol */ @@ -249,8 +255,8 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb) static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { + JPEGLSContext *ctx = avctx->priv_data; const AVFrame *const p = pict; - const int near = avctx->prediction_method; PutBitContext pb, pb2; GetBitContext gb; uint8_t *buf2 = NULL; @@ -261,6 +267,13 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, int i, size, ret; int comps; +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->prediction_method) + ctx->pred = avctx->prediction_method; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16) comps = 1; @@ -301,7 +314,7 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, put_bits(&pb, 8, i); // component ID put_bits(&pb, 8, 0); // mapping index: none } - put_bits(&pb, 8, near); + put_bits(&pb, 8, ctx->pred); put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line put_bits(&pb, 8, 0); // point transform: none @@ -310,7 +323,7 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, goto memfail; /* initialize JPEG-LS state from JPEG parameters */ - state->near = near; + state->near = ctx->pred; state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8; ff_jpegls_reset_coding_parameters(state, 0); ff_jpegls_init_state(state); @@ -433,11 +446,31 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } +#define OFFSET(x) offsetof(JPEGLSContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { +{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "pred" }, + { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, + { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, + { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" }, + + { NULL}, +}; + +static const AVClass jpegls_class = { + .class_name = "jpegls", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_jpegls_encoder = { .name = "jpegls", .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEGLS, + .priv_data_size = sizeof(JPEGLSContext), + .priv_class = &jpegls_class, .init = encode_init_ls, .encode2 = encode_picture_ls, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index 41dba89b7b..b6d73a42be 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -43,6 +43,7 @@ #include "mjpegenc.h" typedef struct LJpegEncContext { + AVClass *class; IDCTDSPContext idsp; ScanTable scantable; uint16_t matrix[64]; @@ -56,6 +57,7 @@ typedef struct LJpegEncContext { uint8_t huff_size_dc_chrominance[12]; uint16_t (*scratch)[4]; + int pred; } LJpegEncContext; static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb, @@ -66,15 +68,21 @@ static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb, const int height = frame->height; const int linesize = frame->linesize[0]; uint16_t (*buffer)[4] = s->scratch; - const int predictor = avctx->prediction_method+1; int left[3], top[3], topleft[3]; int x, y, i; +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->prediction_method) + s->pred = avctx->prediction_method + 1; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + for (i = 0; i < 3; i++) buffer[0][i] = 1 << (9 - 1); for (y = 0; y < height; y++) { - const int modified_predictor = y ? predictor : 1; + const int modified_predictor = y ? s->pred : 1; uint8_t *ptr = frame->data[0] + (linesize * y); if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 3) { @@ -181,12 +189,18 @@ static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb, static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, const AVFrame *frame) { - const int predictor = avctx->prediction_method + 1; LJpegEncContext *s = avctx->priv_data; const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0]; const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0]; int mb_x, mb_y; +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->prediction_method) + s->pred = avctx->prediction_method + 1; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + for (mb_y = 0; mb_y < mb_height; mb_y++) { if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) { @@ -195,7 +209,7 @@ static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, } for (mb_x = 0; mb_x < mb_width; mb_x++) - ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y); + ljpeg_encode_yuv_mb(s, pb, frame, s->pred, mb_x, mb_y); } return 0; @@ -227,7 +241,7 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, init_put_bits(&pb, pkt->data, pkt->size); ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable, - s->matrix); + s->pred, s->matrix); header_bits = put_bits_count(&pb); @@ -316,12 +330,31 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } +#define OFFSET(x) offsetof(LJpegEncContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { +{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" }, + { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, + { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" }, + { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" }, + + { NULL}, +}; + +static const AVClass ljpeg_class = { + .class_name = "ljpeg", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_ljpeg_encoder = { .name = "ljpeg", .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LJPEG, .priv_data_size = sizeof(LJpegEncContext), + .priv_class = &ljpeg_class, .init = ljpeg_encode_init, .encode2 = ljpeg_encode_frame, .close = ljpeg_encode_close, diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 6724310d98..e48c945072 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -154,12 +154,31 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[8][64]) s->i_tex_bits += get_bits_diff(s); } +#define OFFSET(x) offsetof(MpegEncContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { +{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" }, + { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, + { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" }, + { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" }, + + { NULL}, +}; + +static const AVClass mjpeg_class = { + .class_name = "mjpeg", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_mjpeg_encoder = { .name = "mjpeg", .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(MpegEncContext), + .priv_class = &mjpeg_class, .init = ff_mpv_encode_init, .encode2 = ff_mpv_encode_picture, .close = ff_mpv_encode_end, diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 54df9878e9..2262de60bd 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -134,7 +134,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) } void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, - ScanTable *intra_scantable, + ScanTable *intra_scantable, int pred, uint16_t intra_matrix[64]) { int chroma_h_shift, chroma_v_shift; @@ -217,7 +217,7 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, put_bits(pb, 4, 1); /* DC huffman table index */ put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - put_bits(pb, 8, lossless ? avctx->prediction_method + 1 : 0); /* Ss (not used) */ + put_bits(pb, 8, lossless ? pred : 0); /* Ss (not used) */ switch (avctx->codec_id) { case AV_CODEC_ID_MJPEG: put_bits(pb, 8, 63); break; /* Se (not used) */ diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h index b48911e364..9b5933e057 100644 --- a/libavcodec/mjpegenc_common.h +++ b/libavcodec/mjpegenc_common.h @@ -28,7 +28,7 @@ #include "put_bits.h" void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, - ScanTable *intra_scantable, + ScanTable *intra_scantable, int pred, uint16_t intra_matrix[64]); void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); void ff_mjpeg_encode_stuffing(PutBitContext *pbc); diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index ea8da572c0..e7914fd054 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -405,6 +405,7 @@ typedef struct MpegEncContext { /* MJPEG specific */ struct MJpegContext *mjpeg_ctx; + int pred; /* MSMPEG4 specific */ int mv_table_index; diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index fbbbb00990..599cd065fa 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -921,6 +921,9 @@ FF_ENABLE_DEPRECATION_WARNINGS FF_DISABLE_DEPRECATION_WARNINGS if (avctx->brd_scale) s->brd_scale = avctx->brd_scale; + + if (avctx->prediction_method) + s->pred = avctx->prediction_method + 1; FF_ENABLE_DEPRECATION_WARNINGS #endif @@ -3583,7 +3586,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) case FMT_MJPEG: if (CONFIG_MJPEG_ENCODER) ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, - s->intra_matrix); + s->pred, s->intra_matrix); break; case FMT_H261: if (CONFIG_H261_ENCODER) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index b93a72dc1c..11063176db 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -236,10 +236,12 @@ static const AVOption avcodec_options[] = { {"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"}, {"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"}, {"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_PRIVATE_OPT {"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"}, {"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"}, {"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"}, {"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"}, +#endif {"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, {"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"}, {"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"}, diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 28df5af066..f91c54c7de 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/opt.h" #include "libavutil/stereo3d.h" #include "avcodec.h" @@ -35,6 +36,7 @@ #define IOBUF_SIZE 4096 typedef struct PNGEncContext { + AVClass *class; HuffYUVEncDSPContext hdsp; uint8_t *bytestream; @@ -486,21 +488,48 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_huffyuvencdsp_init(&s->hdsp); - s->filter_type = av_clip(avctx->prediction_method, - PNG_FILTER_VALUE_NONE, - PNG_FILTER_VALUE_MIXED); +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->prediction_method) + s->filter_type = av_clip(avctx->prediction_method, + PNG_FILTER_VALUE_NONE, + PNG_FILTER_VALUE_MIXED); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK) s->filter_type = PNG_FILTER_VALUE_NONE; return 0; } +#define OFFSET(x) offsetof(PNGEncContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { +{ "pred", "Prediction method", OFFSET(filter_type), AV_OPT_TYPE_INT, { .i64 = PNG_FILTER_VALUE_NONE }, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED, VE, "pred" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_NONE }, INT_MIN, INT_MAX, VE, "pred" }, + { "sub", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_SUB }, INT_MIN, INT_MAX, VE, "pred" }, + { "up", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_UP }, INT_MIN, INT_MAX, VE, "pred" }, + { "avg", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_AVG }, INT_MIN, INT_MAX, VE, "pred" }, + { "paeth", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_PAETH }, INT_MIN, INT_MAX, VE, "pred" }, + { "mixed", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_MIXED }, INT_MIN, INT_MAX, VE, "pred" }, + + { NULL}, +}; + +static const AVClass png_class = { + .class_name = "png", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; AVCodec ff_png_encoder = { .name = "png", .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PNG, .priv_data_size = sizeof(PNGEncContext), + .priv_class = &png_class, .init = png_enc_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index eb5a924222..35e927ca2d 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -26,9 +26,11 @@ #include "utvideo.h" +#if FF_API_PRIVATE_OPT const int ff_ut_pred_order[5] = { PRED_LEFT, PRED_MEDIAN, PRED_MEDIAN, PRED_NONE, PRED_GRADIENT }; +#endif const int ff_ut_rgb_order[4] = { 1, 2, 0, 3 }; // G, B, R, A diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index 9af0f66a71..7fb838e841 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -26,6 +26,8 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" +#include "libavutil/opt.h" + #include "avcodec.h" #include "internal.h" #include "bswapdsp.h" @@ -111,6 +113,8 @@ static av_cold int utvideo_encode_init(AVCodecContext *avctx) ff_bswapdsp_init(&c->bdsp); ff_huffyuvencdsp_init(&c->hdsp); +#if FF_API_PRIVATE_OPT +FF_DISABLE_DEPRECATION_WARNINGS /* Check the prediction method, and error out if unsupported */ if (avctx->prediction_method < 0 || avctx->prediction_method > 4) { av_log(avctx, AV_LOG_WARNING, @@ -126,7 +130,10 @@ static av_cold int utvideo_encode_init(AVCodecContext *avctx) } /* Convert from libavcodec prediction type to Ut Video's */ - c->frame_pred = ff_ut_pred_order[avctx->prediction_method]; + if (avctx->prediction_method) + c->frame_pred = ff_ut_pred_order[avctx->prediction_method]; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (c->frame_pred == PRED_GRADIENT) { av_log(avctx, AV_LOG_ERROR, "Gradient prediction is not supported.\n"); @@ -631,12 +638,32 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } +#define OFFSET(x) offsetof(UtvideoContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { +{ "pred", "Prediction method", OFFSET(frame_pred), AV_OPT_TYPE_INT, { .i64 = PRED_LEFT }, PRED_NONE, PRED_MEDIAN, VE, "pred" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_NONE }, INT_MIN, INT_MAX, VE, "pred" }, + { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_LEFT }, INT_MIN, INT_MAX, VE, "pred" }, + { "gradient", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_GRADIENT }, INT_MIN, INT_MAX, VE, "pred" }, + { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_MEDIAN }, INT_MIN, INT_MAX, VE, "pred" }, + + { NULL}, +}; + +static const AVClass utvideo_class = { + .class_name = "utvideo", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_utvideo_encoder = { .name = "utvideo", .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_UTVIDEO, .priv_data_size = sizeof(UtvideoContext), + .priv_class = &utvideo_class, .init = utvideo_encode_init, .encode2 = utvideo_encode_frame, .close = utvideo_encode_close, diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak index e1ef7ecbd6..4c0c6bf460 100644 --- a/tests/fate/utvideo.mak +++ b/tests/fate/utvideo.mak @@ -37,7 +37,7 @@ FATE_UTVIDEOENC += fate-utvideoenc_rgba_median fate-utvideoenc_rgba_median: OPTS = -pix_fmt rgba -pred median FATE_UTVIDEOENC += fate-utvideoenc_rgba_none -fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred 3 +fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred none FATE_UTVIDEOENC += fate-utvideoenc_rgb_left fate-utvideoenc_rgb_left: OPTS = -pix_fmt rgb24 -pred left @@ -46,7 +46,7 @@ FATE_UTVIDEOENC += fate-utvideoenc_rgb_median fate-utvideoenc_rgb_median: OPTS = -pix_fmt rgb24 -pred median FATE_UTVIDEOENC += fate-utvideoenc_rgb_none -fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred 3 +fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred none FATE_UTVIDEOENC += fate-utvideoenc_yuv420_left fate-utvideoenc_yuv420_left: OPTS = -pix_fmt yuv420p -pred left @@ -55,7 +55,7 @@ FATE_UTVIDEOENC += fate-utvideoenc_yuv420_median fate-utvideoenc_yuv420_median: OPTS = -pix_fmt yuv420p -pred median FATE_UTVIDEOENC += fate-utvideoenc_yuv420_none -fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred 3 +fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred none FATE_UTVIDEOENC += fate-utvideoenc_yuv422_left fate-utvideoenc_yuv422_left: OPTS = -pix_fmt yuv422p -pred left @@ -64,7 +64,7 @@ FATE_UTVIDEOENC += fate-utvideoenc_yuv422_median fate-utvideoenc_yuv422_median: OPTS = -pix_fmt yuv422p -pred median FATE_UTVIDEOENC += fate-utvideoenc_yuv422_none -fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred 3 +fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred none $(FATE_UTVIDEOENC): $(VREF)