Re: [FFmpeg-devel] [PATCH v4] lavc/libvpxenc: add screen-content-mode option

2024-02-13 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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

2024-02-12 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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

2024-02-10 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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

2024-02-10 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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.

2024-02-08 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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

2024-02-08 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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.

2024-02-07 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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.

2024-01-31 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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.

2024-01-29 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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.

2024-01-25 Thread Dariusz Marcinkiewicz via ffmpeg-devel
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,