From ed019b8e5bfefe59e307ce01f2860777e037b94b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 27 Feb 2012 12:12:19 +0100 Subject: [PATCH] lavc: add -mpv_flags to mpegvideo_enc-based encoders. Deprecate CODEC_FLAG2_SKIP_RD in favor of the corresponding mpv_flags flag. --- libavcodec/avcodec.h | 2 ++ libavcodec/flvenc.c | 3 +++ libavcodec/h261enc.c | 3 +++ libavcodec/mpeg12enc.c | 2 ++ libavcodec/mpeg4videoenc.c | 1 + libavcodec/mpegvideo.h | 23 +++++++++++++++++++++++ libavcodec/mpegvideo_enc.c | 23 ++++++++++++++++++++++- libavcodec/options.c | 4 +++- libavcodec/rv10enc.c | 3 +++ libavcodec/rv20enc.c | 3 +++ libavcodec/version.h | 3 +++ 11 files changed, 68 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index cd86856d32..0623c1cb01 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -570,7 +570,9 @@ typedef struct RcOverride{ #define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. #define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. #define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#if FF_API_MPV_GLOBAL_OPTS #define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#endif #define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. /* Unsupported options : diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c index 332592d623..121aaf548d 100644 --- a/libavcodec/flvenc.c +++ b/libavcodec/flvenc.c @@ -84,6 +84,8 @@ void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run, in } } +FF_MPV_GENERIC_CLASS(flv) + AVCodec ff_flv_encoder = { .name = "flv", .type = AVMEDIA_TYPE_VIDEO, @@ -94,4 +96,5 @@ AVCodec ff_flv_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), + .priv_class = &flv_class, }; diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c index 0ae48ca092..1f3cf714f1 100644 --- a/libavcodec/h261enc.c +++ b/libavcodec/h261enc.c @@ -321,6 +321,8 @@ static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ } } +FF_MPV_GENERIC_CLASS(h261) + AVCodec ff_h261_encoder = { .name = "h261", .type = AVMEDIA_TYPE_VIDEO, @@ -331,4 +333,5 @@ AVCodec ff_h261_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("H.261"), + .priv_class = &h261_class, }; diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index c53d99b1b5..b6cbbbc2d2 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -927,6 +927,7 @@ static void mpeg1_encode_block(MpegEncContext *s, static const AVOption mpeg1_options[] = { COMMON_OPTS + FF_MPV_COMMON_OPTS { NULL }, }; @@ -934,6 +935,7 @@ static const AVOption mpeg2_options[] = { COMMON_OPTS { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, + FF_MPV_COMMON_OPTS { NULL }, }; diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index d512daa1fa..c2d4626dad 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -1320,6 +1320,7 @@ void ff_mpeg4_encode_video_packet_header(MpegEncContext *s) static const AVOption options[] = { { "data_partitioning", "Use data partitioning.", OFFSET(data_partitioning), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, + FF_MPV_COMMON_OPTS { NULL }, }; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 9753d1064c..7e157fdfff 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -37,6 +37,8 @@ #include "mpeg12data.h" #include "rl.h" +#include "libavutil/opt.h" + #define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded enum OutputFormat { @@ -687,6 +689,8 @@ typedef struct MpegEncContext { int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block); + + int mpv_flags; ///< flags set by private options } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \ @@ -694,6 +698,25 @@ typedef struct MpegEncContext { &new_ctx->picture[pic - old_ctx->picture] : pic - (Picture*)old_ctx + (Picture*)new_ctx)\ : NULL) +/* mpegvideo_enc common options */ +#define FF_MPV_FLAG_SKIP_RD 0x0001 + +#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x) +#define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) +#define FF_MPV_COMMON_OPTS \ +{ "mpv_flags", "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "skip_rd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, { FF_MPV_FLAG_SKIP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ + +extern const AVOption ff_mpv_generic_options[]; + +#define FF_MPV_GENERIC_CLASS(name) \ +static const AVClass name ## _class = {\ + .class_name = #name " encoder",\ + .item_name = av_default_item_name,\ + .option = ff_mpv_generic_options,\ + .version = LIBAVUTIL_VERSION_INT,\ +}; + void ff_MPV_decode_defaults(MpegEncContext *s); int ff_MPV_common_init(MpegEncContext *s); void ff_MPV_common_end(MpegEncContext *s); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 6f4df59517..8e502ed62c 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -62,6 +62,11 @@ static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1]; static uint8_t default_fcode_tab[MAX_MV * 2 + 1]; +const AVOption ff_mpv_generic_options[] = { + FF_MPV_COMMON_OPTS + { NULL }, +}; + void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64], const uint16_t *quant_matrix, @@ -606,6 +611,11 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) } s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; +#if FF_API_MPV_GLOBAL_OPTS + if (avctx->flags2 & CODEC_FLAG2_SKIP_RD) + s->mpv_flags |= FF_MPV_FLAG_SKIP_RD; +#endif + switch (avctx->codec->id) { case CODEC_ID_MPEG1VIDEO: s->out_format = FMT_MPEG1; @@ -2698,7 +2708,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, &dmin, &next_block, 0, 0); } - if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){ + if (!best_s.mb_intra && s->mpv_flags & FF_MPV_FLAG_SKIP_RD) { int coded=0; for(i=0; i<6; i++) coded |= s->block_last_index[i]; @@ -4046,6 +4056,7 @@ int ff_dct_quantize_c(MpegEncContext *s, static const AVOption h263_options[] = { { "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, { "structured_slices","Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE}, + FF_MPV_COMMON_OPTS { NULL }, }; @@ -4074,6 +4085,7 @@ static const AVOption h263p_options[] = { { "aiv", "Use alternative inter VLC.", OFFSET(alt_inter_vlc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, { "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, { "structured_slices", "Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE}, + FF_MPV_COMMON_OPTS { NULL }, }; static const AVClass h263p_class = { @@ -4097,6 +4109,8 @@ AVCodec ff_h263p_encoder = { .priv_class = &h263p_class, }; +FF_MPV_GENERIC_CLASS(msmpeg4v2) + AVCodec ff_msmpeg4v2_encoder = { .name = "msmpeg4v2", .type = AVMEDIA_TYPE_VIDEO, @@ -4107,8 +4121,11 @@ AVCodec ff_msmpeg4v2_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), + .priv_class = &msmpeg4v2_class, }; +FF_MPV_GENERIC_CLASS(msmpeg4v3) + AVCodec ff_msmpeg4v3_encoder = { .name = "msmpeg4", .type = AVMEDIA_TYPE_VIDEO, @@ -4119,8 +4136,11 @@ AVCodec ff_msmpeg4v3_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), + .priv_class = &msmpeg4v3_class, }; +FF_MPV_GENERIC_CLASS(wmv1) + AVCodec ff_wmv1_encoder = { .name = "wmv1", .type = AVMEDIA_TYPE_VIDEO, @@ -4131,4 +4151,5 @@ AVCodec ff_wmv1_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"), + .priv_class = &wmv1_class, }; diff --git a/libavcodec/options.c b/libavcodec/options.c index 81e910cb7e..fb48030ebc 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -361,7 +361,9 @@ static const AVOption options[]={ {"refs", "reference frames to consider for motion compensation (Snow)", OFFSET(refs), AV_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E}, {"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, -{"skiprd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"}, +#if FF_API_MPV_GLOBAL_OPTS +{"skiprd", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"}, +#endif {"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.dbl = 6 }, 0, INT_MAX, V|E}, {"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.dbl = 256 }, 0, INT_MAX, V|E}, {"b_sensitivity", "adjusts sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.dbl = 40 }, 1, INT_MAX, V|E}, diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c index 47fb2225e4..1b4694c502 100644 --- a/libavcodec/rv10enc.c +++ b/libavcodec/rv10enc.c @@ -56,6 +56,8 @@ void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 3, 0); /* ignored */ } +FF_MPV_GENERIC_CLASS(rv10) + AVCodec ff_rv10_encoder = { .name = "rv10", .type = AVMEDIA_TYPE_VIDEO, @@ -66,4 +68,5 @@ AVCodec ff_rv10_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"), + .priv_class = &rv10_class, }; diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c index ace70d180b..8b50baf52f 100644 --- a/libavcodec/rv20enc.c +++ b/libavcodec/rv20enc.c @@ -57,6 +57,8 @@ void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number){ } } +FF_MPV_GENERIC_CLASS(rv20) + AVCodec ff_rv20_encoder = { .name = "rv20", .type = AVMEDIA_TYPE_VIDEO, @@ -67,4 +69,5 @@ AVCodec ff_rv20_encoder = { .close = ff_MPV_encode_end, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"), + .priv_class = &rv20_class, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index bf2848d4b2..ffce89588d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -50,5 +50,8 @@ #ifndef FF_API_OLD_ENCODE_VIDEO #define FF_API_OLD_ENCODE_VIDEO (LIBAVCODEC_VERSION_MAJOR < 55) #endif +#ifndef FF_API_MPV_GLOBAL_OPTS +#define FF_API_MPV_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 55) +#endif #endif /* AVCODEC_VERSION_H */