Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH v2 05/11] avcodec/dovi_rpu: add ff_dovi_configure()
Date: Tue, 9 Apr 2024 18:00:21 +0200
Message-ID: <GV1P250MB0737534C9191B5A752C803788F072@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <20240409125914.61149-6-ffmpeg@haasn.xyz>

Niklas Haas:
> From: Niklas Haas <git@haasn.dev>
> 
> We need to set up the configuration struct appropriately based on the
> codec type, colorspace metadata, and presence/absence of an EL (though,
> we currently don't support an EL).
> 
> When present, we use the signalled RPU data header to help infer (and
> validate) the right values.
> 
> Behavior can be controlled by a new DOVIContext.enable flag.
> ---
>  libavcodec/dovi_rpu.c | 176 ++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/dovi_rpu.h |  23 +++++-
>  2 files changed, 198 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
> index 4da711d763e..d3a284c150d 100644
> --- a/libavcodec/dovi_rpu.c
> +++ b/libavcodec/dovi_rpu.c
> @@ -144,6 +144,182 @@ static int guess_hevc_profile(const AVDOVIRpuDataHeader *hdr)
>      return 0; /* unknown */
>  }
>  
> +static struct {
> +    uint64_t pps; // maximum pixels per second
> +    int width; // maximum width
> +    int main; // maximum bitrate in main tier
> +    int high; // maximum bitrate in high tier
> +} dv_levels[] = {
> +     [1] = {1280*720*24,    1280,  20,  50},
> +     [2] = {1280*720*30,    1280,  20,  50},
> +     [3] = {1920*1080*24,   1920,  20,  70},
> +     [4] = {1920*1080*30,   2560,  20,  70},
> +     [5] = {1920*1080*60,   3840,  20,  70},
> +     [6] = {3840*2160*24,   3840,  25, 130},
> +     [7] = {3840*2160*30,   3840,  25, 130},
> +     [8] = {3840*2160*48,   3840,  40, 130},
> +     [9] = {3840*2160*60,   3840,  40, 130},
> +    [10] = {3840*2160*120,  3840,  60, 240},
> +    [11] = {3840*2160*120,  7680,  60, 240},
> +    [12] = {7680*4320*60,   7680, 120, 450},
> +    [13] = {7680*4320*120u, 7680, 240, 800},
> +};
> +
> +int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx)
> +{
> +    AVDOVIDecoderConfigurationRecord *cfg;
> +    const AVDOVIRpuDataHeader *hdr = NULL;
> +    const AVFrameSideData *sd;
> +    int dv_profile, dv_level, bl_compat_id;
> +    size_t cfg_size;
> +    uint64_t pps;
> +
> +    if (!s->enable)
> +        goto skip;
> +
> +    sd = av_frame_side_data_get(avctx->decoded_side_data,
> +                                avctx->nb_decoded_side_data, AV_FRAME_DATA_DOVI_METADATA);
> +
> +    if (sd)
> +        hdr = av_dovi_get_header((const AVDOVIMetadata *) sd->data);
> +
> +    if (s->enable == FF_DOVI_AUTOMATIC && !hdr)
> +        goto skip;
> +
> +    switch (avctx->codec_id) {
> +    case AV_CODEC_ID_AV1:  dv_profile = 10; break;
> +    case AV_CODEC_ID_H264: dv_profile = 9;  break;
> +    case AV_CODEC_ID_HEVC: dv_profile = hdr ? guess_hevc_profile(hdr) : 8; break;
> +    default:
> +        /* No other encoder should be calling this! */
> +        av_assert0(0);
> +        return AVERROR_BUG;
> +    }
> +
> +    if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
> +        if (dv_profile == 9) {
> +            if (avctx->pix_fmt != AV_PIX_FMT_YUV420P)
> +                dv_profile = 0;
> +        } else {
> +            if (avctx->pix_fmt != AV_PIX_FMT_YUV420P10)
> +                dv_profile = 0;
> +        }
> +    }
> +
> +    switch (dv_profile) {
> +    case 0: /* None */
> +        bl_compat_id = -1;
> +        break;
> +    case 4: /* HEVC with enhancement layer */
> +    case 7:
> +        if (s->enable > 0) {
> +            av_log(s->logctx, AV_LOG_ERROR, "Coding of Dolby Vision enhancement "
> +                   "layers is currently unsupported.");
> +            return AVERROR_PATCHWELCOME;
> +        } else {
> +            goto skip;
> +        }
> +    case 5: /* HEVC with proprietary IPTPQc2 */
> +        bl_compat_id = 0;
> +        break;
> +    case 10:
> +        /* FIXME: check for proper H.273 tags once those are added */
> +        if (hdr && hdr->bl_video_full_range_flag) {
> +            /* AV1 with proprietary IPTPQc2 */
> +            bl_compat_id = 0;
> +            break;
> +        }
> +        /* fall through */
> +    case 8: /* HEVC (or AV1) with BL compatibility */
> +        if (avctx->colorspace == AVCOL_SPC_BT2020_NCL &&
> +            avctx->color_primaries == AVCOL_PRI_BT2020 &&
> +            avctx->color_trc == AVCOL_TRC_SMPTE2084) {
> +            bl_compat_id = 1;
> +        } else if (avctx->colorspace == AVCOL_SPC_BT2020_NCL &&
> +                   avctx->color_primaries == AVCOL_PRI_BT2020 &&
> +                   avctx->color_trc == AVCOL_TRC_ARIB_STD_B67) {
> +            bl_compat_id = 4;
> +        } else if (avctx->colorspace == AVCOL_SPC_BT709 &&
> +                   avctx->color_primaries == AVCOL_PRI_BT709 &&
> +                   avctx->color_trc == AVCOL_TRC_BT709) {
> +            bl_compat_id = 2;
> +        } else {
> +            /* Not a valid colorspace combination */
> +            bl_compat_id = -1;
> +        }
> +    }
> +
> +    if (!dv_profile || bl_compat_id < 0) {
> +        if (s->enable > 0) {
> +            av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision enabled, but could "
> +                   "not determine profile and compaatibility mode. Double-check "
> +                   "colorspace and format settings for compatibility?\n");
> +            return AVERROR(EINVAL);
> +        }
> +        goto skip;
> +    }
> +
> +    pps = avctx->width * avctx->height;
> +    if (avctx->framerate.num) {
> +        pps = pps * avctx->framerate.num / avctx->framerate.den;
> +    } else {
> +        pps *= 25; /* sanity fallback */
> +    }
> +
> +    dv_level = 0;
> +    for (int i = 1; i < FF_ARRAY_ELEMS(dv_levels); i++) {
> +        if (pps > dv_levels[i].pps)
> +            continue;
> +        if (avctx->width > dv_levels[i].width)
> +            continue;
> +        /* In theory, we should also test the bitrate when known, and
> +         * distinguish between main and high tier. In practice, just ignore
> +         * the bitrate constraints and hope they work out. This would ideally
> +         * be handled by either the encoder or muxer directly. */
> +        dv_level = i;
> +        break;
> +    }
> +
> +    if (!dv_level) {
> +        if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
> +            av_log(s->logctx, AV_LOG_ERROR, "Coded PPS (%"PRIu64") and width (%d) "
> +                   "exceed Dolby Vision limitations\n", pps, avctx->width);
> +            return AVERROR(EINVAL);
> +        } else {
> +            av_log(s->logctx, AV_LOG_WARNING, "Coded PPS (%"PRIu64") and width (%d) "
> +                   "exceed Dolby Vision limitations. Ignoring, resulting file "
> +                   "may be non-conforming.\n", pps, avctx->width);
> +            dv_level = FF_ARRAY_ELEMS(dv_levels) - 1;
> +        }
> +    }
> +
> +    cfg = av_dovi_alloc(&cfg_size);
> +    if (!cfg)
> +        return AVERROR(ENOMEM);
> +
> +    if (!av_packet_side_data_add(&avctx->coded_side_data, &avctx->nb_coded_side_data,
> +                                 AV_PKT_DATA_DOVI_CONF, cfg, cfg_size, 0)) {
> +        av_free(cfg);
> +        return AVERROR(ENOMEM);
> +    }
> +
> +    cfg->dv_version_major = 1;
> +    cfg->dv_version_minor = 0;
> +    cfg->dv_profile = dv_profile;
> +    cfg->dv_level = dv_level;
> +    cfg->rpu_present_flag = 1;
> +    cfg->el_present_flag = 0;
> +    cfg->bl_present_flag = 1;
> +    cfg->dv_bl_signal_compatibility_id = bl_compat_id;
> +
> +    s->cfg = *cfg;
> +    return 0;
> +
> +skip:
> +    s->cfg = (AVDOVIDecoderConfigurationRecord) {0};
> +    return 0;
> +}
> +
>  static inline uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
>  {
>      uint64_t ipart;
> diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
> index 9a68e45bf1b..56395707369 100644
> --- a/libavcodec/dovi_rpu.h
> +++ b/libavcodec/dovi_rpu.h
> @@ -26,14 +26,25 @@
>  
>  #include "libavutil/dovi_meta.h"
>  #include "libavutil/frame.h"
> +#include "avcodec.h"
>  
>  #define DOVI_MAX_DM_ID 15
>  typedef struct DOVIContext {
>      void *logctx;
>  
> +    /**
> +     * Enable tri-state.
> +     *
> +     * For encoding, FF_DOVI_AUTOMATIC enables Dolby Vision only if
> +     * avctx->decoded_side_data contains an AVDOVIMetadata.
> +     */
> +#define FF_DOVI_AUTOMATIC -1
> +    int enable;
> +
>      /**
>       * Currently active dolby vision configuration, or {0} for none.
> -     * Set by the user when decoding.
> +     * Set by the user when decoding. Generated by ff_dovi_configure()
> +     * when encoding.
>       *
>       * Note: sizeof(cfg) is not part of the libavutil ABI, so users should
>       * never pass &cfg to any other library calls. This is included merely as
> @@ -96,4 +107,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
>   */
>  int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame);
>  
> +/**
> + * Configure the encoder for Dolby Vision encoding. Generates a configuration
> + * record in s->cfg, and attaches it to avctx->coded_side_data. Sets the correct
> + * profile and compatibility ID based on the tagged AVCodecContext colorspace
> + * metadata, and the correct level based on the resolution and tagged framerate.
> + *
> + * Returns 0 or a negative error code.
> + */
> +int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx);
> +
>  #endif /* AVCODEC_DOVI_RPU_H */

All of these encoder-only functions should be put into a file of their
own so that it is not built when not enabling these non-native encoders.

- Andreas

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2024-04-09 16:15 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-09 12:57 [FFmpeg-devel] [PATCH v2 00/11] avcodec: add Dolby Vision encoding Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 01/11] avcodec/dovi_rpu: store entire config record Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 02/11] avcodec/dovi_rpu: properly replace context header Niklas Haas
2024-04-09 15:36   ` Andreas Rheinhardt
2024-04-09 16:02     ` Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 03/11] avcodec/dovi_rpu: clarify error on missing RPU VDR Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 04/11] avcodec/dovi_rpu: clarify semantics of guess_profile() Niklas Haas
2024-04-09 15:37   ` Andreas Rheinhardt
2024-04-09 16:01     ` Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 05/11] avcodec/dovi_rpu: add ff_dovi_configure() Niklas Haas
2024-04-09 16:00   ` Andreas Rheinhardt [this message]
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 06/11] avcodec/dovi_rpu: make `enable` also affect decoding Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 07/11] avcodec/dovi_rpu: add ff_dovi_rpu_generate() Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 08/11] avformat/movenc: warn if dovi cfg ignored Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 09/11] avcodec/libaomenc: implement dolby vision coding Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 10/11] avcodec/libx265: " Niklas Haas
2024-04-09 12:57 ` [FFmpeg-devel] [PATCH v2 11/11] avcodec/libsvtav1: " Niklas Haas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=GV1P250MB0737534C9191B5A752C803788F072@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git