This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 8885116f4d avcodec/liboapvenc: derive and validate APV profile from 
pixel format
8885116f4d is described below

commit 8885116f4dbe10527d4e7a14dc691b07e3915d55
Author:     Soham Kute <[email protected]>
AuthorDate: Sat Apr 18 14:24:28 2026 +0530
Commit:     michaelni <[email protected]>
CommitDate: Mon May 25 23:12:05 2026 +0000

    avcodec/liboapvenc: derive and validate APV profile from pixel format
---
 libavcodec/liboapvenc.c | 152 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 134 insertions(+), 18 deletions(-)

diff --git a/libavcodec/liboapvenc.c b/libavcodec/liboapvenc.c
index 84bd175ef6..2b4da37b7d 100644
--- a/libavcodec/liboapvenc.c
+++ b/libavcodec/liboapvenc.c
@@ -59,8 +59,6 @@ typedef struct ApvEncContext {
 
     oapv_frms_t ifrms;      // frames for input
 
-    int num_frames;         // number of frames in an access unit
-
     int preset_id;          // preset of apv ( fastest, fast, medium, slow, 
placebo)
 
     int qp;                 // quantization parameter (QP) [0,63]
@@ -129,6 +127,121 @@ static inline int get_color_format(enum AVPixelFormat 
pix_fmt)
     return cf;
 }
 
+static inline int get_chroma_format_idc(enum AVPixelFormat pix_fmt)
+{
+    int cfi = -1;
+
+    switch (pix_fmt) {
+    case AV_PIX_FMT_GRAY10:
+        cfi = APV_CHROMA_FORMAT_400;
+        break;
+    case AV_PIX_FMT_YUV422P10:
+    case AV_PIX_FMT_YUV422P12:
+        cfi = APV_CHROMA_FORMAT_422;
+        break;
+    case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV444P12:
+        cfi = APV_CHROMA_FORMAT_444;
+        break;
+    case AV_PIX_FMT_YUVA444P10:
+    case AV_PIX_FMT_YUVA444P12:
+        cfi = APV_CHROMA_FORMAT_4444;
+        break;
+    default:
+        av_assert0(cfi >= 0);
+    }
+
+    return cfi;
+}
+
+static inline int get_min_profile(enum AVPixelFormat pix_fmt)
+{
+    int profile = AV_PROFILE_UNKNOWN;
+
+    switch (pix_fmt) {
+    case AV_PIX_FMT_GRAY10:
+        profile = AV_PROFILE_APV_400_10;
+        break;
+    case AV_PIX_FMT_YUV422P10:
+        profile = AV_PROFILE_APV_422_10;
+        break;
+    case AV_PIX_FMT_YUV422P12:
+        profile = AV_PROFILE_APV_422_12;
+        break;
+    case AV_PIX_FMT_YUV444P10:
+        profile = AV_PROFILE_APV_444_10;
+        break;
+    case AV_PIX_FMT_YUV444P12:
+        profile = AV_PROFILE_APV_444_12;
+        break;
+    case AV_PIX_FMT_YUVA444P10:
+        profile = AV_PROFILE_APV_4444_10;
+        break;
+    case AV_PIX_FMT_YUVA444P12:
+        profile = AV_PROFILE_APV_4444_12;
+        break;
+    default:
+        av_assert0(profile != AV_PROFILE_UNKNOWN);
+    }
+
+    return profile;
+}
+
+static int profile_is_compatible(enum AVPixelFormat pix_fmt, int profile)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    const int chroma_format_idc = get_chroma_format_idc(pix_fmt);
+    const int bit_depth = desc->comp[0].depth;
+
+    av_assert0(desc);
+
+    switch (profile) {
+    case AV_PROFILE_APV_422_10:
+        return chroma_format_idc == APV_CHROMA_FORMAT_422 && bit_depth == 10;
+    case AV_PROFILE_APV_422_12:
+        return chroma_format_idc == APV_CHROMA_FORMAT_422 &&
+               bit_depth >= 10 && bit_depth <= 12;
+    case AV_PROFILE_APV_444_10:
+        return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
+               chroma_format_idc <= APV_CHROMA_FORMAT_444 &&
+               bit_depth == 10;
+    case AV_PROFILE_APV_444_12:
+        return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
+               chroma_format_idc <= APV_CHROMA_FORMAT_444 &&
+               bit_depth >= 10 && bit_depth <= 12;
+    case AV_PROFILE_APV_4444_10:
+        return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
+               chroma_format_idc <= APV_CHROMA_FORMAT_4444 &&
+               bit_depth == 10;
+    case AV_PROFILE_APV_4444_12:
+        return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
+               chroma_format_idc <= APV_CHROMA_FORMAT_4444 &&
+               bit_depth >= 10 && bit_depth <= 12;
+    case AV_PROFILE_APV_400_10:
+        return chroma_format_idc == APV_CHROMA_FORMAT_400 && bit_depth == 10;
+    default:
+        return 0;
+    }
+}
+
+static int validate_profile(AVCodecContext *avctx, int profile)
+{
+    const int minimum = get_min_profile(avctx->pix_fmt);
+    const char *profile_name = av_get_profile_name(avctx->codec, profile);
+    const char *minimum_name = av_get_profile_name(avctx->codec, minimum);
+
+    if (!profile_is_compatible(avctx->pix_fmt, profile)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Profile %s (%d) is incompatible with pixel format %s; minimum 
compatible profile is %s (%d)\n",
+               profile_name ? profile_name : "unknown", profile,
+               av_get_pix_fmt_name(avctx->pix_fmt),
+               minimum_name ? minimum_name : "unknown", minimum);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
 static oapv_imgb_t *apv_imgb_create(AVCodecContext *avctx)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
@@ -180,22 +293,12 @@ fail:
 }
 
 /**
- * The function returns a pointer to the object of the oapve_cdesc_t type.
- * oapve_cdesc_t contains all encoder parameters that should be initialized 
before the encoder is used.
+ * Populate the liboapv configuration from AVCodecContext and encoder options.
  *
- * The field values of the oapve_cdesc_t structure are populated based on:
- * - the corresponding field values of the AvCodecConetxt structure,
- * - the apv encoder specific option values,
- *
- * The order of processing input data and populating the apve_cdsc structure
- * 1) first, the fields of the AVCodecContext structure corresponding to the 
provided input options are processed,
- *    (i.e -pix_fmt yuv422p -s:v 1920x1080 -r 30 -profile:v 0)
- * 2) then apve-specific options added as AVOption to the apv AVCodec 
implementation
- *    (i.e -preset 0)
- *
- * Keep in mind that, there are options that can be set in different ways.
- * In this case, please follow the above-mentioned order of processing.
- * The most recent assignments overwrite the previous values.
+ * AVCodecContext fields are applied first, followed by liboapv private options
+ * and finally oapv-params. The APV profile defaults to the minimum profile
+ * implied by pix_fmt, and later overrides must remain compatible with that
+ * pixel format.
  *
  * @param[in] avctx codec context (AVCodecContext)
  * @param[out] cdsc contains all APV encoder encoder parameters that should be 
initialized before the encoder is use
@@ -228,6 +331,13 @@ static int get_conf(AVCodecContext *avctx, oapve_cdesc_t 
*cdsc)
         cdsc->param[FRM_IDX].fps_den = avctx->time_base.num;
     }
 
+    cdsc->param[FRM_IDX].profile_idc = get_min_profile(avctx->pix_fmt);
+    if (avctx->profile != AV_PROFILE_UNKNOWN) {
+        ret = validate_profile(avctx, avctx->profile);
+        if (ret < 0)
+            return ret;
+        cdsc->param[FRM_IDX].profile_idc = avctx->profile;
+    }
     cdsc->param[FRM_IDX].preset = apv->preset_id;
     cdsc->param[FRM_IDX].qp = apv->qp;
     if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > 
INT_MAX) {
@@ -275,6 +385,12 @@ static int get_conf(AVCodecContext *avctx, oapve_cdesc_t 
*cdsc)
             av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", 
en->key, en->value);
     }
 
+    ret = validate_profile(avctx, cdsc->param[FRM_IDX].profile_idc);
+    if (ret < 0)
+        return ret;
+
+    avctx->profile = cdsc->param[FRM_IDX].profile_idc;
+
     return 0;
 }
 
@@ -426,7 +542,7 @@ static av_cold int liboapve_close(AVCodecContext *avctx)
 {
     ApvEncContext *apv = avctx->priv_data;
 
-    for (int i = 0; i < apv->num_frames; i++) {
+    for (int i = 0; i < apv->ifrms.num_frms; i++) {
         if (apv->ifrms.frm[i].imgb != NULL)
             apv->ifrms.frm[i].imgb->release(apv->ifrms.frm[i].imgb);
         apv->ifrms.frm[i].imgb = NULL;

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to