tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

libaomenc-svc.patch (6806B)


      1 diff --git a/media/ffvpx/libavcodec/libaomenc.c b/media/ffvpx/libavcodec/libaomenc.c
      2 index 0f7571ee7a1ba..a116989b1f4bc 100644
      3 --- a/media/ffvpx/libavcodec/libaomenc.c
      4 +++ b/media/ffvpx/libavcodec/libaomenc.c
      5 @@ -30,6 +30,7 @@
      6 #include <aom/aomcx.h>
      7 
      8 #include "libavutil/avassert.h"
      9 +#include "libavutil/avstring.h"
     10 #include "libavutil/base64.h"
     11 #include "libavutil/common.h"
     12 #include "libavutil/cpu.h"
     13 @@ -137,6 +138,7 @@ typedef struct AOMEncoderContext {
     14     int enable_diff_wtd_comp;
     15     int enable_dist_wtd_comp;
     16     int enable_dual_filter;
     17 +    AVDictionary *svc_parameters;
     18     AVDictionary *aom_params;
     19 } AOMContext;
     20 
     21 @@ -201,6 +203,7 @@ static const char *const ctlidstr[] = {
     22     [AV1E_GET_TARGET_SEQ_LEVEL_IDX]     = "AV1E_GET_TARGET_SEQ_LEVEL_IDX",
     23 #endif
     24     [AV1_GET_NEW_FRAME_IMAGE]           = "AV1_GET_NEW_FRAME_IMAGE",
     25 +    [AV1E_SET_SVC_PARAMS]               = "AV1E_SET_SVC_PARAMS",
     26 };
     27 
     28 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
     29 @@ -382,6 +385,31 @@ static av_cold int codecctl_imgp(AVCodecContext *avctx,
     30     return 0;
     31 }
     32 
     33 +static av_cold int codecctl_svcp(AVCodecContext *avctx,
     34 +#ifdef UENUM1BYTE
     35 +                                 aome_enc_control_id id,
     36 +#else
     37 +                                 enum aome_enc_control_id id,
     38 +#endif
     39 +                                 aom_svc_params_t *svc_params)
     40 +{
     41 +    AOMContext *ctx = avctx->priv_data;
     42 +    char buf[80];
     43 +    int res;
     44 +
     45 +    snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
     46 +
     47 +    res = aom_codec_control(&ctx->encoder, id, svc_params);
     48 +    if (res != AOM_CODEC_OK) {
     49 +        snprintf(buf, sizeof(buf), "Failed to get %s codec control",
     50 +                 ctlidstr[id]);
     51 +        log_encoder_error(avctx, buf);
     52 +        return AVERROR(EINVAL);
     53 +    }
     54 +
     55 +    return 0;
     56 +}
     57 +
     58 static av_cold int aom_free(AVCodecContext *avctx)
     59 {
     60     AOMContext *ctx = avctx->priv_data;
     61 @@ -428,6 +456,18 @@ static av_cold int aom_free(AVCodecContext *avctx)
     62     return 0;
     63 }
     64 
     65 +static void aom_svc_parse_int_array(int *dest, char *value, int max_entries)
     66 +{
     67 +    int dest_idx = 0;
     68 +    char *saveptr = NULL;
     69 +    char *token = av_strtok(value, ",", &saveptr);
     70 +
     71 +    while (token && dest_idx < max_entries) {
     72 +        dest[dest_idx++] = strtoul(token, NULL, 10);
     73 +        token = av_strtok(NULL, ",", &saveptr);
     74 +    }
     75 +}
     76 +
     77 static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
     78                        struct aom_codec_enc_cfg *enccfg, aom_codec_flags_t *flags,
     79                        aom_img_fmt_t *img_fmt)
     80 @@ -968,6 +1008,41 @@ static av_cold int aom_init(AVCodecContext *avctx,
     81     if (ctx->enable_intrabc >= 0)
     82         codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc);
     83 
     84 +    if (enccfg.rc_end_usage == AOM_CBR) {
     85 +        aom_svc_params_t svc_params = {};
     86 +        svc_params.framerate_factor[0] = 1;
     87 +        svc_params.number_spatial_layers = 1;
     88 +        svc_params.number_temporal_layers = 1;
     89 +
     90 +        AVDictionaryEntry *en = NULL;
     91 +        while ((en = av_dict_get(ctx->svc_parameters, "", en, AV_DICT_IGNORE_SUFFIX))) {
     92 +            if (!strlen(en->value))
     93 +                return AVERROR(EINVAL);
     94 +
     95 +            if (!strcmp(en->key, "number_spatial_layers"))
     96 +                svc_params.number_spatial_layers = strtoul(en->value, NULL, 10);
     97 +            else if (!strcmp(en->key, "number_temporal_layers"))
     98 +                svc_params.number_temporal_layers = strtoul(en->value, NULL, 10);
     99 +            else if (!strcmp(en->key, "max_quantizers"))
    100 +                aom_svc_parse_int_array(svc_params.max_quantizers, en->value, AOM_MAX_LAYERS);
    101 +            else if (!strcmp(en->key, "min_quantizers"))
    102 +                aom_svc_parse_int_array(svc_params.min_quantizers, en->value, AOM_MAX_LAYERS);
    103 +            else if (!strcmp(en->key, "scaling_factor_num"))
    104 +                aom_svc_parse_int_array(svc_params.scaling_factor_num, en->value, AOM_MAX_SS_LAYERS);
    105 +            else if (!strcmp(en->key, "scaling_factor_den"))
    106 +                aom_svc_parse_int_array(svc_params.scaling_factor_den, en->value, AOM_MAX_SS_LAYERS);
    107 +            else if (!strcmp(en->key, "layer_target_bitrate"))
    108 +                aom_svc_parse_int_array(svc_params.layer_target_bitrate, en->value, AOM_MAX_LAYERS);
    109 +            else if (!strcmp(en->key, "framerate_factor"))
    110 +                aom_svc_parse_int_array(svc_params.framerate_factor, en->value, AOM_MAX_TS_LAYERS);
    111 +        }
    112 +
    113 +        res = codecctl_svcp(avctx, AV1E_SET_SVC_PARAMS, &svc_params);
    114 +        if (res < 0)
    115 +            return res;
    116 +    }
    117 +
    118 +
    119 #if AOM_ENCODER_ABI_VERSION >= 23
    120     {
    121         const AVDictionaryEntry *en = NULL;
    122 @@ -1310,6 +1385,25 @@ FF_ENABLE_DEPRECATION_WARNINGS
    123 
    124         if (frame->pict_type == AV_PICTURE_TYPE_I)
    125             flags |= AOM_EFLAG_FORCE_KF;
    126 +
    127 +        AVDictionaryEntry*  en = av_dict_get(frame->metadata, "temporal_id", NULL, 0);
    128 +        if (en) {
    129 +            aom_svc_layer_id_t layer_id = {};
    130 +            layer_id.temporal_layer_id = strtoul(en->value, NULL, 10);
    131 +            av_log(avctx, AV_LOG_DEBUG, "Frame pts % " PRId64 " temporal layer id %d",
    132 +                   frame->pts, layer_id.temporal_layer_id);
    133 +            if (!ctx->svc_parameters) {
    134 +                av_log(avctx, AV_LOG_WARNING,
    135 +                       "Temporal SVC not enabled, but temporal layer id received.");
    136 +            }
    137 +            res = aom_codec_control(&ctx->encoder, AV1E_SET_SVC_LAYER_ID, &layer_id);
    138 +            if (res != AOM_CODEC_OK) {
    139 +                av_log(avctx, AV_LOG_ERROR,
    140 +                       "Error setting temporal layer id %d on frame pts % " PRId64 "\n",
    141 +                       layer_id.temporal_layer_id, frame->pts);
    142 +                return res;
    143 +            }
    144 +        }
    145     }
    146 
    147     res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags);
    148 @@ -1538,6 +1632,7 @@ static const AVOption options[] = {
    149     { "enable-masked-comp",           "Enable masked compound",                            OFFSET(enable_masked_comp),           AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
    150     { "enable-interintra-comp",       "Enable interintra compound",                        OFFSET(enable_interintra_comp),       AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
    151     { "enable-smooth-interintra",     "Enable smooth interintra mode",                     OFFSET(enable_smooth_interintra),     AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
    152 +    { "svc-parameters", "SVC configuration using a :-separated list of key=value parameters (only applied in CBR mode)", OFFSET(svc_parameters), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE},
    153 #if AOM_ENCODER_ABI_VERSION >= 23
    154     { "aom-params",                   "Set libaom options using a :-separated list of key=value pairs", OFFSET(aom_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
    155 #endif