Re: [FFmpeg-devel] [PATCH v4] lavc/libvpxenc: add screen-content-mode option
Hello. On Tue, Feb 13, 2024 at 12:12 AM James Zern wrote: > [...] > > +@item screen-content-mode > > +Screen content mode, one of: off (0), screen (1), screen with more > > aggressive rate control (2). > > + > > Move this above 'VP9-specific options' and add a section for VP8. Also > reword this to '...one of: 0 (off), 1 (screen), ...'. The parameter is > an integer so should list that first, similar to aq-mode. > This and below are addressed in v5. Thank you. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5] lavc/libvpxenc: add screen-content-mode option
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. Co-authored-by: Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 6 ++ libavcodec/libvpxenc.c | 13 + libavcodec/version.h | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..13a7084512 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2237,6 +2237,12 @@ the two temporal layer 2 frames within the temporal period. @end table @end table +@item VP8-specific options +@table @option +@item screen-content-mode +Screen content mode, one of: (0) off, (1) screen, (2) screen with more aggressive rate control. +@end table + @item VP9-specific options @table @option @item lossless diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..8f765f2dc4 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -121,6 +121,9 @@ typedef struct VPxEncoderContext { int *ts_layer_flags; int current_temporal_idx; +// VP8-only +int screen_content_mode; + // VP9-only int lossless; int tile_columns; @@ -164,6 +167,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1262,6 +1266,14 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif } #endif +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->screen_content_mode >= 0) { +if (ctx->screen_content_mode == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); +} +codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->screen_content_mode); +} av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); @@ -1946,6 +1958,7 @@ static const AVOption vp8_options[] = { { "auto-alt-ref","Enable use of alternate reference " "frames (2-pass only)", OFFSET(auto_alt_ref),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, { "cpu-used","Quality/Speed ratio modifier", OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, +{ "screen-content-mode", "Encoder screen content mode", OFFSET(screen_content_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, LEGACY_OPTIONS { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index f2f14eaed1..ecdbc51c74 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 39 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.43.0.687.g38aa6559b0-goog ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3] lavc/libvpxenc: add screen-content-mode option
Hello. On Fri, Feb 9, 2024 at 7:28 PM James Zern wrote: > Just sent v4, which addresses the below comments. Thank you. > On Thu, Feb 8, 2024 at 1:58 PM Dariusz Marcinkiewicz via ffmpeg-devel > wrote: ... > > --- a/libavcodec/libvpxenc.c > > +++ b/libavcodec/libvpxenc.c > > @@ -114,6 +114,7 @@ typedef struct VPxEncoderContext { > > int crf; > > int static_thresh; > > int max_intra_rate; > > +int screen_content_mode; > > Move this to a VP8-only section similar to VP9. > Done. ... > > @@ -164,6 +165,7 @@ static const char *const ctlidstr[] = { ... > > +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE > > This control was available in libvpx 1.4.0, the minimum version > supported. You can remove this check. > Done. ... > > +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->screen_content_mode >= > > 0) { > > + if (ctx->screen_content_mode == 2 && ctx->is_alpha) { > > Indent is 4 spaces here and throughout the patch. > Done. > > [...] > > > > -coded_size = queue_frames(avctx, >encoder, > > >coded_frame_list, pkt); > > +coded_size = queue_frames(avctx, >encoder, >coded_frame_list, > > + pkt, ctx->is_alpha, _enc); > > +if (avctx->codec_id == AV_CODEC_ID_VP8 && frame_enc == 0 && > > +ctx->screen_content_mode == 2 && frame) { > > +// VP8 tuned for screen content with aggresive rate control - > > returned > > aggressive. > > > +// OK status code but produced no output, this indicates frame was > > +// rolled back due to bitrate overshoot - try to encode it again. > > This is a little weird given there's no adjustment to the encoder. I > think this should be a separate patch at least. If the encoder decided > to drop the frame in this mode it seems like the right decision given > the setting description. If it works as part of the drop frames > threshold then maybe the recode should be in the library based on some > threshold. > Dropped this part. ... > > [...] > > @@ -1946,6 +1987,12 @@ static const AVOption vp8_options[] = { > > { "auto-alt-ref","Enable use of alternate reference " > > "frames (2-pass only)", > > OFFSET(auto_alt_ref),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, > > { "cpu-used","Quality/Speed ratio modifier", > > OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, > > +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE > > +{ "screen-content-mode", "Encoder screen content mode", > > OFFSET(screen_content_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, > > "screen_content_mode"}, > > +{ "off", "Screen content mode off",0, > > AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, > > "screen_content_mode"}, > > +{ "on", "Screen content mode on", 0, > > AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, > > "screen_content_mode"}, > > +{ "on-agressive-rate-control", "Screen content mode on with aggressive > > rate control", 0,AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, > > "screen_content_mode"}, > > aggressive. > There's no string equivalent in vpxenc though, so this should probably > just be ints. > Removed. ... > > diff --git a/libavcodec/version.h b/libavcodec/version.h > > index 0fae3d06d3..4b618d740f 100644 > > --- a/libavcodec/version.h > > +++ b/libavcodec/version.h > > @@ -30,7 +30,7 @@ > > #include "version_major.h" > > > > #define LIBAVCODEC_VERSION_MINOR 38 > > -#define LIBAVCODEC_VERSION_MICRO 100 > > +#define LIBAVCODEC_VERSION_MICRO 101 > > > > This will need a rebase. Done. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4] lavc/libvpxenc: add screen-content-mode option
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. Co-authored-by: Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 3 +++ libavcodec/libvpxenc.c | 11 +++ libavcodec/version.h | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..0868aa66db 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2150,6 +2150,9 @@ of quality. Set a change threshold on blocks below which they will be skipped by the encoder. +@item screen-content-mode +Screen content mode, one of: off (0), screen (1), screen with more aggressive rate control (2). + @item slices (@emph{token-parts}) Note that FFmpeg's @option{slices} option gives the total number of partitions, while @command{vpxenc}'s @option{token-parts} is given as diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..0d507beaae 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -102,6 +102,7 @@ typedef struct VPxEncoderContext { #define VP8F_AUTO_ALT_REF0x0002 ///< Enable automatic alternate reference frame generation int auto_alt_ref; +int screen_content_mode; int arnr_max_frames; int arnr_strength; @@ -164,6 +165,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1262,6 +1264,14 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif } #endif +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->screen_content_mode >= 0) { +if (ctx->screen_content_mode == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); +} +codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->screen_content_mode); +} av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); @@ -1946,6 +1956,7 @@ static const AVOption vp8_options[] = { { "auto-alt-ref","Enable use of alternate reference " "frames (2-pass only)", OFFSET(auto_alt_ref),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, { "cpu-used","Quality/Speed ratio modifier", OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, +{ "screen-content-mode", "Encoder screen content mode", OFFSET(screen_content_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, "screen_content_mode"}, LEGACY_OPTIONS { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index f2f14eaed1..ecdbc51c74 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 39 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.43.0.687.g38aa6559b0-goog ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] libavcodec: add tune_content option also for VP8.
Hi. On Thu, Feb 8, 2024 at 7:13 AM James Zern wrote: > > Hi, > > On Wed, Feb 7, 2024 at 8:04 AM Dariusz Marcinkiewicz via ffmpeg-devel > wrote: > > > > This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. > > > > For the subject use '(libavcodec|avcodec|lavc)/libvpxenc: ...' to > better document what is being changed. See the history of the file for > examples. Sent out v3 of the patch addressing this and remaining comments. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3] lavc/libvpxenc: add screen-content-mode option
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx and makes us retry encode if screen_content_mode == 2 and no output was produced by encoder. Co-authored-by: Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 3 +++ libavcodec/libvpxenc.c | 57 ++ libavcodec/version.h | 2 +- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..0868aa66db 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2150,6 +2150,9 @@ of quality. Set a change threshold on blocks below which they will be skipped by the encoder. +@item screen-content-mode +Screen content mode, one of: off (0), screen (1), screen with more aggressive rate control (2). + @item slices (@emph{token-parts}) Note that FFmpeg's @option{slices} option gives the total number of partitions, while @command{vpxenc}'s @option{token-parts} is given as diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..7571a8577a 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -114,6 +114,7 @@ typedef struct VPxEncoderContext { int crf; int static_thresh; int max_intra_rate; +int screen_content_mode; int rc_undershoot_pct; int rc_overshoot_pct; @@ -164,6 +165,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1262,6 +1264,16 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif } #endif +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->screen_content_mode >= 0) { + if (ctx->screen_content_mode == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); + } + codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->screen_content_mode); +} +#endif av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); @@ -1379,14 +1391,15 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, * @return AVERROR(ENOMEM) on coded frame queue data allocation error */ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, -struct FrameListData **frame_list, AVPacket *pkt_out) +struct FrameListData **frame_list, AVPacket *pkt_out, +int queue_only, int *frame_enc) { VPxContext *ctx = avctx->priv_data; const struct vpx_codec_cx_pkt *pkt; const void *iter = NULL; int size = 0; -if (!ctx->is_alpha && *frame_list) { +if (!queue_only && *frame_list) { struct FrameListData *cx_frame = *frame_list; /* return the leading frame if we've already begun queueing */ size = storeframe(avctx, cx_frame, NULL, pkt_out); @@ -1401,7 +1414,7 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, while (pkt = vpx_codec_get_cx_data(encoder, )) { switch (pkt->kind) { case VPX_CODEC_CX_FRAME_PKT: -if (!ctx->is_alpha && !size) { +if (!queue_only && !size) { struct FrameListData cx_frame; /* avoid storing the frame when the list is empty and we haven't yet @@ -1411,6 +1424,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, size = storeframe(avctx, _frame, NULL, pkt_out); if (size < 0) return size; +if (size > 0) +*frame_enc = 1; } else { struct FrameListData *cx_frame = av_malloc(sizeof(*cx_frame)); @@ -1430,6 +1445,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, return AVERROR(ENOMEM); } memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); +if (pkt->data.frame.sz > 0) + *frame_enc = 1; coded_frame_add(frame_list, cx_frame); } break; @@ -1693,6 +1710,7 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt, vpx_svc_layer_id_t layer_id; int layer_id_valid = 0; unsigned long duration = 0; +int frame_enc = 0; if (avctx->qmax >= 0 && enccfg->rc_max_quantizer != avctx->qmax) { struct vpx_codec_enc_cfg cfg = *enccfg; @@ -1856,9 +1874,32 @@
[FFmpeg-devel] [PATCH v2] libavcodec: add tune_content option also for VP8.
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. Changes since v1: - Put the new param initialzation in the right place, - Account for cases when the encoder's output is queued up. Co-authored-by: Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 7 -- libavcodec/libvpxenc.c | 56 ++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..2a9b38f62a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2186,6 +2186,11 @@ Enable error resiliency features. Increase sharpness at the expense of lower PSNR. The valid range is [0, 7]. +@item tune-content +Set content type. +For VP8: default (0), screen (1), screen with aggressive rate control (2). +For VP9: default (0), screen (1), film (2). + @item ts-parameters Sets the temporal scalability configuration using a :-separated list of key=value pairs. For example, to specify temporal scalability parameters @@ -2268,8 +2273,6 @@ colorspaces: @end table @item row-mt @var{boolean} Enable row based multi-threading. -@item tune-content -Set content type: default (0), screen (1), film (2). @item corpus-complexity Corpus VBR mode is a variant of standard VBR where the complexity distribution midpoint is passed in rather than calculated for a specific clip or chunk. diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..c73c92d49b 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -164,6 +164,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1262,6 +1263,16 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif } #endif +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->tune_content >= 0) { + if (ctx->tune_content == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); + } + codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->tune_content); +} +#endif av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); @@ -1379,14 +1390,15 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, * @return AVERROR(ENOMEM) on coded frame queue data allocation error */ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, -struct FrameListData **frame_list, AVPacket *pkt_out) +struct FrameListData **frame_list, AVPacket *pkt_out, +int queue_only, int *frame_enc) { VPxContext *ctx = avctx->priv_data; const struct vpx_codec_cx_pkt *pkt; const void *iter = NULL; int size = 0; -if (!ctx->is_alpha && *frame_list) { +if (!queue_only && *frame_list) { struct FrameListData *cx_frame = *frame_list; /* return the leading frame if we've already begun queueing */ size = storeframe(avctx, cx_frame, NULL, pkt_out); @@ -1401,7 +1413,7 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, while (pkt = vpx_codec_get_cx_data(encoder, )) { switch (pkt->kind) { case VPX_CODEC_CX_FRAME_PKT: -if (!ctx->is_alpha && !size) { +if (!queue_only && !size) { struct FrameListData cx_frame; /* avoid storing the frame when the list is empty and we haven't yet @@ -1411,6 +1423,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, size = storeframe(avctx, _frame, NULL, pkt_out); if (size < 0) return size; +if (size > 0) +*frame_enc = 1; } else { struct FrameListData *cx_frame = av_malloc(sizeof(*cx_frame)); @@ -1430,6 +1444,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, return AVERROR(ENOMEM); } memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); +if (pkt->data.frame.sz > 0) + *frame_enc = 1; coded_frame_add(frame_list, cx_frame); } break; @@ -1693,6 +1709,7 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt, vpx_svc_layer_id_t layer_id; int layer_id_valid = 0; unsigned long duration = 0;
[FFmpeg-devel] [PATCH v2] libavcodec: add tune_content option also for VP8.
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. Changes since v1: - Put the new param initialzation in the right place, - Account for cases when the encoder's output is queued up. Co-authored-by: Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 7 -- libavcodec/libvpxenc.c | 56 ++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..2a9b38f62a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2186,6 +2186,11 @@ Enable error resiliency features. Increase sharpness at the expense of lower PSNR. The valid range is [0, 7]. +@item tune-content +Set content type. +For VP8: default (0), screen (1), screen with aggressive rate control (2). +For VP9: default (0), screen (1), film (2). + @item ts-parameters Sets the temporal scalability configuration using a :-separated list of key=value pairs. For example, to specify temporal scalability parameters @@ -2268,8 +2273,6 @@ colorspaces: @end table @item row-mt @var{boolean} Enable row based multi-threading. -@item tune-content -Set content type: default (0), screen (1), film (2). @item corpus-complexity Corpus VBR mode is a variant of standard VBR where the complexity distribution midpoint is passed in rather than calculated for a specific clip or chunk. diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..c73c92d49b 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -164,6 +164,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1262,6 +1263,16 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif } #endif +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE +if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->tune_content >= 0) { + if (ctx->tune_content == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); + } + codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->tune_content); +} +#endif av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); @@ -1379,14 +1390,15 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, * @return AVERROR(ENOMEM) on coded frame queue data allocation error */ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, -struct FrameListData **frame_list, AVPacket *pkt_out) +struct FrameListData **frame_list, AVPacket *pkt_out, +int queue_only, int *frame_enc) { VPxContext *ctx = avctx->priv_data; const struct vpx_codec_cx_pkt *pkt; const void *iter = NULL; int size = 0; -if (!ctx->is_alpha && *frame_list) { +if (!queue_only && *frame_list) { struct FrameListData *cx_frame = *frame_list; /* return the leading frame if we've already begun queueing */ size = storeframe(avctx, cx_frame, NULL, pkt_out); @@ -1401,7 +1413,7 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, while (pkt = vpx_codec_get_cx_data(encoder, )) { switch (pkt->kind) { case VPX_CODEC_CX_FRAME_PKT: -if (!ctx->is_alpha && !size) { +if (!queue_only && !size) { struct FrameListData cx_frame; /* avoid storing the frame when the list is empty and we haven't yet @@ -1411,6 +1423,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, size = storeframe(avctx, _frame, NULL, pkt_out); if (size < 0) return size; +if (size > 0) +*frame_enc = 1; } else { struct FrameListData *cx_frame = av_malloc(sizeof(*cx_frame)); @@ -1430,6 +1444,8 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder, return AVERROR(ENOMEM); } memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); +if (pkt->data.frame.sz > 0) + *frame_enc = 1; coded_frame_add(frame_list, cx_frame); } break; @@ -1693,6 +1709,7 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt, vpx_svc_layer_id_t layer_id; int layer_id_valid = 0; unsigned long duration = 0;
Re: [FFmpeg-devel] [PATCH] libavcodec: add tune_content option also for VP8.
Please ignore this version of the patch. I'll send out v2 soon. Apologies for the noise. On Thu, Jan 25, 2024 at 6:13 PM Dariusz Marcinkiewicz wrote: > This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. > > Change authored by Erik Språng > > Signed-off-by: Dariusz Marcinkiewicz > --- > doc/encoders.texi | 7 +-- > libavcodec/libvpxenc.c | 35 ++- > 2 files changed, 39 insertions(+), 3 deletions(-) > > diff --git a/doc/encoders.texi b/doc/encoders.texi > index c9fe6d6143..2a9b38f62a 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -2186,6 +2186,11 @@ Enable error resiliency features. > Increase sharpness at the expense of lower PSNR. > The valid range is [0, 7]. > > +@item tune-content > +Set content type. > +For VP8: default (0), screen (1), screen with aggressive rate control (2). > +For VP9: default (0), screen (1), film (2). > + > @item ts-parameters > Sets the temporal scalability configuration using a :-separated list of > key=value pairs. For example, to specify temporal scalability parameters > @@ -2268,8 +2273,6 @@ colorspaces: > @end table > @item row-mt @var{boolean} > Enable row based multi-threading. > -@item tune-content > -Set content type: default (0), screen (1), film (2). > @item corpus-complexity > Corpus VBR mode is a variant of standard VBR where the complexity > distribution > midpoint is passed in rather than calculated for a specific clip or chunk. > diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c > index 80988a2608..c28cca40a2 100644 > --- a/libavcodec/libvpxenc.c > +++ b/libavcodec/libvpxenc.c > @@ -164,6 +164,7 @@ static const char *const ctlidstr[] = { > [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", > [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", > [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", > +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", > #if CONFIG_LIBVPX_VP9_ENCODER > [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", > [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", > @@ -1249,8 +1250,19 @@ static av_cold int vpx_init(AVCodecContext *avctx, > codecctl_int(avctx, VP9E_SET_ROW_MT, ctx->row_mt); > #endif > #ifdef VPX_CTRL_VP9E_SET_TUNE_CONTENT > -if (ctx->tune_content >= 0) > +if (ctx->tune_content >= 0 && avctx->codec_id == AV_CODEC_ID_VP9) > { > codecctl_int(avctx, VP9E_SET_TUNE_CONTENT, ctx->tune_content); > +} > +#endif > +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE > +if (ctx->tune_content >= 0 && avctx->codec_id == AV_CODEC_ID_VP8) > { > + if (ctx->tune_content == 2 && ctx->is_alpha) { > +av_log(avctx, AV_LOG_ERROR, > + "Transparency encoding with screen mode with > aggressive rate control not supported\n"); > +return AVERROR(EINVAL); > + } > + codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, > ctx->tune_content); > +} > #endif > #ifdef VPX_CTRL_VP9E_SET_TPL > if (ctx->tpl_model >= 0) > @@ -1857,6 +1869,21 @@ FF_ENABLE_DEPRECATION_WARNINGS > } > > coded_size = queue_frames(avctx, >encoder, > >coded_frame_list, pkt); > +if (avctx->codec_id == AV_CODEC_ID_VP8 && coded_size == 0 && > ctx->tune_content == 2) { > +// VP8 tuned for screen content with aggresive rate control - > returned > +// OK status code but produced no output, this indicates frame was > +// rolled back due to bitrate overshoot - try to encode it again. > +av_log(avctx, AV_LOG_VERBOSE, > + "Attempting to reencode dropped VP8 screencast frame."); > +res = vpx_codec_encode(>encoder, rawimg, timestamp, > + avctx->ticks_per_frame, flags, > ctx->deadline); > +if (res != VPX_CODEC_OK) { > +log_encoder_error(avctx, "Error encoding frame"); > +return AVERROR_INVALIDDATA; > +} > +coded_size = queue_frames(avctx, >encoder, > >coded_frame_list, pkt); > +} > + > if (ctx->is_alpha) { > queue_frames(avctx, >encoder_alpha, > >alpha_coded_frame_list, NULL); > > @@ -1946,6 +1973,12 @@ static const AVOption vp8_options[] = { > { "auto-alt-ref","Enable use of alternate reference " > "frames (2-pass only)", > OFFSET(auto_alt_ref),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, > { "cpu-used","Quality/Speed ratio modifier", > OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, > +{ "tune-content", "Tune content type", > OFFSET(tune_content),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, > "tune_content"}, > +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE > +{ "default", "Regular video content", > 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, > "tune_content"}, > +{ "screen",
[FFmpeg-devel] [PATCH] libavcodec: add tune_content option also for VP8.
This exposes VP8E_SET_SCREEN_CONTENT_MODE option from libvpx. Change authored by Erik Språng Signed-off-by: Dariusz Marcinkiewicz --- doc/encoders.texi | 7 +-- libavcodec/libvpxenc.c | 35 ++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9fe6d6143..2a9b38f62a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2186,6 +2186,11 @@ Enable error resiliency features. Increase sharpness at the expense of lower PSNR. The valid range is [0, 7]. +@item tune-content +Set content type. +For VP8: default (0), screen (1), screen with aggressive rate control (2). +For VP9: default (0), screen (1), film (2). + @item ts-parameters Sets the temporal scalability configuration using a :-separated list of key=value pairs. For example, to specify temporal scalability parameters @@ -2268,8 +2273,6 @@ colorspaces: @end table @item row-mt @var{boolean} Enable row based multi-threading. -@item tune-content -Set content type: default (0), screen (1), film (2). @item corpus-complexity Corpus VBR mode is a variant of standard VBR where the complexity distribution midpoint is passed in rather than calculated for a specific clip or chunk. diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 80988a2608..c28cca40a2 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -164,6 +164,7 @@ static const char *const ctlidstr[] = { [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", [VP8E_SET_TEMPORAL_LAYER_ID] = "VP8E_SET_TEMPORAL_LAYER_ID", +[VP8E_SET_SCREEN_CONTENT_MODE] = "VP8E_SET_SCREEN_CONTENT_MODE", #if CONFIG_LIBVPX_VP9_ENCODER [VP9E_SET_LOSSLESS]= "VP9E_SET_LOSSLESS", [VP9E_SET_TILE_COLUMNS]= "VP9E_SET_TILE_COLUMNS", @@ -1249,8 +1250,19 @@ static av_cold int vpx_init(AVCodecContext *avctx, codecctl_int(avctx, VP9E_SET_ROW_MT, ctx->row_mt); #endif #ifdef VPX_CTRL_VP9E_SET_TUNE_CONTENT -if (ctx->tune_content >= 0) +if (ctx->tune_content >= 0 && avctx->codec_id == AV_CODEC_ID_VP9) { codecctl_int(avctx, VP9E_SET_TUNE_CONTENT, ctx->tune_content); +} +#endif +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE +if (ctx->tune_content >= 0 && avctx->codec_id == AV_CODEC_ID_VP8) { + if (ctx->tune_content == 2 && ctx->is_alpha) { +av_log(avctx, AV_LOG_ERROR, + "Transparency encoding with screen mode with aggressive rate control not supported\n"); +return AVERROR(EINVAL); + } + codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->tune_content); +} #endif #ifdef VPX_CTRL_VP9E_SET_TPL if (ctx->tpl_model >= 0) @@ -1857,6 +1869,21 @@ FF_ENABLE_DEPRECATION_WARNINGS } coded_size = queue_frames(avctx, >encoder, >coded_frame_list, pkt); +if (avctx->codec_id == AV_CODEC_ID_VP8 && coded_size == 0 && ctx->tune_content == 2) { +// VP8 tuned for screen content with aggresive rate control - returned +// OK status code but produced no output, this indicates frame was +// rolled back due to bitrate overshoot - try to encode it again. +av_log(avctx, AV_LOG_VERBOSE, + "Attempting to reencode dropped VP8 screencast frame."); +res = vpx_codec_encode(>encoder, rawimg, timestamp, + avctx->ticks_per_frame, flags, ctx->deadline); +if (res != VPX_CODEC_OK) { +log_encoder_error(avctx, "Error encoding frame"); +return AVERROR_INVALIDDATA; +} +coded_size = queue_frames(avctx, >encoder, >coded_frame_list, pkt); +} + if (ctx->is_alpha) { queue_frames(avctx, >encoder_alpha, >alpha_coded_frame_list, NULL); @@ -1946,6 +1973,12 @@ static const AVOption vp8_options[] = { { "auto-alt-ref","Enable use of alternate reference " "frames (2-pass only)", OFFSET(auto_alt_ref),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, { "cpu-used","Quality/Speed ratio modifier", OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, +{ "tune-content", "Tune content type", OFFSET(tune_content),AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, "tune_content"}, +#ifdef VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE +{ "default", "Regular video content", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "tune_content"}, +{ "screen", "Screen content mode on", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "tune_content"}, +{ "screen-rate-control", "Screen content mode with aggressive rate control", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE,