[FFmpeg-devel] [PATCH 02/10] hw_base_encode: move VAAPI SPS/PPS constructors to a shared file

Tong Wu wutong1208 at outlook.com
Wed Sep 4 17:09:21 EEST 2024


Lynne:
>Subject: [FFmpeg-devel] [PATCH 02/10] hw_base_encode: move VAAPI SPS/PPS
>constructors to a shared file
>
>---
> libavcodec/Makefile              |   2 +-
> libavcodec/hw_base_encode_h264.c | 265
>+++++++++++++++++++++++++++++++  libavcodec/hw_base_encode_h264.h |  53
>+++++++
> libavcodec/vaapi_encode_h264.c   | 262 +++---------------------------
> 4 files changed, 341 insertions(+), 241 deletions(-)  create mode 100644
>libavcodec/hw_base_encode_h264.c  create mode 100644
>libavcodec/hw_base_encode_h264.h
>
>diff --git a/libavcodec/Makefile b/libavcodec/Makefile index
>3b4b8681f5..2e53dd723a 100644
>--- a/libavcodec/Makefile
>+++ b/libavcodec/Makefile
>@@ -166,7 +166,7 @@ OBJS-$(CONFIG_STARTCODE)               += startcode.o
> OBJS-$(CONFIG_TEXTUREDSP)              += texturedsp.o
> OBJS-$(CONFIG_TEXTUREDSPENC)           += texturedspenc.o
> OBJS-$(CONFIG_TPELDSP)                 += tpeldsp.o
>-OBJS-$(CONFIG_VAAPI_ENCODE)            += vaapi_encode.o hw_base_encode.o
>+OBJS-$(CONFIG_VAAPI_ENCODE)            += vaapi_encode.o hw_base_encode.o
>hw_base_encode_h264.o
> OBJS-$(CONFIG_AV1_AMF_ENCODER)         += amfenc_av1.o
> OBJS-$(CONFIG_VC1DSP)                  += vc1dsp.o
> OBJS-$(CONFIG_VIDEODSP)                += videodsp.o
>diff --git a/libavcodec/hw_base_encode_h264.c
>b/libavcodec/hw_base_encode_h264.c
>new file mode 100644
>index 0000000000..5c3957cddb
>--- /dev/null
>+++ b/libavcodec/hw_base_encode_h264.c
>@@ -0,0 +1,265 @@
>+/*
>+ * This file is part of FFmpeg.
>+ *
>+ * FFmpeg is free software; you can redistribute it and/or
>+ * modify it under the terms of the GNU Lesser General Public
>+ * License as published by the Free Software Foundation; either
>+ * version 2.1 of the License, or (at your option) any later version.
>+ *
>+ * FFmpeg is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>+ * Lesser General Public License for more details.
>+ *
>+ * You should have received a copy of the GNU Lesser General Public
>+ * License along with FFmpeg; if not, write to the Free Software
>+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>+02110-1301 USA  */
>+
>+#include "hw_base_encode_h264.h"
>+
>+#include "h2645data.h"
>+#include "h264_levels.h"
>+
>+#include "libavutil/pixdesc.h"
>+
>+int ff_hw_base_encode_init_params_h264(FFHWBaseEncodeContext *base_ctx,
>+                                       AVCodecContext *avctx,
>+                                       FFHWBaseEncodeH264 *common,
>+                                       FFHWBaseEncodeH264Opts *opts) {
>+    H264RawSPS *sps = &common->raw_sps;
>+    H264RawPPS *pps = &common->raw_pps;
>+    const AVPixFmtDescriptor *desc;
>+    int bit_depth;
>+
>+    memset(sps, 0, sizeof(*sps));
>+    memset(pps, 0, sizeof(*pps));
>+
>+    desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
>+    av_assert0(desc);
>+    if (desc->nb_components == 1 || desc->log2_chroma_w != 1 || desc-
>>log2_chroma_h != 1) {
>+        av_log(avctx, AV_LOG_ERROR, "Chroma format of input pixel format "
>+                "%s is not supported.\n", desc->name);
>+        return AVERROR(EINVAL);
>+    }
>+    bit_depth = desc->comp[0].depth;
>+
>+    sps->nal_unit_header.nal_ref_idc   = 3;
>+    sps->nal_unit_header.nal_unit_type = H264_NAL_SPS;
>+
>+    sps->profile_idc = avctx->profile & 0xff;
>+
>+    if (avctx->profile == AV_PROFILE_H264_CONSTRAINED_BASELINE ||
>+        avctx->profile == AV_PROFILE_H264_MAIN)
>+        sps->constraint_set1_flag = 1;
>+
>+    if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
>AV_PROFILE_H264_HIGH_10)
>+        sps->constraint_set3_flag = base_ctx->gop_size == 1;
>+
>+    if (avctx->profile == AV_PROFILE_H264_MAIN ||
>+        avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
>AV_PROFILE_H264_HIGH_10) {
>+        sps->constraint_set4_flag = 1;
>+        sps->constraint_set5_flag = base_ctx->b_per_p == 0;
>+    }
>+
>+    if (base_ctx->gop_size == 1)
>+        common->dpb_frames = 0;
>+    else
>+        common->dpb_frames = 1 + base_ctx->max_b_depth;
>+
>+    if (avctx->level != AV_LEVEL_UNKNOWN) {
>+        sps->level_idc = avctx->level;
>+    } else {
>+        const H264LevelDescriptor *level;
>+        int framerate;
>+
>+        if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
>+            framerate = avctx->framerate.num / avctx->framerate.den;
>+        else
>+            framerate = 0;
>+
>+        level = ff_h264_guess_level(sps->profile_idc,
>+                                    opts->bit_rate,
>+                                    framerate,
>+                                    common->mb_width  * 16,
>+                                    common->mb_height * 16,
>+                                    common->dpb_frames);
>+        if (level) {
>+            av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
>+            if (level->constraint_set3_flag)
>+                sps->constraint_set3_flag = 1;
>+            sps->level_idc = level->level_idc;
>+        } else {
>+            av_log(avctx, AV_LOG_WARNING, "Stream will not conform "
>+                   "to any level: using level 6.2.\n");
>+            sps->level_idc = 62;
>+        }
>+    }
>+
>+    sps->seq_parameter_set_id = 0;
>+    sps->chroma_format_idc    = 1;
>+    sps->bit_depth_luma_minus8 = bit_depth - 8;
>+    sps->bit_depth_chroma_minus8 = bit_depth - 8;
>+
>+    sps->log2_max_frame_num_minus4 = 4;
>+    sps->pic_order_cnt_type        = base_ctx->max_b_depth ? 0 : 2;
>+    if (sps->pic_order_cnt_type == 0) {
>+        sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
>+    }
>+
>+    sps->max_num_ref_frames = common->dpb_frames;
>+
>+    sps->pic_width_in_mbs_minus1        = common->mb_width  - 1;
>+    sps->pic_height_in_map_units_minus1 = common->mb_height - 1;
>+
>+    sps->frame_mbs_only_flag = 1;
>+    sps->direct_8x8_inference_flag = 1;
>+
>+    if (avctx->width  != 16 * common->mb_width ||
>+        avctx->height != 16 * common->mb_height) {
>+        sps->frame_cropping_flag = 1;
>+
>+        sps->frame_crop_left_offset   = 0;
>+        sps->frame_crop_right_offset  =
>+            (16 * common->mb_width - avctx->width) / 2;
>+        sps->frame_crop_top_offset    = 0;
>+        sps->frame_crop_bottom_offset =
>+            (16 * common->mb_height - avctx->height) / 2;
>+    } else {
>+        sps->frame_cropping_flag = 0;
>+    }
>+
>+    sps->vui_parameters_present_flag = 1;
>+
>+    if (avctx->sample_aspect_ratio.num != 0 &&
>+        avctx->sample_aspect_ratio.den != 0) {
>+        int num, den, i;
>+        av_reduce(&num, &den, avctx->sample_aspect_ratio.num,
>+                  avctx->sample_aspect_ratio.den, 65535);
>+        for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) {
>+            if (num == ff_h2645_pixel_aspect[i].num &&
>+                den == ff_h2645_pixel_aspect[i].den) {
>+                sps->vui.aspect_ratio_idc = i;
>+                break;
>+            }
>+        }
>+        if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) {
>+            sps->vui.aspect_ratio_idc = 255;
>+            sps->vui.sar_width  = num;
>+            sps->vui.sar_height = den;
>+        }
>+        sps->vui.aspect_ratio_info_present_flag = 1;
>+    }
>+
>+    // Unspecified video format, from table E-2.
>+    sps->vui.video_format             = 5;
>+    sps->vui.video_full_range_flag    =
>+        avctx->color_range == AVCOL_RANGE_JPEG;
>+    sps->vui.colour_primaries         = avctx->color_primaries;
>+    sps->vui.transfer_characteristics = avctx->color_trc;
>+    sps->vui.matrix_coefficients      = avctx->colorspace;
>+    if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
>+        avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
>+        avctx->colorspace      != AVCOL_SPC_UNSPECIFIED)
>+        sps->vui.colour_description_present_flag = 1;
>+    if (avctx->color_range     != AVCOL_RANGE_UNSPECIFIED ||
>+        sps->vui.colour_description_present_flag)
>+        sps->vui.video_signal_type_present_flag = 1;
>+
>+    if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
>+        sps->vui.chroma_loc_info_present_flag = 1;
>+        sps->vui.chroma_sample_loc_type_top_field    =
>+        sps->vui.chroma_sample_loc_type_bottom_field =
>+            avctx->chroma_sample_location - 1;
>+    }
>+
>+    sps->vui.timing_info_present_flag = 1;
>+    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
>+        sps->vui.num_units_in_tick = avctx->framerate.den;
>+        sps->vui.time_scale        = 2 * avctx->framerate.num;
>+        sps->vui.fixed_frame_rate_flag = 1;
>+    } else {
>+        sps->vui.num_units_in_tick = avctx->time_base.num;
>+        sps->vui.time_scale        = 2 * avctx->time_base.den;
>+        sps->vui.fixed_frame_rate_flag = 0;
>+    }
>+
>+    if (opts->flags & FF_HW_H264_SEI_TIMING) {
>+        H264RawHRD *hrd = &sps->vui.nal_hrd_parameters;
>+        H264RawSEIBufferingPeriod *bp = &common->sei_buffering_period;
>+
>+        sps->vui.nal_hrd_parameters_present_flag = 1;
>+
>+        hrd->cpb_cnt_minus1 = 0;
>+
>+        // Try to scale these to a sensible range so that the
>+        // golomb encode of the value is not overlong.
>+        hrd->bit_rate_scale =
>+            av_clip_uintp2(av_log2(opts->bit_rate) - 15 - 6, 4);
>+        hrd->bit_rate_value_minus1[0] =
>+            (opts->bit_rate >> hrd->bit_rate_scale + 6) - 1;
>+
>+        hrd->cpb_size_scale =
>+            av_clip_uintp2(av_log2(opts->hrd_buffer_size) - 15 - 4, 4);
>+        hrd->cpb_size_value_minus1[0] =
>+            (opts->hrd_buffer_size >> hrd->cpb_size_scale + 4) - 1;
>+
>+        // CBR mode as defined for the HRD cannot be achieved without filler
>+        // data, so this flag cannot be set even with VAAPI CBR modes.
>+        hrd->cbr_flag[0] = 0;
>+
>+        hrd->initial_cpb_removal_delay_length_minus1 = 23;
>+        hrd->cpb_removal_delay_length_minus1         = 23;
>+        hrd->dpb_output_delay_length_minus1          = 7;
>+        hrd->time_offset_length                      = 0;
>+
>+        bp->seq_parameter_set_id = sps->seq_parameter_set_id;
>+
>+        // This calculation can easily overflow 32 bits.
>+        bp->nal.initial_cpb_removal_delay[0] = 90000 *
>+            (uint64_t)opts->initial_buffer_fullness /
>+            opts->hrd_buffer_size;
>+        bp->nal.initial_cpb_removal_delay_offset[0] = 0;
>+    } else {
>+        sps->vui.nal_hrd_parameters_present_flag = 0;
>+        sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag;
>+    }
>+
>+    sps->vui.bitstream_restriction_flag    = 1;
>+    sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
>+    sps->vui.log2_max_mv_length_horizontal = 15;
>+    sps->vui.log2_max_mv_length_vertical   = 15;
>+    sps->vui.max_num_reorder_frames        = base_ctx->max_b_depth;
>+    sps->vui.max_dec_frame_buffering       = base_ctx->max_b_depth + 1;
>+
>+    pps->nal_unit_header.nal_ref_idc = 3;
>+    pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
>+
>+    pps->pic_parameter_set_id = 0;
>+    pps->seq_parameter_set_id = 0;
>+
>+    pps->entropy_coding_mode_flag =
>+        !(sps->profile_idc == AV_PROFILE_H264_BASELINE ||
>+          sps->profile_idc == AV_PROFILE_H264_EXTENDED ||
>+          sps->profile_idc == AV_PROFILE_H264_CAVLC_444);
>+    if (!opts->cabac && pps->entropy_coding_mode_flag)
>+        pps->entropy_coding_mode_flag = 0;
>+
>+    pps->num_ref_idx_l0_default_active_minus1 = 0;
>+    pps->num_ref_idx_l1_default_active_minus1 = 0;
>+
>+    pps->pic_init_qp_minus26 = opts->fixed_qp_idr - 26;
>+
>+    if (sps->profile_idc == AV_PROFILE_H264_BASELINE ||
>+        sps->profile_idc == AV_PROFILE_H264_EXTENDED ||
>+        sps->profile_idc == AV_PROFILE_H264_MAIN) {
>+        pps->more_rbsp_data = 0;
>+    } else {
>+        pps->more_rbsp_data = 1;
>+
>+        pps->transform_8x8_mode_flag = 1;
>+    }
>+
>+    return 0;
>+}
>diff --git a/libavcodec/hw_base_encode_h264.h
>b/libavcodec/hw_base_encode_h264.h
>new file mode 100644
>index 0000000000..d1bae8f36f
>--- /dev/null
>+++ b/libavcodec/hw_base_encode_h264.h
>@@ -0,0 +1,53 @@
>+/*
>+ * This file is part of FFmpeg.
>+ *
>+ * FFmpeg is free software; you can redistribute it and/or
>+ * modify it under the terms of the GNU Lesser General Public
>+ * License as published by the Free Software Foundation; either
>+ * version 2.1 of the License, or (at your option) any later version.
>+ *
>+ * FFmpeg is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>+ * Lesser General Public License for more details.
>+ *
>+ * You should have received a copy of the GNU Lesser General Public
>+ * License along with FFmpeg; if not, write to the Free Software
>+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>+02110-1301 USA  */
>+
>+#ifndef AVCODEC_HW_BASE_ENCODE_H264_H
>+#define AVCODEC_HW_BASE_ENCODE_H264_H
>+
>+#include "hw_base_encode.h"
>+#include "cbs_h264.h"
>+
>+typedef struct FFHWBaseEncodeH264 {
>+    H264RawSPS raw_sps;
>+    H264RawPPS raw_pps;
>+    H264RawAUD raw_aud;
>+
>+    H264RawSEIBufferingPeriod sei_buffering_period;
>+
>+    int dpb_frames;
>+    int mb_width;
>+    int mb_height;
>+} FFHWBaseEncodeH264;
>+
>+typedef struct FFHWBaseEncodeH264Opts {
>+    int flags;
>+#define FF_HW_H264_SEI_TIMING (1 << 0)
>+
>+    int64_t bit_rate;
>+    int cabac;
>+    int fixed_qp_idr;
>+    uint64_t hrd_buffer_size;
>+    uint64_t initial_buffer_fullness;
>+} FFHWBaseEncodeH264Opts;
>+
>+int ff_hw_base_encode_init_params_h264(FFHWBaseEncodeContext *base_ctx,
>+                                       AVCodecContext *avctx,
>+                                       FFHWBaseEncodeH264 *common,
>+                                       FFHWBaseEncodeH264Opts *opts);
>+
>+#endif /* AVCODEC_HW_BASE_ENCODE_H264_H */
>diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
>index 35d3967766..443a569104 100644
>--- a/libavcodec/vaapi_encode_h264.c
>+++ b/libavcodec/vaapi_encode_h264.c
>@@ -33,6 +33,7 @@
> #include "cbs_h264.h"
> #include "codec_internal.h"
> #include "h264.h"
>+#include "hw_base_encode_h264.h"
> #include "h264_levels.h"
> #include "h2645data.h"
> #include "vaapi_encode.h"
>@@ -67,6 +68,7 @@ typedef struct VAAPIEncodeH264Picture {
>
> typedef struct VAAPIEncodeH264Context {
>     VAAPIEncodeContext common;
>+    FFHWBaseEncodeH264 units;
>
>     // User options.
>     int qp;
>@@ -85,15 +87,11 @@ typedef struct VAAPIEncodeH264Context {
>     int fixed_qp_p;
>     int fixed_qp_b;
>
>-    int dpb_frames;
>-
>     // Writer structures.
>     CodedBitstreamContext *cbc;
>     CodedBitstreamFragment current_access_unit;
>
>     H264RawAUD   raw_aud;
>-    H264RawSPS   raw_sps;
>-    H264RawPPS   raw_pps;
>     H264RawSlice raw_slice;
>
>     H264RawSEIBufferingPeriod      sei_buffering_period;
>@@ -168,11 +166,11 @@ static int
>vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx,
>         priv->aud_needed = 0;
>     }
>
>-    err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_sps);
>+    err = vaapi_encode_h264_add_nal(avctx, au, &priv->units.raw_sps);
>     if (err < 0)
>         goto fail;
>
>-    err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_pps);
>+    err = vaapi_encode_h264_add_nal(avctx, au, &priv->units.raw_pps);
>     if (err < 0)
>         goto fail;
>
>@@ -298,240 +296,24 @@ static int
>vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
>     FFHWBaseEncodeContext        *base_ctx = avctx->priv_data;
>     VAAPIEncodeContext                *ctx = avctx->priv_data;
>     VAAPIEncodeH264Context           *priv = avctx->priv_data;
>-    H264RawSPS                        *sps = &priv->raw_sps;
>-    H264RawPPS                        *pps = &priv->raw_pps;
>+    H264RawSPS                        *sps = &priv->units.raw_sps;
>+    H264RawPPS                        *pps = &priv->units.raw_pps;
>     VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
>     VAEncPictureParameterBufferH264  *vpic = ctx->codec_picture_params;
>-    const AVPixFmtDescriptor *desc;
>-    int bit_depth;
>-
>-    memset(sps, 0, sizeof(*sps));
>-    memset(pps, 0, sizeof(*pps));
>-
>-    desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
>-    av_assert0(desc);
>-    if (desc->nb_components == 1 || desc->log2_chroma_w != 1 || desc-
>>log2_chroma_h != 1) {
>-        av_log(avctx, AV_LOG_ERROR, "Chroma format of input pixel format "
>-                "%s is not supported.\n", desc->name);
>-        return AVERROR(EINVAL);
>-    }
>-    bit_depth = desc->comp[0].depth;
>-
>-    sps->nal_unit_header.nal_ref_idc   = 3;
>-    sps->nal_unit_header.nal_unit_type = H264_NAL_SPS;
>-
>-    sps->profile_idc = avctx->profile & 0xff;
>-
>-    if (avctx->profile == AV_PROFILE_H264_CONSTRAINED_BASELINE ||
>-        avctx->profile == AV_PROFILE_H264_MAIN)
>-        sps->constraint_set1_flag = 1;
>-
>-    if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
>AV_PROFILE_H264_HIGH_10)
>-        sps->constraint_set3_flag = base_ctx->gop_size == 1;
>-
>-    if (avctx->profile == AV_PROFILE_H264_MAIN ||
>-        avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
>AV_PROFILE_H264_HIGH_10) {
>-        sps->constraint_set4_flag = 1;
>-        sps->constraint_set5_flag = base_ctx->b_per_p == 0;
>-    }
>-
>-    if (base_ctx->gop_size == 1)
>-        priv->dpb_frames = 0;
>-    else
>-        priv->dpb_frames = 1 + base_ctx->max_b_depth;
>-
>-    if (avctx->level != AV_LEVEL_UNKNOWN) {
>-        sps->level_idc = avctx->level;
>-    } else {
>-        const H264LevelDescriptor *level;
>-        int framerate;
>-
>-        if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
>-            framerate = avctx->framerate.num / avctx->framerate.den;
>-        else
>-            framerate = 0;
>-
>-        level = ff_h264_guess_level(sps->profile_idc,
>-                                    avctx->bit_rate,
>-                                    framerate,
>-                                    priv->mb_width  * 16,
>-                                    priv->mb_height * 16,
>-                                    priv->dpb_frames);
>-        if (level) {
>-            av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
>-            if (level->constraint_set3_flag)
>-                sps->constraint_set3_flag = 1;
>-            sps->level_idc = level->level_idc;
>-        } else {
>-            av_log(avctx, AV_LOG_WARNING, "Stream will not conform "
>-                   "to any level: using level 6.2.\n");
>-            sps->level_idc = 62;
>-        }
>-    }
>-
>-    sps->seq_parameter_set_id = 0;
>-    sps->chroma_format_idc    = 1;
>-    sps->bit_depth_luma_minus8 = bit_depth - 8;
>-    sps->bit_depth_chroma_minus8 = bit_depth - 8;
>-
>-    sps->log2_max_frame_num_minus4 = 4;
>-    sps->pic_order_cnt_type        = base_ctx->max_b_depth ? 0 : 2;
>-    if (sps->pic_order_cnt_type == 0) {
>-        sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
>-    }
>-
>-    sps->max_num_ref_frames = priv->dpb_frames;
>-
>-    sps->pic_width_in_mbs_minus1        = priv->mb_width  - 1;
>-    sps->pic_height_in_map_units_minus1 = priv->mb_height - 1;
>-
>-    sps->frame_mbs_only_flag = 1;
>-    sps->direct_8x8_inference_flag = 1;
>-
>-    if (avctx->width  != 16 * priv->mb_width ||
>-        avctx->height != 16 * priv->mb_height) {
>-        sps->frame_cropping_flag = 1;
>-
>-        sps->frame_crop_left_offset   = 0;
>-        sps->frame_crop_right_offset  =
>-            (16 * priv->mb_width - avctx->width) / 2;
>-        sps->frame_crop_top_offset    = 0;
>-        sps->frame_crop_bottom_offset =
>-            (16 * priv->mb_height - avctx->height) / 2;
>-    } else {
>-        sps->frame_cropping_flag = 0;
>-    }
>-
>-    sps->vui_parameters_present_flag = 1;
>-
>-    if (avctx->sample_aspect_ratio.num != 0 &&
>-        avctx->sample_aspect_ratio.den != 0) {
>-        int num, den, i;
>-        av_reduce(&num, &den, avctx->sample_aspect_ratio.num,
>-                  avctx->sample_aspect_ratio.den, 65535);
>-        for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) {
>-            if (num == ff_h2645_pixel_aspect[i].num &&
>-                den == ff_h2645_pixel_aspect[i].den) {
>-                sps->vui.aspect_ratio_idc = i;
>-                break;
>-            }
>-        }
>-        if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) {
>-            sps->vui.aspect_ratio_idc = 255;
>-            sps->vui.sar_width  = num;
>-            sps->vui.sar_height = den;
>-        }
>-        sps->vui.aspect_ratio_info_present_flag = 1;
>-    }
>-
>-    // Unspecified video format, from table E-2.
>-    sps->vui.video_format             = 5;
>-    sps->vui.video_full_range_flag    =
>-        avctx->color_range == AVCOL_RANGE_JPEG;
>-    sps->vui.colour_primaries         = avctx->color_primaries;
>-    sps->vui.transfer_characteristics = avctx->color_trc;
>-    sps->vui.matrix_coefficients      = avctx->colorspace;
>-    if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
>-        avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
>-        avctx->colorspace      != AVCOL_SPC_UNSPECIFIED)
>-        sps->vui.colour_description_present_flag = 1;
>-    if (avctx->color_range     != AVCOL_RANGE_UNSPECIFIED ||
>-        sps->vui.colour_description_present_flag)
>-        sps->vui.video_signal_type_present_flag = 1;
>-
>-    if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
>-        sps->vui.chroma_loc_info_present_flag = 1;
>-        sps->vui.chroma_sample_loc_type_top_field    =
>-        sps->vui.chroma_sample_loc_type_bottom_field =
>-            avctx->chroma_sample_location - 1;
>-    }
>-
>-    sps->vui.timing_info_present_flag = 1;
>-    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
>-        sps->vui.num_units_in_tick = avctx->framerate.den;
>-        sps->vui.time_scale        = 2 * avctx->framerate.num;
>-        sps->vui.fixed_frame_rate_flag = 1;
>-    } else {
>-        sps->vui.num_units_in_tick = avctx->time_base.num;
>-        sps->vui.time_scale        = 2 * avctx->time_base.den;
>-        sps->vui.fixed_frame_rate_flag = 0;
>-    }
>-
>-    if (priv->sei & SEI_TIMING) {
>-        H264RawHRD *hrd = &sps->vui.nal_hrd_parameters;
>-        H264RawSEIBufferingPeriod *bp = &priv->sei_buffering_period;
>-
>-        sps->vui.nal_hrd_parameters_present_flag = 1;
>-
>-        hrd->cpb_cnt_minus1 = 0;
>-
>-        // Try to scale these to a sensible range so that the
>-        // golomb encode of the value is not overlong.
>-        hrd->bit_rate_scale =
>-            av_clip_uintp2(av_log2(ctx->va_bit_rate) - 15 - 6, 4);
>-        hrd->bit_rate_value_minus1[0] =
>-            (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1;
>-
>-        hrd->cpb_size_scale =
>-            av_clip_uintp2(av_log2(ctx->hrd_params.buffer_size) - 15 - 4, 4);
>-        hrd->cpb_size_value_minus1[0] =
>-            (ctx->hrd_params.buffer_size >> hrd->cpb_size_scale + 4) - 1;
>-
>-        // CBR mode as defined for the HRD cannot be achieved without filler
>-        // data, so this flag cannot be set even with VAAPI CBR modes.
>-        hrd->cbr_flag[0] = 0;
>
>-        hrd->initial_cpb_removal_delay_length_minus1 = 23;
>-        hrd->cpb_removal_delay_length_minus1         = 23;
>-        hrd->dpb_output_delay_length_minus1          = 7;
>-        hrd->time_offset_length                      = 0;
>-
>-        bp->seq_parameter_set_id = sps->seq_parameter_set_id;
>-
>-        // This calculation can easily overflow 32 bits.
>-        bp->nal.initial_cpb_removal_delay[0] = 90000 *
>-            (uint64_t)ctx->hrd_params.initial_buffer_fullness /
>-            ctx->hrd_params.buffer_size;
>-        bp->nal.initial_cpb_removal_delay_offset[0] = 0;
>-    } else {
>-        sps->vui.nal_hrd_parameters_present_flag = 0;
>-        sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag;
>-    }
>-
>-    sps->vui.bitstream_restriction_flag    = 1;
>-    sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
>-    sps->vui.log2_max_mv_length_horizontal = 15;
>-    sps->vui.log2_max_mv_length_vertical   = 15;
>-    sps->vui.max_num_reorder_frames        = base_ctx->max_b_depth;
>-    sps->vui.max_dec_frame_buffering       = base_ctx->max_b_depth + 1;
>-
>-    pps->nal_unit_header.nal_ref_idc = 3;
>-    pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
>-
>-    pps->pic_parameter_set_id = 0;
>-    pps->seq_parameter_set_id = 0;
>-
>-    pps->entropy_coding_mode_flag =
>-        !(sps->profile_idc == AV_PROFILE_H264_BASELINE ||
>-          sps->profile_idc == AV_PROFILE_H264_EXTENDED ||
>-          sps->profile_idc == AV_PROFILE_H264_CAVLC_444);
>-    if (!priv->coder && pps->entropy_coding_mode_flag)
>-        pps->entropy_coding_mode_flag = 0;
>-
>-    pps->num_ref_idx_l0_default_active_minus1 = 0;
>-    pps->num_ref_idx_l1_default_active_minus1 = 0;
>-
>-    pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26;
>-
>-    if (sps->profile_idc == AV_PROFILE_H264_BASELINE ||
>-        sps->profile_idc == AV_PROFILE_H264_EXTENDED ||
>-        sps->profile_idc == AV_PROFILE_H264_MAIN) {
>-        pps->more_rbsp_data = 0;
>-    } else {
>-        pps->more_rbsp_data = 1;
>+    FFHWBaseEncodeH264Opts unit_opts = {
>+        .flags = (priv->sei & SEI_TIMING) ? FF_HW_H264_SEI_TIMING : 0,
>+        .cabac = priv->coder,
>+        .hrd_buffer_size = ctx->hrd_params.buffer_size,
>+        .fixed_qp_idr = priv->fixed_qp_idr,
>+        .initial_buffer_fullness = ctx->hrd_params.initial_buffer_fullness,
>+        .bit_rate = ctx->va_bit_rate,
>+    };
>
>-        pps->transform_8x8_mode_flag = 1;
>-    }
>+    int err = ff_hw_base_encode_init_params_h264(base_ctx, avctx,
>+                                                 &priv->units, &unit_opts);
>+    if (err < 0)
>+        return err;
>
>     *vseq = (VAEncSequenceParameterBufferH264) {
>         .seq_parameter_set_id = sps->seq_parameter_set_id, @@ -660,7 +442,7
>@@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
>         }
>     }
>     hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame;
>-    if (priv->raw_sps.pic_order_cnt_type == 2) {
>+    if (priv->units.raw_sps.pic_order_cnt_type == 2) {
>         hpic->pic_order_cnt *= 2;
>     }
>
>@@ -870,8 +652,8 @@ static int
>vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>     VAAPIEncodePicture         *vaapi_pic = pic->priv;
>     VAAPIEncodeH264Picture          *hpic = pic->codec_priv;
>     FFHWBaseEncodePicture           *prev = pic->prev;
>-    H264RawSPS                       *sps = &priv->raw_sps;
>-    H264RawPPS                       *pps = &priv->raw_pps;
>+    H264RawSPS                       *sps = &priv->units.raw_sps;
>+    H264RawPPS                       *pps = &priv->units.raw_pps;
>     H264RawSliceHeader                *sh = &priv->raw_slice.header;
>     VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params;
>     VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; @@ -
>923,7 +705,7 @@ static int
>vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>                 ++keep;
>             }
>         }
>-        av_assert0(keep <= priv->dpb_frames);
>+        av_assert0(keep <= priv->units.dpb_frames);
>
>         if (discard == 0) {
>             sh->adaptive_ref_pic_marking_mode_flag = 0;
>--

Are you planning to move more codecs to shared file such as hevc? Since some flags are based on the query result of hardware specific API, d3d12 may not align with the constructors in shared file.


More information about the ffmpeg-devel mailing list