Re: [FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
On Fri, Nov 16, 2018 at 8:59 PM James Zern wrote: > > On Wed, Nov 14, 2018 at 12:56 PM Ard Oerlemans > wrote: > > > > This commit adds configuration options to libvpxenc.c that can be used to > > enable VP8 temporal scalability. It also adds a way to programmatically set > > the > > per-frame encoding flags which can be used to control usage and updates of > > reference frames while encoding with temporal scalability enabled. > > --- > > doc/encoders.texi | 28 +++ > > libavcodec/libvpxenc.c | 81 ++ > > 2 files changed, 109 insertions(+) > > > > lgtm. I'll submit this soon if there aren't any further comments. > applied, thanks for the patch. > > [...] > > +while (token && dest_idx < max_entries) > > +{ > > This should be joined with the previous line. I have a fix for it locally. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
On Wed, Nov 14, 2018 at 12:56 PM Ard Oerlemans wrote: > > This commit adds configuration options to libvpxenc.c that can be used to > enable VP8 temporal scalability. It also adds a way to programmatically set > the > per-frame encoding flags which can be used to control usage and updates of > reference frames while encoding with temporal scalability enabled. > --- > doc/encoders.texi | 28 +++ > libavcodec/libvpxenc.c | 81 ++ > 2 files changed, 109 insertions(+) > lgtm. I'll submit this soon if there aren't any further comments. > [...] > +while (token && dest_idx < max_entries) > +{ This should be joined with the previous line. I have a fix for it locally. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
This commit adds configuration options to libvpxenc.c that can be used to enable VP8 temporal scalability. It also adds a way to programmatically set the per-frame encoding flags which can be used to control usage and updates of reference frames while encoding with temporal scalability enabled. --- doc/encoders.texi | 28 +++ libavcodec/libvpxenc.c | 81 ++ 2 files changed, 109 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index c9464ca7b3..39c3830dd5 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1655,6 +1655,34 @@ Set number of frames to look ahead for frametype and ratecontrol. @item error-resilient Enable error resiliency features. +@item VP8-specific options +@table @option +@item ts-parameters +Sets the temporal scalability configuration using a :-separated list of +key=value pairs. For example, to specify temporal scalability parameters +with @code{ffmpeg}: +@example +ffmpeg -i INPUT -c:v libvpx -ts-parameters ts_number_layers=3:\ +ts_target_bitrate=25,50,100:ts_rate_decimator=4,2,1:\ +ts_periodicity=4:ts_layer_id=0,2,1,2 OUTPUT +@end example +Below is a brief explanation of each of the parameters, please +refer to @code{struct vpx_codec_enc_cfg} in @code{vpx/vpx_encoder.h} for more +details. +@table @option +@item ts_number_layers +Number of temporal coding layers. +@item ts_target_bitrate +Target bitrate for each temporal layer. +@item ts_rate_decimator +Frame rate decimation factor for each temporal layer. +@item ts_periodicity +Length of the sequence defining frame temporal layer membership. +@item ts_layer_id +Template defining the membership of frames to temporal layers. +@end table +@end table + @item VP9-specific options @table @option @item lossless diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index ad440a9c21..774fda457e 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -33,6 +33,7 @@ #include "libavutil/avassert.h" #include "libvpx.h" #include "profiles.h" +#include "libavutil/avstring.h" #include "libavutil/base64.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -98,6 +99,8 @@ typedef struct VPxEncoderContext { int rc_undershoot_pct; int rc_overshoot_pct; +char *vp8_ts_parameters; + // VP9-only int lossless; int tile_columns; @@ -169,6 +172,7 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, { int width = -30; int level = AV_LOG_DEBUG; +int i; av_log(avctx, level, "vpx_codec_enc_cfg\n"); av_log(avctx, level, "generic settings\n" @@ -208,6 +212,25 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, " %*s%u\n %*s%u\n", width, "rc_undershoot_pct:", cfg->rc_undershoot_pct, width, "rc_overshoot_pct:", cfg->rc_overshoot_pct); +av_log(avctx, level, "temporal layering settings\n" + " %*s%u\n", width, "ts_number_layers:", cfg->ts_number_layers); +av_log(avctx, level, + "\n %*s", width, "ts_target_bitrate:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_target_bitrate[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s", width, "ts_rate_decimator:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_rate_decimator[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s%u\n", width, "ts_periodicity:", cfg->ts_periodicity); +av_log(avctx, level, + "\n %*s", width, "ts_layer_id:"); +for (i = 0; i < VPX_TS_MAX_PERIODICITY; i++) +av_log(avctx, level, "%u ", cfg->ts_layer_id[i]); +av_log(avctx, level, "\n"); av_log(avctx, level, "decoder buffer model\n" " %*s%u\n %*s%u\n %*s%u\n", width, "rc_buf_sz:", cfg->rc_buf_sz, @@ -325,6 +348,40 @@ static av_cold int vpx_free(AVCodecContext *avctx) return 0; } +static void vp8_ts_parse_int_array(int *dest, char *value, size_t value_len, int max_entries) +{ +int dest_idx = 0; +char *saveptr = NULL; +char *token = av_strtok(value, ",", ); + +while (token && dest_idx < max_entries) +{ +dest[dest_idx++] = strtoul(token, NULL, 10); +token = av_strtok(NULL, ",", ); +} +} + +static int vp8_ts_param_parse(struct vpx_codec_enc_cfg *enccfg, char *key, char *value) +{ +size_t value_len = strlen(value); + +if (!value_len) +return -1; + +if (!strcmp(key, "ts_number_layers")) +enccfg->ts_number_layers = strtoul(value, , 10); +else if (!strcmp(key, "ts_target_bitrate")) +vp8_ts_parse_int_array(enccfg->ts_target_bitrate, value, value_len, VPX_TS_MAX_LAYERS); +else if (!strcmp(key, "ts_rate_decimator")) + vp8_ts_parse_int_array(enccfg->ts_rate_decimator, value, value_len, VPX_TS_MAX_LAYERS); +else if (!strcmp(key, "ts_periodicity")) +
Re: [FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
On Mon, Nov 12, 2018 at 10:37 AM Ard Oerlemans wrote: > > Thanks for the suggestion. I have updated the patch. > Try to keep the original patch message so it's easier to apply. > Ard > > --- > doc/encoders.texi | 28 +++ > libavcodec/libvpxenc.c | 79 ++ > 2 files changed, 107 insertions(+) > This looks OK, just some minor comments. > [...] > +static void vp8_ts_parse_int_array(int* dest, char *value, size_t value_len, > int max_entries) '*' is associated with the variable. > [...] > +{ > +int dest_idx = 0; > +char *value_end = value + value_len; > +while (value < value_end && dest_idx < max_entries) { > +dest[dest_idx] = strtoul(value, , 10); > +while (value < value_end && (*value == ',' || av_isspace(*value))) > +value++; Could this just be av_strtok? > [...] > @@ -1113,6 +1191,7 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket > *pkt, > static const AVOption vp8_options[] = { > COMMON_OPTIONS > { "cpu-used","Quality/Speed ratio modifier", > OFFSET(cpu_used),AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, > +{ "ts-parameters", "Temporal scaling configuration using a :-separated > list of key=value parameters", OFFSET(vp8_ts_parameters), AV_OPT_TYPE_STRING, > {.str=NULL}, 0, 0, VE}, This doesn't apply. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
Thanks for the suggestion. I have updated the patch. Ard --- doc/encoders.texi | 28 +++ libavcodec/libvpxenc.c | 79 ++ 2 files changed, 107 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 899faac49b..6ecd572ea3 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1654,6 +1654,34 @@ Set number of frames to look ahead for frametype and ratecontrol. @item error-resilient Enable error resiliency features. +@item VP8-specific options +@table @option +@item ts-parameters +Sets the temporal scalability configuration using a :-separated list of +key=value pairs. For example, to specify temporal scalability parameters +with @code{ffmpeg}: +@example +ffmpeg -i INPUT -c:v libvpx -ts-parameters ts_number_layers=3:\ +ts_target_bitrate=25,50,100:ts_rate_decimator=4,2,1:\ +ts_periodicity=4:ts_layer_id=0,2,1,2 OUTPUT +@end example +Below is a brief explanation of each of the parameters, please +refer to @code{struct vpx_codec_enc_cfg} in @code{vpx/vpx_encoder.h} for more +details. +@table @option +@item ts_number_layers +Number of temporal coding layers. +@item ts_target_bitrate +Target bitrate for each temporal layer. +@item ts_rate_decimator +Frame rate decimation factor for each temporal layer. +@item ts_periodicity +Length of the sequence defining frame temporal layer membership. +@item ts_layer_id +Template defining the membership of frames to temporal layers. +@end table +@end table + @item VP9-specific options @table @option @item lossless diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 09f7a88452..161f952d65 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -33,6 +33,7 @@ #include "libavutil/avassert.h" #include "libvpx.h" #include "profiles.h" +#include "libavutil/avstring.h" #include "libavutil/base64.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -98,6 +99,8 @@ typedef struct VPxEncoderContext { int rc_undershoot_pct; int rc_overshoot_pct; +char *vp8_ts_parameters; + // VP9-only int lossless; int tile_columns; @@ -165,6 +168,7 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, { int width = -30; int level = AV_LOG_DEBUG; +int i; av_log(avctx, level, "vpx_codec_enc_cfg\n"); av_log(avctx, level, "generic settings\n" @@ -204,6 +208,25 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, " %*s%u\n %*s%u\n", width, "rc_undershoot_pct:", cfg->rc_undershoot_pct, width, "rc_overshoot_pct:", cfg->rc_overshoot_pct); +av_log(avctx, level, "temporal layering settings\n" + " %*s%u\n", width, "ts_number_layers:", cfg->ts_number_layers); +av_log(avctx, level, + "\n %*s", width, "ts_target_bitrate:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_target_bitrate[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s", width, "ts_rate_decimator:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_rate_decimator[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s%u\n", width, "ts_periodicity:", cfg->ts_periodicity); +av_log(avctx, level, + "\n %*s", width, "ts_layer_id:"); +for (i = 0; i < VPX_TS_MAX_PERIODICITY; i++) +av_log(avctx, level, "%u ", cfg->ts_layer_id[i]); +av_log(avctx, level, "\n"); av_log(avctx, level, "decoder buffer model\n" " %*s%u\n %*s%u\n %*s%u\n", width, "rc_buf_sz:", cfg->rc_buf_sz, @@ -321,6 +344,39 @@ static av_cold int vpx_free(AVCodecContext *avctx) return 0; } +static void vp8_ts_parse_int_array(int* dest, char *value, size_t value_len, int max_entries) +{ +int dest_idx = 0; +char *value_end = value + value_len; +while (value < value_end && dest_idx < max_entries) { +dest[dest_idx] = strtoul(value, , 10); +while (value < value_end && (*value == ',' || av_isspace(*value))) +value++; +dest_idx++; +} +} + +static int vp8_ts_param_parse(struct vpx_codec_enc_cfg *enccfg, char *key, char *value) +{ +size_t value_len = strlen(value); + +if (!value_len) +return -1; + +if (!strcmp(key, "ts_number_layers")) +enccfg->ts_number_layers = strtoul(value, , 10); +else if (!strcmp(key, "ts_target_bitrate")) +vp8_ts_parse_int_array(enccfg->ts_target_bitrate, value, value_len, VPX_TS_MAX_LAYERS); +else if (!strcmp(key, "ts_rate_decimator")) + vp8_ts_parse_int_array(enccfg->ts_rate_decimator, value, value_len, VPX_TS_MAX_LAYERS); +else if (!strcmp(key, "ts_periodicity")) +enccfg->ts_periodicity = strtoul(value, , 10); +else if (!strcmp(key, "ts_layer_id")) +vp8_ts_parse_int_array(enccfg->ts_layer_id, value, value_len, VPX_TS_MAX_PERIODICITY); + +return
Re: [FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
2018-11-08 21:44 GMT+01:00, Ard Oerlemans : > +#if CONFIG_LIBVPX_VP8_ENCODER > +if (frame->metadata) { if (CONFIG_LIBVPX_VP8_ENCODER && frame->metadata) may be more inline with FFmpeg's code style. Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/libvpxenc: add VP8 temporal scalability configuration options
This commit adds configuration options to libvpxenc.c that can be used to enable VP8 temporal scalability. It also adds a way to programmatically set the per-frame encoding flags which can be used to control usage and updates of reference frames while encoding with temporal scalability enabled. --- doc/encoders.texi | 28 ++ libavcodec/libvpxenc.c | 85 ++ 2 files changed, 113 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 899faac49b..6ecd572ea3 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1654,6 +1654,34 @@ Set number of frames to look ahead for frametype and ratecontrol. @item error-resilient Enable error resiliency features. +@item VP8-specific options +@table @option +@item ts-parameters +Sets the temporal scalability configuration using a :-separated list of +key=value pairs. For example, to specify temporal scalability parameters +with @code{ffmpeg}: +@example +ffmpeg -i INPUT -c:v libvpx -ts-parameters ts_number_layers=3:\ +ts_target_bitrate=25,50,100:ts_rate_decimator=4,2,1:\ +ts_periodicity=4:ts_layer_id=0,2,1,2 OUTPUT +@end example +Below is a brief explanation of each of the parameters, please +refer to @code{struct vpx_codec_enc_cfg} in @code{vpx/vpx_encoder.h} for more +details. +@table @option +@item ts_number_layers +Number of temporal coding layers. +@item ts_target_bitrate +Target bitrate for each temporal layer. +@item ts_rate_decimator +Frame rate decimation factor for each temporal layer. +@item ts_periodicity +Length of the sequence defining frame temporal layer membership. +@item ts_layer_id +Template defining the membership of frames to temporal layers. +@end table +@end table + @item VP9-specific options @table @option @item lossless diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 09f7a88452..206f17f4cd 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -33,6 +33,7 @@ #include "libavutil/avassert.h" #include "libvpx.h" #include "profiles.h" +#include "libavutil/avstring.h" #include "libavutil/base64.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -98,6 +99,8 @@ typedef struct VPxEncoderContext { int rc_undershoot_pct; int rc_overshoot_pct; +char *vp8_ts_parameters; + // VP9-only int lossless; int tile_columns; @@ -165,6 +168,7 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, { int width = -30; int level = AV_LOG_DEBUG; +int i; av_log(avctx, level, "vpx_codec_enc_cfg\n"); av_log(avctx, level, "generic settings\n" @@ -204,6 +208,25 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx, " %*s%u\n %*s%u\n", width, "rc_undershoot_pct:", cfg->rc_undershoot_pct, width, "rc_overshoot_pct:", cfg->rc_overshoot_pct); +av_log(avctx, level, "temporal layering settings\n" + " %*s%u\n", width, "ts_number_layers:", cfg->ts_number_layers); +av_log(avctx, level, + "\n %*s", width, "ts_target_bitrate:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_target_bitrate[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s", width, "ts_rate_decimator:"); +for (i = 0; i < VPX_TS_MAX_LAYERS; i++) +av_log(avctx, level, "%u ", cfg->ts_rate_decimator[i]); +av_log(avctx, level, "\n"); +av_log(avctx, level, + "\n %*s%u\n", width, "ts_periodicity:", cfg->ts_periodicity); +av_log(avctx, level, + "\n %*s", width, "ts_layer_id:"); +for (i = 0; i < VPX_TS_MAX_PERIODICITY; i++) +av_log(avctx, level, "%u ", cfg->ts_layer_id[i]); +av_log(avctx, level, "\n"); av_log(avctx, level, "decoder buffer model\n" " %*s%u\n %*s%u\n %*s%u\n", width, "rc_buf_sz:", cfg->rc_buf_sz, @@ -321,6 +344,41 @@ static av_cold int vpx_free(AVCodecContext *avctx) return 0; } +#if CONFIG_LIBVPX_VP8_ENCODER +static void vp8_ts_parse_int_array(int* dest, char *value, size_t value_len, int max_entries) +{ +int dest_idx = 0; +char *value_end = value + value_len; +while (value < value_end && dest_idx < max_entries) { +dest[dest_idx] = strtoul(value, , 10); +while (value < value_end && (*value == ',' || av_isspace(*value))) +value++; +dest_idx++; +} +} + +static int vp8_ts_param_parse(struct vpx_codec_enc_cfg *enccfg, char *key, char *value) +{ +size_t value_len = strlen(value); + +if (!value_len) +return -1; + +if (!strcmp(key, "ts_number_layers")) +enccfg->ts_number_layers = strtoul(value, , 10); +else if (!strcmp(key, "ts_target_bitrate")) +vp8_ts_parse_int_array(enccfg->ts_target_bitrate, value, value_len, VPX_TS_MAX_LAYERS); +else if (!strcmp(key, "ts_rate_decimator")) + vp8_ts_parse_int_array(enccfg->ts_rate_decimator, value, value_len,