1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include <string.h> 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <va/va.h> 22cabdff1aSopenharmony_ci#include <va/va_enc_h264.h> 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 25cabdff1aSopenharmony_ci#include "libavutil/common.h" 26cabdff1aSopenharmony_ci#include "libavutil/internal.h" 27cabdff1aSopenharmony_ci#include "libavutil/opt.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "avcodec.h" 30cabdff1aSopenharmony_ci#include "cbs.h" 31cabdff1aSopenharmony_ci#include "cbs_h264.h" 32cabdff1aSopenharmony_ci#include "codec_internal.h" 33cabdff1aSopenharmony_ci#include "h264.h" 34cabdff1aSopenharmony_ci#include "h264_levels.h" 35cabdff1aSopenharmony_ci#include "h264_sei.h" 36cabdff1aSopenharmony_ci#include "vaapi_encode.h" 37cabdff1aSopenharmony_ci#include "version.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_cienum { 40cabdff1aSopenharmony_ci SEI_TIMING = 0x01, 41cabdff1aSopenharmony_ci SEI_IDENTIFIER = 0x02, 42cabdff1aSopenharmony_ci SEI_RECOVERY_POINT = 0x04, 43cabdff1aSopenharmony_ci}; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci// Random (version 4) ISO 11578 UUID. 46cabdff1aSopenharmony_cistatic const uint8_t vaapi_encode_h264_sei_identifier_uuid[16] = { 47cabdff1aSopenharmony_ci 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf, 48cabdff1aSopenharmony_ci 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d, 49cabdff1aSopenharmony_ci}; 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_citypedef struct VAAPIEncodeH264Picture { 52cabdff1aSopenharmony_ci int frame_num; 53cabdff1aSopenharmony_ci int pic_order_cnt; 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci int64_t last_idr_frame; 56cabdff1aSopenharmony_ci uint16_t idr_pic_id; 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci int primary_pic_type; 59cabdff1aSopenharmony_ci int slice_type; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci int cpb_delay; 62cabdff1aSopenharmony_ci int dpb_delay; 63cabdff1aSopenharmony_ci} VAAPIEncodeH264Picture; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_citypedef struct VAAPIEncodeH264Context { 66cabdff1aSopenharmony_ci VAAPIEncodeContext common; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci // User options. 69cabdff1aSopenharmony_ci int qp; 70cabdff1aSopenharmony_ci int quality; 71cabdff1aSopenharmony_ci int coder; 72cabdff1aSopenharmony_ci int aud; 73cabdff1aSopenharmony_ci int sei; 74cabdff1aSopenharmony_ci int profile; 75cabdff1aSopenharmony_ci int level; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci // Derived settings. 78cabdff1aSopenharmony_ci int mb_width; 79cabdff1aSopenharmony_ci int mb_height; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci int fixed_qp_idr; 82cabdff1aSopenharmony_ci int fixed_qp_p; 83cabdff1aSopenharmony_ci int fixed_qp_b; 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci int dpb_frames; 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci // Writer structures. 88cabdff1aSopenharmony_ci CodedBitstreamContext *cbc; 89cabdff1aSopenharmony_ci CodedBitstreamFragment current_access_unit; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci H264RawAUD raw_aud; 92cabdff1aSopenharmony_ci H264RawSPS raw_sps; 93cabdff1aSopenharmony_ci H264RawPPS raw_pps; 94cabdff1aSopenharmony_ci H264RawSlice raw_slice; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci H264RawSEIBufferingPeriod sei_buffering_period; 97cabdff1aSopenharmony_ci H264RawSEIPicTiming sei_pic_timing; 98cabdff1aSopenharmony_ci H264RawSEIRecoveryPoint sei_recovery_point; 99cabdff1aSopenharmony_ci SEIRawUserDataUnregistered sei_identifier; 100cabdff1aSopenharmony_ci char *sei_identifier_string; 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci int aud_needed; 103cabdff1aSopenharmony_ci int sei_needed; 104cabdff1aSopenharmony_ci int sei_cbr_workaround_needed; 105cabdff1aSopenharmony_ci} VAAPIEncodeH264Context; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_cistatic int vaapi_encode_h264_write_access_unit(AVCodecContext *avctx, 109cabdff1aSopenharmony_ci char *data, size_t *data_len, 110cabdff1aSopenharmony_ci CodedBitstreamFragment *au) 111cabdff1aSopenharmony_ci{ 112cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 113cabdff1aSopenharmony_ci int err; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci err = ff_cbs_write_fragment_data(priv->cbc, au); 116cabdff1aSopenharmony_ci if (err < 0) { 117cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n"); 118cabdff1aSopenharmony_ci return err; 119cabdff1aSopenharmony_ci } 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (*data_len < 8 * au->data_size - au->data_bit_padding) { 122cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Access unit too large: " 123cabdff1aSopenharmony_ci "%zu < %zu.\n", *data_len, 124cabdff1aSopenharmony_ci 8 * au->data_size - au->data_bit_padding); 125cabdff1aSopenharmony_ci return AVERROR(ENOSPC); 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci memcpy(data, au->data, au->data_size); 129cabdff1aSopenharmony_ci *data_len = 8 * au->data_size - au->data_bit_padding; 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci return 0; 132cabdff1aSopenharmony_ci} 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_cistatic int vaapi_encode_h264_add_nal(AVCodecContext *avctx, 135cabdff1aSopenharmony_ci CodedBitstreamFragment *au, 136cabdff1aSopenharmony_ci void *nal_unit) 137cabdff1aSopenharmony_ci{ 138cabdff1aSopenharmony_ci H264RawNALUnitHeader *header = nal_unit; 139cabdff1aSopenharmony_ci int err; 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci err = ff_cbs_insert_unit_content(au, -1, 142cabdff1aSopenharmony_ci header->nal_unit_type, nal_unit, NULL); 143cabdff1aSopenharmony_ci if (err < 0) { 144cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " 145cabdff1aSopenharmony_ci "type = %d.\n", header->nal_unit_type); 146cabdff1aSopenharmony_ci return err; 147cabdff1aSopenharmony_ci } 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci return 0; 150cabdff1aSopenharmony_ci} 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_cistatic int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, 153cabdff1aSopenharmony_ci char *data, size_t *data_len) 154cabdff1aSopenharmony_ci{ 155cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 156cabdff1aSopenharmony_ci CodedBitstreamFragment *au = &priv->current_access_unit; 157cabdff1aSopenharmony_ci int err; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci if (priv->aud_needed) { 160cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 161cabdff1aSopenharmony_ci if (err < 0) 162cabdff1aSopenharmony_ci goto fail; 163cabdff1aSopenharmony_ci priv->aud_needed = 0; 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_sps); 167cabdff1aSopenharmony_ci if (err < 0) 168cabdff1aSopenharmony_ci goto fail; 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_pps); 171cabdff1aSopenharmony_ci if (err < 0) 172cabdff1aSopenharmony_ci goto fail; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 175cabdff1aSopenharmony_cifail: 176cabdff1aSopenharmony_ci ff_cbs_fragment_reset(au); 177cabdff1aSopenharmony_ci return err; 178cabdff1aSopenharmony_ci} 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_cistatic int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx, 181cabdff1aSopenharmony_ci VAAPIEncodePicture *pic, 182cabdff1aSopenharmony_ci VAAPIEncodeSlice *slice, 183cabdff1aSopenharmony_ci char *data, size_t *data_len) 184cabdff1aSopenharmony_ci{ 185cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 186cabdff1aSopenharmony_ci CodedBitstreamFragment *au = &priv->current_access_unit; 187cabdff1aSopenharmony_ci int err; 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_ci if (priv->aud_needed) { 190cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 191cabdff1aSopenharmony_ci if (err < 0) 192cabdff1aSopenharmony_ci goto fail; 193cabdff1aSopenharmony_ci priv->aud_needed = 0; 194cabdff1aSopenharmony_ci } 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_slice); 197cabdff1aSopenharmony_ci if (err < 0) 198cabdff1aSopenharmony_ci goto fail; 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 201cabdff1aSopenharmony_cifail: 202cabdff1aSopenharmony_ci ff_cbs_fragment_reset(au); 203cabdff1aSopenharmony_ci return err; 204cabdff1aSopenharmony_ci} 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_cistatic int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, 207cabdff1aSopenharmony_ci VAAPIEncodePicture *pic, 208cabdff1aSopenharmony_ci int index, int *type, 209cabdff1aSopenharmony_ci char *data, size_t *data_len) 210cabdff1aSopenharmony_ci{ 211cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 212cabdff1aSopenharmony_ci CodedBitstreamFragment *au = &priv->current_access_unit; 213cabdff1aSopenharmony_ci int err; 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci if (priv->sei_needed) { 216cabdff1aSopenharmony_ci if (priv->aud_needed) { 217cabdff1aSopenharmony_ci err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); 218cabdff1aSopenharmony_ci if (err < 0) 219cabdff1aSopenharmony_ci goto fail; 220cabdff1aSopenharmony_ci priv->aud_needed = 0; 221cabdff1aSopenharmony_ci } 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci if (priv->sei_needed & SEI_IDENTIFIER) { 224cabdff1aSopenharmony_ci err = ff_cbs_sei_add_message(priv->cbc, au, 1, 225cabdff1aSopenharmony_ci SEI_TYPE_USER_DATA_UNREGISTERED, 226cabdff1aSopenharmony_ci &priv->sei_identifier, NULL); 227cabdff1aSopenharmony_ci if (err < 0) 228cabdff1aSopenharmony_ci goto fail; 229cabdff1aSopenharmony_ci } 230cabdff1aSopenharmony_ci if (priv->sei_needed & SEI_TIMING) { 231cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_IDR) { 232cabdff1aSopenharmony_ci err = ff_cbs_sei_add_message(priv->cbc, au, 1, 233cabdff1aSopenharmony_ci SEI_TYPE_BUFFERING_PERIOD, 234cabdff1aSopenharmony_ci &priv->sei_buffering_period, NULL); 235cabdff1aSopenharmony_ci if (err < 0) 236cabdff1aSopenharmony_ci goto fail; 237cabdff1aSopenharmony_ci } 238cabdff1aSopenharmony_ci err = ff_cbs_sei_add_message(priv->cbc, au, 1, 239cabdff1aSopenharmony_ci SEI_TYPE_PIC_TIMING, 240cabdff1aSopenharmony_ci &priv->sei_pic_timing, NULL); 241cabdff1aSopenharmony_ci if (err < 0) 242cabdff1aSopenharmony_ci goto fail; 243cabdff1aSopenharmony_ci } 244cabdff1aSopenharmony_ci if (priv->sei_needed & SEI_RECOVERY_POINT) { 245cabdff1aSopenharmony_ci err = ff_cbs_sei_add_message(priv->cbc, au, 1, 246cabdff1aSopenharmony_ci SEI_TYPE_RECOVERY_POINT, 247cabdff1aSopenharmony_ci &priv->sei_recovery_point, NULL); 248cabdff1aSopenharmony_ci if (err < 0) 249cabdff1aSopenharmony_ci goto fail; 250cabdff1aSopenharmony_ci } 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci priv->sei_needed = 0; 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); 255cabdff1aSopenharmony_ci if (err < 0) 256cabdff1aSopenharmony_ci goto fail; 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci ff_cbs_fragment_reset(au); 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci *type = VAEncPackedHeaderRawData; 261cabdff1aSopenharmony_ci return 0; 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci#if !CONFIG_VAAPI_1 264cabdff1aSopenharmony_ci } else if (priv->sei_cbr_workaround_needed) { 265cabdff1aSopenharmony_ci // Insert a zero-length header using the old SEI type. This is 266cabdff1aSopenharmony_ci // required to avoid triggering broken behaviour on Intel platforms 267cabdff1aSopenharmony_ci // in CBR mode where an invalid SEI message is generated by the 268cabdff1aSopenharmony_ci // driver and inserted into the stream. 269cabdff1aSopenharmony_ci *data_len = 0; 270cabdff1aSopenharmony_ci *type = VAEncPackedHeaderH264_SEI; 271cabdff1aSopenharmony_ci priv->sei_cbr_workaround_needed = 0; 272cabdff1aSopenharmony_ci return 0; 273cabdff1aSopenharmony_ci#endif 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci } else { 276cabdff1aSopenharmony_ci return AVERROR_EOF; 277cabdff1aSopenharmony_ci } 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_cifail: 280cabdff1aSopenharmony_ci ff_cbs_fragment_reset(au); 281cabdff1aSopenharmony_ci return err; 282cabdff1aSopenharmony_ci} 283cabdff1aSopenharmony_ci 284cabdff1aSopenharmony_cistatic int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) 285cabdff1aSopenharmony_ci{ 286cabdff1aSopenharmony_ci VAAPIEncodeContext *ctx = avctx->priv_data; 287cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 288cabdff1aSopenharmony_ci H264RawSPS *sps = &priv->raw_sps; 289cabdff1aSopenharmony_ci H264RawPPS *pps = &priv->raw_pps; 290cabdff1aSopenharmony_ci VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params; 291cabdff1aSopenharmony_ci VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params; 292cabdff1aSopenharmony_ci 293cabdff1aSopenharmony_ci memset(sps, 0, sizeof(*sps)); 294cabdff1aSopenharmony_ci memset(pps, 0, sizeof(*pps)); 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci sps->nal_unit_header.nal_ref_idc = 3; 297cabdff1aSopenharmony_ci sps->nal_unit_header.nal_unit_type = H264_NAL_SPS; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci sps->profile_idc = avctx->profile & 0xff; 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci if (avctx->profile == FF_PROFILE_H264_CONSTRAINED_BASELINE || 302cabdff1aSopenharmony_ci avctx->profile == FF_PROFILE_H264_MAIN) 303cabdff1aSopenharmony_ci sps->constraint_set1_flag = 1; 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci if (avctx->profile == FF_PROFILE_H264_HIGH) 306cabdff1aSopenharmony_ci sps->constraint_set3_flag = ctx->gop_size == 1; 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_ci if (avctx->profile == FF_PROFILE_H264_MAIN || 309cabdff1aSopenharmony_ci avctx->profile == FF_PROFILE_H264_HIGH) { 310cabdff1aSopenharmony_ci sps->constraint_set4_flag = 1; 311cabdff1aSopenharmony_ci sps->constraint_set5_flag = ctx->b_per_p == 0; 312cabdff1aSopenharmony_ci } 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci if (ctx->gop_size == 1) 315cabdff1aSopenharmony_ci priv->dpb_frames = 0; 316cabdff1aSopenharmony_ci else 317cabdff1aSopenharmony_ci priv->dpb_frames = 1 + ctx->max_b_depth; 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_ci if (avctx->level != FF_LEVEL_UNKNOWN) { 320cabdff1aSopenharmony_ci sps->level_idc = avctx->level; 321cabdff1aSopenharmony_ci } else { 322cabdff1aSopenharmony_ci const H264LevelDescriptor *level; 323cabdff1aSopenharmony_ci int framerate; 324cabdff1aSopenharmony_ci 325cabdff1aSopenharmony_ci if (avctx->framerate.num > 0 && avctx->framerate.den > 0) 326cabdff1aSopenharmony_ci framerate = avctx->framerate.num / avctx->framerate.den; 327cabdff1aSopenharmony_ci else 328cabdff1aSopenharmony_ci framerate = 0; 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci level = ff_h264_guess_level(sps->profile_idc, 331cabdff1aSopenharmony_ci avctx->bit_rate, 332cabdff1aSopenharmony_ci framerate, 333cabdff1aSopenharmony_ci priv->mb_width * 16, 334cabdff1aSopenharmony_ci priv->mb_height * 16, 335cabdff1aSopenharmony_ci priv->dpb_frames); 336cabdff1aSopenharmony_ci if (level) { 337cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); 338cabdff1aSopenharmony_ci if (level->constraint_set3_flag) 339cabdff1aSopenharmony_ci sps->constraint_set3_flag = 1; 340cabdff1aSopenharmony_ci sps->level_idc = level->level_idc; 341cabdff1aSopenharmony_ci } else { 342cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Stream will not conform " 343cabdff1aSopenharmony_ci "to any level: using level 6.2.\n"); 344cabdff1aSopenharmony_ci sps->level_idc = 62; 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci } 347cabdff1aSopenharmony_ci 348cabdff1aSopenharmony_ci sps->seq_parameter_set_id = 0; 349cabdff1aSopenharmony_ci sps->chroma_format_idc = 1; 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_ci sps->log2_max_frame_num_minus4 = 4; 352cabdff1aSopenharmony_ci sps->pic_order_cnt_type = 0; 353cabdff1aSopenharmony_ci sps->log2_max_pic_order_cnt_lsb_minus4 = 4; 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci sps->max_num_ref_frames = priv->dpb_frames; 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_ci sps->pic_width_in_mbs_minus1 = priv->mb_width - 1; 358cabdff1aSopenharmony_ci sps->pic_height_in_map_units_minus1 = priv->mb_height - 1; 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci sps->frame_mbs_only_flag = 1; 361cabdff1aSopenharmony_ci sps->direct_8x8_inference_flag = 1; 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci if (avctx->width != 16 * priv->mb_width || 364cabdff1aSopenharmony_ci avctx->height != 16 * priv->mb_height) { 365cabdff1aSopenharmony_ci sps->frame_cropping_flag = 1; 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_ci sps->frame_crop_left_offset = 0; 368cabdff1aSopenharmony_ci sps->frame_crop_right_offset = 369cabdff1aSopenharmony_ci (16 * priv->mb_width - avctx->width) / 2; 370cabdff1aSopenharmony_ci sps->frame_crop_top_offset = 0; 371cabdff1aSopenharmony_ci sps->frame_crop_bottom_offset = 372cabdff1aSopenharmony_ci (16 * priv->mb_height - avctx->height) / 2; 373cabdff1aSopenharmony_ci } else { 374cabdff1aSopenharmony_ci sps->frame_cropping_flag = 0; 375cabdff1aSopenharmony_ci } 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci sps->vui_parameters_present_flag = 1; 378cabdff1aSopenharmony_ci 379cabdff1aSopenharmony_ci if (avctx->sample_aspect_ratio.num != 0 && 380cabdff1aSopenharmony_ci avctx->sample_aspect_ratio.den != 0) { 381cabdff1aSopenharmony_ci static const AVRational sar_idc[] = { 382cabdff1aSopenharmony_ci { 0, 0 }, 383cabdff1aSopenharmony_ci { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, 384cabdff1aSopenharmony_ci { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, 385cabdff1aSopenharmony_ci { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, 386cabdff1aSopenharmony_ci { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, 387cabdff1aSopenharmony_ci }; 388cabdff1aSopenharmony_ci int num, den, i; 389cabdff1aSopenharmony_ci av_reduce(&num, &den, avctx->sample_aspect_ratio.num, 390cabdff1aSopenharmony_ci avctx->sample_aspect_ratio.den, 65535); 391cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) { 392cabdff1aSopenharmony_ci if (num == sar_idc[i].num && 393cabdff1aSopenharmony_ci den == sar_idc[i].den) { 394cabdff1aSopenharmony_ci sps->vui.aspect_ratio_idc = i; 395cabdff1aSopenharmony_ci break; 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci } 398cabdff1aSopenharmony_ci if (i >= FF_ARRAY_ELEMS(sar_idc)) { 399cabdff1aSopenharmony_ci sps->vui.aspect_ratio_idc = 255; 400cabdff1aSopenharmony_ci sps->vui.sar_width = num; 401cabdff1aSopenharmony_ci sps->vui.sar_height = den; 402cabdff1aSopenharmony_ci } 403cabdff1aSopenharmony_ci sps->vui.aspect_ratio_info_present_flag = 1; 404cabdff1aSopenharmony_ci } 405cabdff1aSopenharmony_ci 406cabdff1aSopenharmony_ci // Unspecified video format, from table E-2. 407cabdff1aSopenharmony_ci sps->vui.video_format = 5; 408cabdff1aSopenharmony_ci sps->vui.video_full_range_flag = 409cabdff1aSopenharmony_ci avctx->color_range == AVCOL_RANGE_JPEG; 410cabdff1aSopenharmony_ci sps->vui.colour_primaries = avctx->color_primaries; 411cabdff1aSopenharmony_ci sps->vui.transfer_characteristics = avctx->color_trc; 412cabdff1aSopenharmony_ci sps->vui.matrix_coefficients = avctx->colorspace; 413cabdff1aSopenharmony_ci if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || 414cabdff1aSopenharmony_ci avctx->color_trc != AVCOL_TRC_UNSPECIFIED || 415cabdff1aSopenharmony_ci avctx->colorspace != AVCOL_SPC_UNSPECIFIED) 416cabdff1aSopenharmony_ci sps->vui.colour_description_present_flag = 1; 417cabdff1aSopenharmony_ci if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || 418cabdff1aSopenharmony_ci sps->vui.colour_description_present_flag) 419cabdff1aSopenharmony_ci sps->vui.video_signal_type_present_flag = 1; 420cabdff1aSopenharmony_ci 421cabdff1aSopenharmony_ci if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { 422cabdff1aSopenharmony_ci sps->vui.chroma_loc_info_present_flag = 1; 423cabdff1aSopenharmony_ci sps->vui.chroma_sample_loc_type_top_field = 424cabdff1aSopenharmony_ci sps->vui.chroma_sample_loc_type_bottom_field = 425cabdff1aSopenharmony_ci avctx->chroma_sample_location - 1; 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci sps->vui.timing_info_present_flag = 1; 429cabdff1aSopenharmony_ci if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { 430cabdff1aSopenharmony_ci sps->vui.num_units_in_tick = avctx->framerate.den; 431cabdff1aSopenharmony_ci sps->vui.time_scale = 2 * avctx->framerate.num; 432cabdff1aSopenharmony_ci sps->vui.fixed_frame_rate_flag = 1; 433cabdff1aSopenharmony_ci } else { 434cabdff1aSopenharmony_ci sps->vui.num_units_in_tick = avctx->time_base.num; 435cabdff1aSopenharmony_ci sps->vui.time_scale = 2 * avctx->time_base.den; 436cabdff1aSopenharmony_ci sps->vui.fixed_frame_rate_flag = 0; 437cabdff1aSopenharmony_ci } 438cabdff1aSopenharmony_ci 439cabdff1aSopenharmony_ci if (priv->sei & SEI_TIMING) { 440cabdff1aSopenharmony_ci H264RawHRD *hrd = &sps->vui.nal_hrd_parameters; 441cabdff1aSopenharmony_ci H264RawSEIBufferingPeriod *bp = &priv->sei_buffering_period; 442cabdff1aSopenharmony_ci 443cabdff1aSopenharmony_ci sps->vui.nal_hrd_parameters_present_flag = 1; 444cabdff1aSopenharmony_ci 445cabdff1aSopenharmony_ci hrd->cpb_cnt_minus1 = 0; 446cabdff1aSopenharmony_ci 447cabdff1aSopenharmony_ci // Try to scale these to a sensible range so that the 448cabdff1aSopenharmony_ci // golomb encode of the value is not overlong. 449cabdff1aSopenharmony_ci hrd->bit_rate_scale = 450cabdff1aSopenharmony_ci av_clip_uintp2(av_log2(ctx->va_bit_rate) - 15 - 6, 4); 451cabdff1aSopenharmony_ci hrd->bit_rate_value_minus1[0] = 452cabdff1aSopenharmony_ci (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1; 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_ci hrd->cpb_size_scale = 455cabdff1aSopenharmony_ci av_clip_uintp2(av_log2(ctx->hrd_params.buffer_size) - 15 - 4, 4); 456cabdff1aSopenharmony_ci hrd->cpb_size_value_minus1[0] = 457cabdff1aSopenharmony_ci (ctx->hrd_params.buffer_size >> hrd->cpb_size_scale + 4) - 1; 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_ci // CBR mode as defined for the HRD cannot be achieved without filler 460cabdff1aSopenharmony_ci // data, so this flag cannot be set even with VAAPI CBR modes. 461cabdff1aSopenharmony_ci hrd->cbr_flag[0] = 0; 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci hrd->initial_cpb_removal_delay_length_minus1 = 23; 464cabdff1aSopenharmony_ci hrd->cpb_removal_delay_length_minus1 = 23; 465cabdff1aSopenharmony_ci hrd->dpb_output_delay_length_minus1 = 7; 466cabdff1aSopenharmony_ci hrd->time_offset_length = 0; 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci bp->seq_parameter_set_id = sps->seq_parameter_set_id; 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci // This calculation can easily overflow 32 bits. 471cabdff1aSopenharmony_ci bp->nal.initial_cpb_removal_delay[0] = 90000 * 472cabdff1aSopenharmony_ci (uint64_t)ctx->hrd_params.initial_buffer_fullness / 473cabdff1aSopenharmony_ci ctx->hrd_params.buffer_size; 474cabdff1aSopenharmony_ci bp->nal.initial_cpb_removal_delay_offset[0] = 0; 475cabdff1aSopenharmony_ci } else { 476cabdff1aSopenharmony_ci sps->vui.nal_hrd_parameters_present_flag = 0; 477cabdff1aSopenharmony_ci sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag; 478cabdff1aSopenharmony_ci } 479cabdff1aSopenharmony_ci 480cabdff1aSopenharmony_ci sps->vui.bitstream_restriction_flag = 1; 481cabdff1aSopenharmony_ci sps->vui.motion_vectors_over_pic_boundaries_flag = 1; 482cabdff1aSopenharmony_ci sps->vui.log2_max_mv_length_horizontal = 15; 483cabdff1aSopenharmony_ci sps->vui.log2_max_mv_length_vertical = 15; 484cabdff1aSopenharmony_ci sps->vui.max_num_reorder_frames = ctx->max_b_depth; 485cabdff1aSopenharmony_ci sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1; 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci pps->nal_unit_header.nal_ref_idc = 3; 488cabdff1aSopenharmony_ci pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; 489cabdff1aSopenharmony_ci 490cabdff1aSopenharmony_ci pps->pic_parameter_set_id = 0; 491cabdff1aSopenharmony_ci pps->seq_parameter_set_id = 0; 492cabdff1aSopenharmony_ci 493cabdff1aSopenharmony_ci pps->entropy_coding_mode_flag = 494cabdff1aSopenharmony_ci !(sps->profile_idc == FF_PROFILE_H264_BASELINE || 495cabdff1aSopenharmony_ci sps->profile_idc == FF_PROFILE_H264_EXTENDED || 496cabdff1aSopenharmony_ci sps->profile_idc == FF_PROFILE_H264_CAVLC_444); 497cabdff1aSopenharmony_ci if (!priv->coder && pps->entropy_coding_mode_flag) 498cabdff1aSopenharmony_ci pps->entropy_coding_mode_flag = 0; 499cabdff1aSopenharmony_ci 500cabdff1aSopenharmony_ci pps->num_ref_idx_l0_default_active_minus1 = 0; 501cabdff1aSopenharmony_ci pps->num_ref_idx_l1_default_active_minus1 = 0; 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_ci pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26; 504cabdff1aSopenharmony_ci 505cabdff1aSopenharmony_ci if (sps->profile_idc == FF_PROFILE_H264_BASELINE || 506cabdff1aSopenharmony_ci sps->profile_idc == FF_PROFILE_H264_EXTENDED || 507cabdff1aSopenharmony_ci sps->profile_idc == FF_PROFILE_H264_MAIN) { 508cabdff1aSopenharmony_ci pps->more_rbsp_data = 0; 509cabdff1aSopenharmony_ci } else { 510cabdff1aSopenharmony_ci pps->more_rbsp_data = 1; 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_ci pps->transform_8x8_mode_flag = 1; 513cabdff1aSopenharmony_ci } 514cabdff1aSopenharmony_ci 515cabdff1aSopenharmony_ci *vseq = (VAEncSequenceParameterBufferH264) { 516cabdff1aSopenharmony_ci .seq_parameter_set_id = sps->seq_parameter_set_id, 517cabdff1aSopenharmony_ci .level_idc = sps->level_idc, 518cabdff1aSopenharmony_ci .intra_period = ctx->gop_size, 519cabdff1aSopenharmony_ci .intra_idr_period = ctx->gop_size, 520cabdff1aSopenharmony_ci .ip_period = ctx->b_per_p + 1, 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci .bits_per_second = ctx->va_bit_rate, 523cabdff1aSopenharmony_ci .max_num_ref_frames = sps->max_num_ref_frames, 524cabdff1aSopenharmony_ci .picture_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1, 525cabdff1aSopenharmony_ci .picture_height_in_mbs = sps->pic_height_in_map_units_minus1 + 1, 526cabdff1aSopenharmony_ci 527cabdff1aSopenharmony_ci .seq_fields.bits = { 528cabdff1aSopenharmony_ci .chroma_format_idc = sps->chroma_format_idc, 529cabdff1aSopenharmony_ci .frame_mbs_only_flag = sps->frame_mbs_only_flag, 530cabdff1aSopenharmony_ci .mb_adaptive_frame_field_flag = sps->mb_adaptive_frame_field_flag, 531cabdff1aSopenharmony_ci .seq_scaling_matrix_present_flag = sps->seq_scaling_matrix_present_flag, 532cabdff1aSopenharmony_ci .direct_8x8_inference_flag = sps->direct_8x8_inference_flag, 533cabdff1aSopenharmony_ci .log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4, 534cabdff1aSopenharmony_ci .pic_order_cnt_type = sps->pic_order_cnt_type, 535cabdff1aSopenharmony_ci .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4, 536cabdff1aSopenharmony_ci .delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag, 537cabdff1aSopenharmony_ci }, 538cabdff1aSopenharmony_ci 539cabdff1aSopenharmony_ci .bit_depth_luma_minus8 = sps->bit_depth_luma_minus8, 540cabdff1aSopenharmony_ci .bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8, 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci .frame_cropping_flag = sps->frame_cropping_flag, 543cabdff1aSopenharmony_ci .frame_crop_left_offset = sps->frame_crop_left_offset, 544cabdff1aSopenharmony_ci .frame_crop_right_offset = sps->frame_crop_right_offset, 545cabdff1aSopenharmony_ci .frame_crop_top_offset = sps->frame_crop_top_offset, 546cabdff1aSopenharmony_ci .frame_crop_bottom_offset = sps->frame_crop_bottom_offset, 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_ci .vui_parameters_present_flag = sps->vui_parameters_present_flag, 549cabdff1aSopenharmony_ci 550cabdff1aSopenharmony_ci .vui_fields.bits = { 551cabdff1aSopenharmony_ci .aspect_ratio_info_present_flag = sps->vui.aspect_ratio_info_present_flag, 552cabdff1aSopenharmony_ci .timing_info_present_flag = sps->vui.timing_info_present_flag, 553cabdff1aSopenharmony_ci .bitstream_restriction_flag = sps->vui.bitstream_restriction_flag, 554cabdff1aSopenharmony_ci .log2_max_mv_length_horizontal = sps->vui.log2_max_mv_length_horizontal, 555cabdff1aSopenharmony_ci .log2_max_mv_length_vertical = sps->vui.log2_max_mv_length_vertical, 556cabdff1aSopenharmony_ci }, 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci .aspect_ratio_idc = sps->vui.aspect_ratio_idc, 559cabdff1aSopenharmony_ci .sar_width = sps->vui.sar_width, 560cabdff1aSopenharmony_ci .sar_height = sps->vui.sar_height, 561cabdff1aSopenharmony_ci .num_units_in_tick = sps->vui.num_units_in_tick, 562cabdff1aSopenharmony_ci .time_scale = sps->vui.time_scale, 563cabdff1aSopenharmony_ci }; 564cabdff1aSopenharmony_ci 565cabdff1aSopenharmony_ci *vpic = (VAEncPictureParameterBufferH264) { 566cabdff1aSopenharmony_ci .CurrPic = { 567cabdff1aSopenharmony_ci .picture_id = VA_INVALID_ID, 568cabdff1aSopenharmony_ci .flags = VA_PICTURE_H264_INVALID, 569cabdff1aSopenharmony_ci }, 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_ci .coded_buf = VA_INVALID_ID, 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci .pic_parameter_set_id = pps->pic_parameter_set_id, 574cabdff1aSopenharmony_ci .seq_parameter_set_id = pps->seq_parameter_set_id, 575cabdff1aSopenharmony_ci 576cabdff1aSopenharmony_ci .pic_init_qp = pps->pic_init_qp_minus26 + 26, 577cabdff1aSopenharmony_ci .num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1, 578cabdff1aSopenharmony_ci .num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1, 579cabdff1aSopenharmony_ci 580cabdff1aSopenharmony_ci .chroma_qp_index_offset = pps->chroma_qp_index_offset, 581cabdff1aSopenharmony_ci .second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset, 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ci .pic_fields.bits = { 584cabdff1aSopenharmony_ci .entropy_coding_mode_flag = pps->entropy_coding_mode_flag, 585cabdff1aSopenharmony_ci .weighted_pred_flag = pps->weighted_pred_flag, 586cabdff1aSopenharmony_ci .weighted_bipred_idc = pps->weighted_bipred_idc, 587cabdff1aSopenharmony_ci .constrained_intra_pred_flag = pps->constrained_intra_pred_flag, 588cabdff1aSopenharmony_ci .transform_8x8_mode_flag = pps->transform_8x8_mode_flag, 589cabdff1aSopenharmony_ci .deblocking_filter_control_present_flag = 590cabdff1aSopenharmony_ci pps->deblocking_filter_control_present_flag, 591cabdff1aSopenharmony_ci .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present_flag, 592cabdff1aSopenharmony_ci .pic_order_present_flag = 593cabdff1aSopenharmony_ci pps->bottom_field_pic_order_in_frame_present_flag, 594cabdff1aSopenharmony_ci .pic_scaling_matrix_present_flag = pps->pic_scaling_matrix_present_flag, 595cabdff1aSopenharmony_ci }, 596cabdff1aSopenharmony_ci }; 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ci return 0; 599cabdff1aSopenharmony_ci} 600cabdff1aSopenharmony_ci 601cabdff1aSopenharmony_cistatic int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, 602cabdff1aSopenharmony_ci VAAPIEncodePicture *pic) 603cabdff1aSopenharmony_ci{ 604cabdff1aSopenharmony_ci VAAPIEncodeContext *ctx = avctx->priv_data; 605cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 606cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *hpic = pic->priv_data; 607cabdff1aSopenharmony_ci VAAPIEncodePicture *prev = pic->prev; 608cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL; 609cabdff1aSopenharmony_ci VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; 610cabdff1aSopenharmony_ci int i; 611cabdff1aSopenharmony_ci 612cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_IDR) { 613cabdff1aSopenharmony_ci av_assert0(pic->display_order == pic->encode_order); 614cabdff1aSopenharmony_ci 615cabdff1aSopenharmony_ci hpic->frame_num = 0; 616cabdff1aSopenharmony_ci hpic->last_idr_frame = pic->display_order; 617cabdff1aSopenharmony_ci hpic->idr_pic_id = hprev ? hprev->idr_pic_id + 1 : 0; 618cabdff1aSopenharmony_ci 619cabdff1aSopenharmony_ci hpic->primary_pic_type = 0; 620cabdff1aSopenharmony_ci hpic->slice_type = 7; 621cabdff1aSopenharmony_ci } else { 622cabdff1aSopenharmony_ci av_assert0(prev); 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci hpic->frame_num = hprev->frame_num + prev->is_reference; 625cabdff1aSopenharmony_ci 626cabdff1aSopenharmony_ci hpic->last_idr_frame = hprev->last_idr_frame; 627cabdff1aSopenharmony_ci hpic->idr_pic_id = hprev->idr_pic_id; 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_I) { 630cabdff1aSopenharmony_ci hpic->slice_type = 7; 631cabdff1aSopenharmony_ci hpic->primary_pic_type = 0; 632cabdff1aSopenharmony_ci } else if (pic->type == PICTURE_TYPE_P) { 633cabdff1aSopenharmony_ci hpic->slice_type = 5; 634cabdff1aSopenharmony_ci hpic->primary_pic_type = 1; 635cabdff1aSopenharmony_ci } else { 636cabdff1aSopenharmony_ci hpic->slice_type = 6; 637cabdff1aSopenharmony_ci hpic->primary_pic_type = 2; 638cabdff1aSopenharmony_ci } 639cabdff1aSopenharmony_ci } 640cabdff1aSopenharmony_ci hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame; 641cabdff1aSopenharmony_ci hpic->dpb_delay = pic->display_order - pic->encode_order + ctx->max_b_depth; 642cabdff1aSopenharmony_ci hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame; 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_ci if (priv->aud) { 645cabdff1aSopenharmony_ci priv->aud_needed = 1; 646cabdff1aSopenharmony_ci priv->raw_aud = (H264RawAUD) { 647cabdff1aSopenharmony_ci .nal_unit_header = { 648cabdff1aSopenharmony_ci .nal_unit_type = H264_NAL_AUD, 649cabdff1aSopenharmony_ci }, 650cabdff1aSopenharmony_ci .primary_pic_type = hpic->primary_pic_type, 651cabdff1aSopenharmony_ci }; 652cabdff1aSopenharmony_ci } else { 653cabdff1aSopenharmony_ci priv->aud_needed = 0; 654cabdff1aSopenharmony_ci } 655cabdff1aSopenharmony_ci 656cabdff1aSopenharmony_ci priv->sei_needed = 0; 657cabdff1aSopenharmony_ci 658cabdff1aSopenharmony_ci if (priv->sei & SEI_IDENTIFIER && pic->encode_order == 0) 659cabdff1aSopenharmony_ci priv->sei_needed |= SEI_IDENTIFIER; 660cabdff1aSopenharmony_ci#if !CONFIG_VAAPI_1 661cabdff1aSopenharmony_ci if (ctx->va_rc_mode == VA_RC_CBR) 662cabdff1aSopenharmony_ci priv->sei_cbr_workaround_needed = 1; 663cabdff1aSopenharmony_ci#endif 664cabdff1aSopenharmony_ci 665cabdff1aSopenharmony_ci if (priv->sei & SEI_TIMING) { 666cabdff1aSopenharmony_ci priv->sei_pic_timing = (H264RawSEIPicTiming) { 667cabdff1aSopenharmony_ci .cpb_removal_delay = 2 * hpic->cpb_delay, 668cabdff1aSopenharmony_ci .dpb_output_delay = 2 * hpic->dpb_delay, 669cabdff1aSopenharmony_ci }; 670cabdff1aSopenharmony_ci 671cabdff1aSopenharmony_ci priv->sei_needed |= SEI_TIMING; 672cabdff1aSopenharmony_ci } 673cabdff1aSopenharmony_ci 674cabdff1aSopenharmony_ci if (priv->sei & SEI_RECOVERY_POINT && pic->type == PICTURE_TYPE_I) { 675cabdff1aSopenharmony_ci priv->sei_recovery_point = (H264RawSEIRecoveryPoint) { 676cabdff1aSopenharmony_ci .recovery_frame_cnt = 0, 677cabdff1aSopenharmony_ci .exact_match_flag = 1, 678cabdff1aSopenharmony_ci .broken_link_flag = ctx->b_per_p > 0, 679cabdff1aSopenharmony_ci }; 680cabdff1aSopenharmony_ci 681cabdff1aSopenharmony_ci priv->sei_needed |= SEI_RECOVERY_POINT; 682cabdff1aSopenharmony_ci } 683cabdff1aSopenharmony_ci 684cabdff1aSopenharmony_ci vpic->CurrPic = (VAPictureH264) { 685cabdff1aSopenharmony_ci .picture_id = pic->recon_surface, 686cabdff1aSopenharmony_ci .frame_idx = hpic->frame_num, 687cabdff1aSopenharmony_ci .flags = 0, 688cabdff1aSopenharmony_ci .TopFieldOrderCnt = hpic->pic_order_cnt, 689cabdff1aSopenharmony_ci .BottomFieldOrderCnt = hpic->pic_order_cnt, 690cabdff1aSopenharmony_ci }; 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci for (i = 0; i < pic->nb_refs; i++) { 693cabdff1aSopenharmony_ci VAAPIEncodePicture *ref = pic->refs[i]; 694cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *href; 695cabdff1aSopenharmony_ci 696cabdff1aSopenharmony_ci av_assert0(ref && ref->encode_order < pic->encode_order); 697cabdff1aSopenharmony_ci href = ref->priv_data; 698cabdff1aSopenharmony_ci 699cabdff1aSopenharmony_ci vpic->ReferenceFrames[i] = (VAPictureH264) { 700cabdff1aSopenharmony_ci .picture_id = ref->recon_surface, 701cabdff1aSopenharmony_ci .frame_idx = href->frame_num, 702cabdff1aSopenharmony_ci .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, 703cabdff1aSopenharmony_ci .TopFieldOrderCnt = href->pic_order_cnt, 704cabdff1aSopenharmony_ci .BottomFieldOrderCnt = href->pic_order_cnt, 705cabdff1aSopenharmony_ci }; 706cabdff1aSopenharmony_ci } 707cabdff1aSopenharmony_ci for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) { 708cabdff1aSopenharmony_ci vpic->ReferenceFrames[i] = (VAPictureH264) { 709cabdff1aSopenharmony_ci .picture_id = VA_INVALID_ID, 710cabdff1aSopenharmony_ci .flags = VA_PICTURE_H264_INVALID, 711cabdff1aSopenharmony_ci }; 712cabdff1aSopenharmony_ci } 713cabdff1aSopenharmony_ci 714cabdff1aSopenharmony_ci vpic->coded_buf = pic->output_buffer; 715cabdff1aSopenharmony_ci 716cabdff1aSopenharmony_ci vpic->frame_num = hpic->frame_num; 717cabdff1aSopenharmony_ci 718cabdff1aSopenharmony_ci vpic->pic_fields.bits.idr_pic_flag = (pic->type == PICTURE_TYPE_IDR); 719cabdff1aSopenharmony_ci vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B); 720cabdff1aSopenharmony_ci 721cabdff1aSopenharmony_ci return 0; 722cabdff1aSopenharmony_ci} 723cabdff1aSopenharmony_ci 724cabdff1aSopenharmony_cistatic void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, 725cabdff1aSopenharmony_ci VAAPIEncodePicture *pic, 726cabdff1aSopenharmony_ci VAAPIEncodePicture **rpl0, 727cabdff1aSopenharmony_ci VAAPIEncodePicture **rpl1, 728cabdff1aSopenharmony_ci int *rpl_size) 729cabdff1aSopenharmony_ci{ 730cabdff1aSopenharmony_ci VAAPIEncodePicture *prev; 731cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *hp, *hn, *hc; 732cabdff1aSopenharmony_ci int i, j, n = 0; 733cabdff1aSopenharmony_ci 734cabdff1aSopenharmony_ci prev = pic->prev; 735cabdff1aSopenharmony_ci av_assert0(prev); 736cabdff1aSopenharmony_ci hp = pic->priv_data; 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci for (i = 0; i < pic->prev->nb_dpb_pics; i++) { 739cabdff1aSopenharmony_ci hn = prev->dpb[i]->priv_data; 740cabdff1aSopenharmony_ci av_assert0(hn->frame_num < hp->frame_num); 741cabdff1aSopenharmony_ci 742cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_P) { 743cabdff1aSopenharmony_ci for (j = n; j > 0; j--) { 744cabdff1aSopenharmony_ci hc = rpl0[j - 1]->priv_data; 745cabdff1aSopenharmony_ci av_assert0(hc->frame_num != hn->frame_num); 746cabdff1aSopenharmony_ci if (hc->frame_num > hn->frame_num) 747cabdff1aSopenharmony_ci break; 748cabdff1aSopenharmony_ci rpl0[j] = rpl0[j - 1]; 749cabdff1aSopenharmony_ci } 750cabdff1aSopenharmony_ci rpl0[j] = prev->dpb[i]; 751cabdff1aSopenharmony_ci 752cabdff1aSopenharmony_ci } else if (pic->type == PICTURE_TYPE_B) { 753cabdff1aSopenharmony_ci for (j = n; j > 0; j--) { 754cabdff1aSopenharmony_ci hc = rpl0[j - 1]->priv_data; 755cabdff1aSopenharmony_ci av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); 756cabdff1aSopenharmony_ci if (hc->pic_order_cnt < hp->pic_order_cnt) { 757cabdff1aSopenharmony_ci if (hn->pic_order_cnt > hp->pic_order_cnt || 758cabdff1aSopenharmony_ci hn->pic_order_cnt < hc->pic_order_cnt) 759cabdff1aSopenharmony_ci break; 760cabdff1aSopenharmony_ci } else { 761cabdff1aSopenharmony_ci if (hn->pic_order_cnt > hc->pic_order_cnt) 762cabdff1aSopenharmony_ci break; 763cabdff1aSopenharmony_ci } 764cabdff1aSopenharmony_ci rpl0[j] = rpl0[j - 1]; 765cabdff1aSopenharmony_ci } 766cabdff1aSopenharmony_ci rpl0[j] = prev->dpb[i]; 767cabdff1aSopenharmony_ci 768cabdff1aSopenharmony_ci for (j = n; j > 0; j--) { 769cabdff1aSopenharmony_ci hc = rpl1[j - 1]->priv_data; 770cabdff1aSopenharmony_ci av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); 771cabdff1aSopenharmony_ci if (hc->pic_order_cnt > hp->pic_order_cnt) { 772cabdff1aSopenharmony_ci if (hn->pic_order_cnt < hp->pic_order_cnt || 773cabdff1aSopenharmony_ci hn->pic_order_cnt > hc->pic_order_cnt) 774cabdff1aSopenharmony_ci break; 775cabdff1aSopenharmony_ci } else { 776cabdff1aSopenharmony_ci if (hn->pic_order_cnt < hc->pic_order_cnt) 777cabdff1aSopenharmony_ci break; 778cabdff1aSopenharmony_ci } 779cabdff1aSopenharmony_ci rpl1[j] = rpl1[j - 1]; 780cabdff1aSopenharmony_ci } 781cabdff1aSopenharmony_ci rpl1[j] = prev->dpb[i]; 782cabdff1aSopenharmony_ci } 783cabdff1aSopenharmony_ci 784cabdff1aSopenharmony_ci ++n; 785cabdff1aSopenharmony_ci } 786cabdff1aSopenharmony_ci 787cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_B) { 788cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 789cabdff1aSopenharmony_ci if (rpl0[i] != rpl1[i]) 790cabdff1aSopenharmony_ci break; 791cabdff1aSopenharmony_ci } 792cabdff1aSopenharmony_ci if (i == n) 793cabdff1aSopenharmony_ci FFSWAP(VAAPIEncodePicture*, rpl1[0], rpl1[1]); 794cabdff1aSopenharmony_ci } 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_P || 797cabdff1aSopenharmony_ci pic->type == PICTURE_TYPE_B) { 798cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:", 799cabdff1aSopenharmony_ci hp->frame_num, hp->pic_order_cnt); 800cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 801cabdff1aSopenharmony_ci hn = rpl0[i]->priv_data; 802cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", 803cabdff1aSopenharmony_ci hn->frame_num, hn->pic_order_cnt); 804cabdff1aSopenharmony_ci } 805cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 806cabdff1aSopenharmony_ci } 807cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_B) { 808cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:", 809cabdff1aSopenharmony_ci hp->frame_num, hp->pic_order_cnt); 810cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 811cabdff1aSopenharmony_ci hn = rpl1[i]->priv_data; 812cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", 813cabdff1aSopenharmony_ci hn->frame_num, hn->pic_order_cnt); 814cabdff1aSopenharmony_ci } 815cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 816cabdff1aSopenharmony_ci } 817cabdff1aSopenharmony_ci 818cabdff1aSopenharmony_ci *rpl_size = n; 819cabdff1aSopenharmony_ci} 820cabdff1aSopenharmony_ci 821cabdff1aSopenharmony_cistatic int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, 822cabdff1aSopenharmony_ci VAAPIEncodePicture *pic, 823cabdff1aSopenharmony_ci VAAPIEncodeSlice *slice) 824cabdff1aSopenharmony_ci{ 825cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 826cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *hpic = pic->priv_data; 827cabdff1aSopenharmony_ci VAAPIEncodePicture *prev = pic->prev; 828cabdff1aSopenharmony_ci H264RawSPS *sps = &priv->raw_sps; 829cabdff1aSopenharmony_ci H264RawPPS *pps = &priv->raw_pps; 830cabdff1aSopenharmony_ci H264RawSliceHeader *sh = &priv->raw_slice.header; 831cabdff1aSopenharmony_ci VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; 832cabdff1aSopenharmony_ci VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; 833cabdff1aSopenharmony_ci int i, j; 834cabdff1aSopenharmony_ci 835cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_IDR) { 836cabdff1aSopenharmony_ci sh->nal_unit_header.nal_unit_type = H264_NAL_IDR_SLICE; 837cabdff1aSopenharmony_ci sh->nal_unit_header.nal_ref_idc = 3; 838cabdff1aSopenharmony_ci } else { 839cabdff1aSopenharmony_ci sh->nal_unit_header.nal_unit_type = H264_NAL_SLICE; 840cabdff1aSopenharmony_ci sh->nal_unit_header.nal_ref_idc = pic->is_reference; 841cabdff1aSopenharmony_ci } 842cabdff1aSopenharmony_ci 843cabdff1aSopenharmony_ci sh->first_mb_in_slice = slice->block_start; 844cabdff1aSopenharmony_ci sh->slice_type = hpic->slice_type; 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_ci sh->pic_parameter_set_id = pps->pic_parameter_set_id; 847cabdff1aSopenharmony_ci 848cabdff1aSopenharmony_ci sh->frame_num = hpic->frame_num & 849cabdff1aSopenharmony_ci ((1 << (4 + sps->log2_max_frame_num_minus4)) - 1); 850cabdff1aSopenharmony_ci sh->idr_pic_id = hpic->idr_pic_id; 851cabdff1aSopenharmony_ci sh->pic_order_cnt_lsb = hpic->pic_order_cnt & 852cabdff1aSopenharmony_ci ((1 << (4 + sps->log2_max_pic_order_cnt_lsb_minus4)) - 1); 853cabdff1aSopenharmony_ci 854cabdff1aSopenharmony_ci sh->direct_spatial_mv_pred_flag = 1; 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_B) 857cabdff1aSopenharmony_ci sh->slice_qp_delta = priv->fixed_qp_b - (pps->pic_init_qp_minus26 + 26); 858cabdff1aSopenharmony_ci else if (pic->type == PICTURE_TYPE_P) 859cabdff1aSopenharmony_ci sh->slice_qp_delta = priv->fixed_qp_p - (pps->pic_init_qp_minus26 + 26); 860cabdff1aSopenharmony_ci else 861cabdff1aSopenharmony_ci sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26); 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ci if (pic->is_reference && pic->type != PICTURE_TYPE_IDR) { 864cabdff1aSopenharmony_ci VAAPIEncodePicture *discard_list[MAX_DPB_SIZE]; 865cabdff1aSopenharmony_ci int discard = 0, keep = 0; 866cabdff1aSopenharmony_ci 867cabdff1aSopenharmony_ci // Discard everything which is in the DPB of the previous frame but 868cabdff1aSopenharmony_ci // not in the DPB of this one. 869cabdff1aSopenharmony_ci for (i = 0; i < prev->nb_dpb_pics; i++) { 870cabdff1aSopenharmony_ci for (j = 0; j < pic->nb_dpb_pics; j++) { 871cabdff1aSopenharmony_ci if (prev->dpb[i] == pic->dpb[j]) 872cabdff1aSopenharmony_ci break; 873cabdff1aSopenharmony_ci } 874cabdff1aSopenharmony_ci if (j == pic->nb_dpb_pics) { 875cabdff1aSopenharmony_ci discard_list[discard] = prev->dpb[i]; 876cabdff1aSopenharmony_ci ++discard; 877cabdff1aSopenharmony_ci } else { 878cabdff1aSopenharmony_ci ++keep; 879cabdff1aSopenharmony_ci } 880cabdff1aSopenharmony_ci } 881cabdff1aSopenharmony_ci av_assert0(keep <= priv->dpb_frames); 882cabdff1aSopenharmony_ci 883cabdff1aSopenharmony_ci if (discard == 0) { 884cabdff1aSopenharmony_ci sh->adaptive_ref_pic_marking_mode_flag = 0; 885cabdff1aSopenharmony_ci } else { 886cabdff1aSopenharmony_ci sh->adaptive_ref_pic_marking_mode_flag = 1; 887cabdff1aSopenharmony_ci for (i = 0; i < discard; i++) { 888cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *old = discard_list[i]->priv_data; 889cabdff1aSopenharmony_ci av_assert0(old->frame_num < hpic->frame_num); 890cabdff1aSopenharmony_ci sh->mmco[i].memory_management_control_operation = 1; 891cabdff1aSopenharmony_ci sh->mmco[i].difference_of_pic_nums_minus1 = 892cabdff1aSopenharmony_ci hpic->frame_num - old->frame_num - 1; 893cabdff1aSopenharmony_ci } 894cabdff1aSopenharmony_ci sh->mmco[i].memory_management_control_operation = 0; 895cabdff1aSopenharmony_ci } 896cabdff1aSopenharmony_ci } 897cabdff1aSopenharmony_ci 898cabdff1aSopenharmony_ci // If the intended references are not the first entries of RefPicListN 899cabdff1aSopenharmony_ci // by default, use ref-pic-list-modification to move them there. 900cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) { 901cabdff1aSopenharmony_ci VAAPIEncodePicture *def_l0[MAX_DPB_SIZE], *def_l1[MAX_DPB_SIZE]; 902cabdff1aSopenharmony_ci VAAPIEncodeH264Picture *href; 903cabdff1aSopenharmony_ci int n; 904cabdff1aSopenharmony_ci 905cabdff1aSopenharmony_ci vaapi_encode_h264_default_ref_pic_list(avctx, pic, 906cabdff1aSopenharmony_ci def_l0, def_l1, &n); 907cabdff1aSopenharmony_ci 908cabdff1aSopenharmony_ci if (pic->type == PICTURE_TYPE_P) { 909cabdff1aSopenharmony_ci int need_rplm = 0; 910cabdff1aSopenharmony_ci for (i = 0; i < pic->nb_refs; i++) { 911cabdff1aSopenharmony_ci av_assert0(pic->refs[i]); 912cabdff1aSopenharmony_ci if (pic->refs[i] != def_l0[i]) 913cabdff1aSopenharmony_ci need_rplm = 1; 914cabdff1aSopenharmony_ci } 915cabdff1aSopenharmony_ci 916cabdff1aSopenharmony_ci sh->ref_pic_list_modification_flag_l0 = need_rplm; 917cabdff1aSopenharmony_ci if (need_rplm) { 918cabdff1aSopenharmony_ci int pic_num = hpic->frame_num; 919cabdff1aSopenharmony_ci for (i = 0; i < pic->nb_refs; i++) { 920cabdff1aSopenharmony_ci href = pic->refs[i]->priv_data; 921cabdff1aSopenharmony_ci av_assert0(href->frame_num != pic_num); 922cabdff1aSopenharmony_ci if (href->frame_num < pic_num) { 923cabdff1aSopenharmony_ci sh->rplm_l0[i].modification_of_pic_nums_idc = 0; 924cabdff1aSopenharmony_ci sh->rplm_l0[i].abs_diff_pic_num_minus1 = 925cabdff1aSopenharmony_ci pic_num - href->frame_num - 1; 926cabdff1aSopenharmony_ci } else { 927cabdff1aSopenharmony_ci sh->rplm_l0[i].modification_of_pic_nums_idc = 1; 928cabdff1aSopenharmony_ci sh->rplm_l0[i].abs_diff_pic_num_minus1 = 929cabdff1aSopenharmony_ci href->frame_num - pic_num - 1; 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci pic_num = href->frame_num; 932cabdff1aSopenharmony_ci } 933cabdff1aSopenharmony_ci sh->rplm_l0[i].modification_of_pic_nums_idc = 3; 934cabdff1aSopenharmony_ci } 935cabdff1aSopenharmony_ci 936cabdff1aSopenharmony_ci } else { 937cabdff1aSopenharmony_ci int need_rplm_l0 = 0, need_rplm_l1 = 0; 938cabdff1aSopenharmony_ci int n0 = 0, n1 = 0; 939cabdff1aSopenharmony_ci for (i = 0; i < pic->nb_refs; i++) { 940cabdff1aSopenharmony_ci av_assert0(pic->refs[i]); 941cabdff1aSopenharmony_ci href = pic->refs[i]->priv_data; 942cabdff1aSopenharmony_ci av_assert0(href->pic_order_cnt != hpic->pic_order_cnt); 943cabdff1aSopenharmony_ci if (href->pic_order_cnt < hpic->pic_order_cnt) { 944cabdff1aSopenharmony_ci if (pic->refs[i] != def_l0[n0]) 945cabdff1aSopenharmony_ci need_rplm_l0 = 1; 946cabdff1aSopenharmony_ci ++n0; 947cabdff1aSopenharmony_ci } else { 948cabdff1aSopenharmony_ci if (pic->refs[i] != def_l1[n1]) 949cabdff1aSopenharmony_ci need_rplm_l1 = 1; 950cabdff1aSopenharmony_ci ++n1; 951cabdff1aSopenharmony_ci } 952cabdff1aSopenharmony_ci } 953cabdff1aSopenharmony_ci 954cabdff1aSopenharmony_ci sh->ref_pic_list_modification_flag_l0 = need_rplm_l0; 955cabdff1aSopenharmony_ci if (need_rplm_l0) { 956cabdff1aSopenharmony_ci int pic_num = hpic->frame_num; 957cabdff1aSopenharmony_ci for (i = j = 0; i < pic->nb_refs; i++) { 958cabdff1aSopenharmony_ci href = pic->refs[i]->priv_data; 959cabdff1aSopenharmony_ci if (href->pic_order_cnt > hpic->pic_order_cnt) 960cabdff1aSopenharmony_ci continue; 961cabdff1aSopenharmony_ci av_assert0(href->frame_num != pic_num); 962cabdff1aSopenharmony_ci if (href->frame_num < pic_num) { 963cabdff1aSopenharmony_ci sh->rplm_l0[j].modification_of_pic_nums_idc = 0; 964cabdff1aSopenharmony_ci sh->rplm_l0[j].abs_diff_pic_num_minus1 = 965cabdff1aSopenharmony_ci pic_num - href->frame_num - 1; 966cabdff1aSopenharmony_ci } else { 967cabdff1aSopenharmony_ci sh->rplm_l0[j].modification_of_pic_nums_idc = 1; 968cabdff1aSopenharmony_ci sh->rplm_l0[j].abs_diff_pic_num_minus1 = 969cabdff1aSopenharmony_ci href->frame_num - pic_num - 1; 970cabdff1aSopenharmony_ci } 971cabdff1aSopenharmony_ci pic_num = href->frame_num; 972cabdff1aSopenharmony_ci ++j; 973cabdff1aSopenharmony_ci } 974cabdff1aSopenharmony_ci av_assert0(j == n0); 975cabdff1aSopenharmony_ci sh->rplm_l0[j].modification_of_pic_nums_idc = 3; 976cabdff1aSopenharmony_ci } 977cabdff1aSopenharmony_ci 978cabdff1aSopenharmony_ci sh->ref_pic_list_modification_flag_l1 = need_rplm_l1; 979cabdff1aSopenharmony_ci if (need_rplm_l1) { 980cabdff1aSopenharmony_ci int pic_num = hpic->frame_num; 981cabdff1aSopenharmony_ci for (i = j = 0; i < pic->nb_refs; i++) { 982cabdff1aSopenharmony_ci href = pic->refs[i]->priv_data; 983cabdff1aSopenharmony_ci if (href->pic_order_cnt < hpic->pic_order_cnt) 984cabdff1aSopenharmony_ci continue; 985cabdff1aSopenharmony_ci av_assert0(href->frame_num != pic_num); 986cabdff1aSopenharmony_ci if (href->frame_num < pic_num) { 987cabdff1aSopenharmony_ci sh->rplm_l1[j].modification_of_pic_nums_idc = 0; 988cabdff1aSopenharmony_ci sh->rplm_l1[j].abs_diff_pic_num_minus1 = 989cabdff1aSopenharmony_ci pic_num - href->frame_num - 1; 990cabdff1aSopenharmony_ci } else { 991cabdff1aSopenharmony_ci sh->rplm_l1[j].modification_of_pic_nums_idc = 1; 992cabdff1aSopenharmony_ci sh->rplm_l1[j].abs_diff_pic_num_minus1 = 993cabdff1aSopenharmony_ci href->frame_num - pic_num - 1; 994cabdff1aSopenharmony_ci } 995cabdff1aSopenharmony_ci pic_num = href->frame_num; 996cabdff1aSopenharmony_ci ++j; 997cabdff1aSopenharmony_ci } 998cabdff1aSopenharmony_ci av_assert0(j == n1); 999cabdff1aSopenharmony_ci sh->rplm_l1[j].modification_of_pic_nums_idc = 3; 1000cabdff1aSopenharmony_ci } 1001cabdff1aSopenharmony_ci } 1002cabdff1aSopenharmony_ci } 1003cabdff1aSopenharmony_ci 1004cabdff1aSopenharmony_ci vslice->macroblock_address = slice->block_start; 1005cabdff1aSopenharmony_ci vslice->num_macroblocks = slice->block_size; 1006cabdff1aSopenharmony_ci 1007cabdff1aSopenharmony_ci vslice->macroblock_info = VA_INVALID_ID; 1008cabdff1aSopenharmony_ci 1009cabdff1aSopenharmony_ci vslice->slice_type = sh->slice_type % 5; 1010cabdff1aSopenharmony_ci vslice->pic_parameter_set_id = sh->pic_parameter_set_id; 1011cabdff1aSopenharmony_ci vslice->idr_pic_id = sh->idr_pic_id; 1012cabdff1aSopenharmony_ci 1013cabdff1aSopenharmony_ci vslice->pic_order_cnt_lsb = sh->pic_order_cnt_lsb; 1014cabdff1aSopenharmony_ci 1015cabdff1aSopenharmony_ci vslice->direct_spatial_mv_pred_flag = sh->direct_spatial_mv_pred_flag; 1016cabdff1aSopenharmony_ci 1017cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(vslice->RefPicList0); i++) { 1018cabdff1aSopenharmony_ci vslice->RefPicList0[i].picture_id = VA_INVALID_ID; 1019cabdff1aSopenharmony_ci vslice->RefPicList0[i].flags = VA_PICTURE_H264_INVALID; 1020cabdff1aSopenharmony_ci vslice->RefPicList1[i].picture_id = VA_INVALID_ID; 1021cabdff1aSopenharmony_ci vslice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID; 1022cabdff1aSopenharmony_ci } 1023cabdff1aSopenharmony_ci 1024cabdff1aSopenharmony_ci av_assert0(pic->nb_refs <= 2); 1025cabdff1aSopenharmony_ci if (pic->nb_refs >= 1) { 1026cabdff1aSopenharmony_ci // Backward reference for P- or B-frame. 1027cabdff1aSopenharmony_ci av_assert0(pic->type == PICTURE_TYPE_P || 1028cabdff1aSopenharmony_ci pic->type == PICTURE_TYPE_B); 1029cabdff1aSopenharmony_ci vslice->RefPicList0[0] = vpic->ReferenceFrames[0]; 1030cabdff1aSopenharmony_ci } 1031cabdff1aSopenharmony_ci if (pic->nb_refs >= 2) { 1032cabdff1aSopenharmony_ci // Forward reference for B-frame. 1033cabdff1aSopenharmony_ci av_assert0(pic->type == PICTURE_TYPE_B); 1034cabdff1aSopenharmony_ci vslice->RefPicList1[0] = vpic->ReferenceFrames[1]; 1035cabdff1aSopenharmony_ci } 1036cabdff1aSopenharmony_ci 1037cabdff1aSopenharmony_ci vslice->slice_qp_delta = sh->slice_qp_delta; 1038cabdff1aSopenharmony_ci 1039cabdff1aSopenharmony_ci return 0; 1040cabdff1aSopenharmony_ci} 1041cabdff1aSopenharmony_ci 1042cabdff1aSopenharmony_cistatic av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) 1043cabdff1aSopenharmony_ci{ 1044cabdff1aSopenharmony_ci VAAPIEncodeContext *ctx = avctx->priv_data; 1045cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 1046cabdff1aSopenharmony_ci int err; 1047cabdff1aSopenharmony_ci 1048cabdff1aSopenharmony_ci err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_H264, avctx); 1049cabdff1aSopenharmony_ci if (err < 0) 1050cabdff1aSopenharmony_ci return err; 1051cabdff1aSopenharmony_ci 1052cabdff1aSopenharmony_ci priv->mb_width = FFALIGN(avctx->width, 16) / 16; 1053cabdff1aSopenharmony_ci priv->mb_height = FFALIGN(avctx->height, 16) / 16; 1054cabdff1aSopenharmony_ci 1055cabdff1aSopenharmony_ci if (ctx->va_rc_mode == VA_RC_CQP) { 1056cabdff1aSopenharmony_ci priv->fixed_qp_p = av_clip(ctx->rc_quality, 1, 51); 1057cabdff1aSopenharmony_ci if (avctx->i_quant_factor > 0.0) 1058cabdff1aSopenharmony_ci priv->fixed_qp_idr = 1059cabdff1aSopenharmony_ci av_clip((avctx->i_quant_factor * priv->fixed_qp_p + 1060cabdff1aSopenharmony_ci avctx->i_quant_offset) + 0.5, 1, 51); 1061cabdff1aSopenharmony_ci else 1062cabdff1aSopenharmony_ci priv->fixed_qp_idr = priv->fixed_qp_p; 1063cabdff1aSopenharmony_ci if (avctx->b_quant_factor > 0.0) 1064cabdff1aSopenharmony_ci priv->fixed_qp_b = 1065cabdff1aSopenharmony_ci av_clip((avctx->b_quant_factor * priv->fixed_qp_p + 1066cabdff1aSopenharmony_ci avctx->b_quant_offset) + 0.5, 1, 51); 1067cabdff1aSopenharmony_ci else 1068cabdff1aSopenharmony_ci priv->fixed_qp_b = priv->fixed_qp_p; 1069cabdff1aSopenharmony_ci 1070cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " 1071cabdff1aSopenharmony_ci "%d / %d / %d for IDR- / P- / B-frames.\n", 1072cabdff1aSopenharmony_ci priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); 1073cabdff1aSopenharmony_ci 1074cabdff1aSopenharmony_ci } else { 1075cabdff1aSopenharmony_ci // These still need to be set for pic_init_qp/slice_qp_delta. 1076cabdff1aSopenharmony_ci priv->fixed_qp_idr = 26; 1077cabdff1aSopenharmony_ci priv->fixed_qp_p = 26; 1078cabdff1aSopenharmony_ci priv->fixed_qp_b = 26; 1079cabdff1aSopenharmony_ci } 1080cabdff1aSopenharmony_ci 1081cabdff1aSopenharmony_ci if (!ctx->rc_mode->hrd) { 1082cabdff1aSopenharmony_ci // Timing SEI requires a mode respecting HRD parameters. 1083cabdff1aSopenharmony_ci priv->sei &= ~SEI_TIMING; 1084cabdff1aSopenharmony_ci } 1085cabdff1aSopenharmony_ci 1086cabdff1aSopenharmony_ci if (priv->sei & SEI_IDENTIFIER) { 1087cabdff1aSopenharmony_ci const char *lavc = LIBAVCODEC_IDENT; 1088cabdff1aSopenharmony_ci const char *vaapi = VA_VERSION_S; 1089cabdff1aSopenharmony_ci const char *driver; 1090cabdff1aSopenharmony_ci int len; 1091cabdff1aSopenharmony_ci 1092cabdff1aSopenharmony_ci memcpy(priv->sei_identifier.uuid_iso_iec_11578, 1093cabdff1aSopenharmony_ci vaapi_encode_h264_sei_identifier_uuid, 1094cabdff1aSopenharmony_ci sizeof(priv->sei_identifier.uuid_iso_iec_11578)); 1095cabdff1aSopenharmony_ci 1096cabdff1aSopenharmony_ci driver = vaQueryVendorString(ctx->hwctx->display); 1097cabdff1aSopenharmony_ci if (!driver) 1098cabdff1aSopenharmony_ci driver = "unknown driver"; 1099cabdff1aSopenharmony_ci 1100cabdff1aSopenharmony_ci len = snprintf(NULL, 0, "%s / VAAPI %s / %s", lavc, vaapi, driver); 1101cabdff1aSopenharmony_ci if (len >= 0) { 1102cabdff1aSopenharmony_ci priv->sei_identifier_string = av_malloc(len + 1); 1103cabdff1aSopenharmony_ci if (!priv->sei_identifier_string) 1104cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1105cabdff1aSopenharmony_ci 1106cabdff1aSopenharmony_ci snprintf(priv->sei_identifier_string, len + 1, 1107cabdff1aSopenharmony_ci "%s / VAAPI %s / %s", lavc, vaapi, driver); 1108cabdff1aSopenharmony_ci 1109cabdff1aSopenharmony_ci priv->sei_identifier.data = priv->sei_identifier_string; 1110cabdff1aSopenharmony_ci priv->sei_identifier.data_length = len + 1; 1111cabdff1aSopenharmony_ci } 1112cabdff1aSopenharmony_ci } 1113cabdff1aSopenharmony_ci 1114cabdff1aSopenharmony_ci ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8); 1115cabdff1aSopenharmony_ci 1116cabdff1aSopenharmony_ci return 0; 1117cabdff1aSopenharmony_ci} 1118cabdff1aSopenharmony_ci 1119cabdff1aSopenharmony_cistatic const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = { 1120cabdff1aSopenharmony_ci { FF_PROFILE_H264_HIGH, 8, 3, 1, 1, VAProfileH264High }, 1121cabdff1aSopenharmony_ci { FF_PROFILE_H264_MAIN, 8, 3, 1, 1, VAProfileH264Main }, 1122cabdff1aSopenharmony_ci { FF_PROFILE_H264_CONSTRAINED_BASELINE, 1123cabdff1aSopenharmony_ci 8, 3, 1, 1, VAProfileH264ConstrainedBaseline }, 1124cabdff1aSopenharmony_ci { FF_PROFILE_UNKNOWN } 1125cabdff1aSopenharmony_ci}; 1126cabdff1aSopenharmony_ci 1127cabdff1aSopenharmony_cistatic const VAAPIEncodeType vaapi_encode_type_h264 = { 1128cabdff1aSopenharmony_ci .profiles = vaapi_encode_h264_profiles, 1129cabdff1aSopenharmony_ci 1130cabdff1aSopenharmony_ci .flags = FLAG_SLICE_CONTROL | 1131cabdff1aSopenharmony_ci FLAG_B_PICTURES | 1132cabdff1aSopenharmony_ci FLAG_B_PICTURE_REFERENCES | 1133cabdff1aSopenharmony_ci FLAG_NON_IDR_KEY_PICTURES, 1134cabdff1aSopenharmony_ci 1135cabdff1aSopenharmony_ci .default_quality = 20, 1136cabdff1aSopenharmony_ci 1137cabdff1aSopenharmony_ci .configure = &vaapi_encode_h264_configure, 1138cabdff1aSopenharmony_ci 1139cabdff1aSopenharmony_ci .picture_priv_data_size = sizeof(VAAPIEncodeH264Picture), 1140cabdff1aSopenharmony_ci 1141cabdff1aSopenharmony_ci .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), 1142cabdff1aSopenharmony_ci .init_sequence_params = &vaapi_encode_h264_init_sequence_params, 1143cabdff1aSopenharmony_ci 1144cabdff1aSopenharmony_ci .picture_params_size = sizeof(VAEncPictureParameterBufferH264), 1145cabdff1aSopenharmony_ci .init_picture_params = &vaapi_encode_h264_init_picture_params, 1146cabdff1aSopenharmony_ci 1147cabdff1aSopenharmony_ci .slice_params_size = sizeof(VAEncSliceParameterBufferH264), 1148cabdff1aSopenharmony_ci .init_slice_params = &vaapi_encode_h264_init_slice_params, 1149cabdff1aSopenharmony_ci 1150cabdff1aSopenharmony_ci .sequence_header_type = VAEncPackedHeaderSequence, 1151cabdff1aSopenharmony_ci .write_sequence_header = &vaapi_encode_h264_write_sequence_header, 1152cabdff1aSopenharmony_ci 1153cabdff1aSopenharmony_ci .slice_header_type = VAEncPackedHeaderH264_Slice, 1154cabdff1aSopenharmony_ci .write_slice_header = &vaapi_encode_h264_write_slice_header, 1155cabdff1aSopenharmony_ci 1156cabdff1aSopenharmony_ci .write_extra_header = &vaapi_encode_h264_write_extra_header, 1157cabdff1aSopenharmony_ci}; 1158cabdff1aSopenharmony_ci 1159cabdff1aSopenharmony_cistatic av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) 1160cabdff1aSopenharmony_ci{ 1161cabdff1aSopenharmony_ci VAAPIEncodeContext *ctx = avctx->priv_data; 1162cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 1163cabdff1aSopenharmony_ci 1164cabdff1aSopenharmony_ci ctx->codec = &vaapi_encode_type_h264; 1165cabdff1aSopenharmony_ci 1166cabdff1aSopenharmony_ci if (avctx->profile == FF_PROFILE_UNKNOWN) 1167cabdff1aSopenharmony_ci avctx->profile = priv->profile; 1168cabdff1aSopenharmony_ci if (avctx->level == FF_LEVEL_UNKNOWN) 1169cabdff1aSopenharmony_ci avctx->level = priv->level; 1170cabdff1aSopenharmony_ci if (avctx->compression_level == FF_COMPRESSION_DEFAULT) 1171cabdff1aSopenharmony_ci avctx->compression_level = priv->quality; 1172cabdff1aSopenharmony_ci 1173cabdff1aSopenharmony_ci // Reject unsupported profiles. 1174cabdff1aSopenharmony_ci switch (avctx->profile) { 1175cabdff1aSopenharmony_ci case FF_PROFILE_H264_BASELINE: 1176cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " 1177cabdff1aSopenharmony_ci "supported, using constrained baseline profile instead.\n"); 1178cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; 1179cabdff1aSopenharmony_ci break; 1180cabdff1aSopenharmony_ci case FF_PROFILE_H264_EXTENDED: 1181cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "H.264 extended profile " 1182cabdff1aSopenharmony_ci "is not supported.\n"); 1183cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1184cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_10: 1185cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_10_INTRA: 1186cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles " 1187cabdff1aSopenharmony_ci "are not supported.\n"); 1188cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1189cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_422: 1190cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_422_INTRA: 1191cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_444: 1192cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_444_PREDICTIVE: 1193cabdff1aSopenharmony_ci case FF_PROFILE_H264_HIGH_444_INTRA: 1194cabdff1aSopenharmony_ci case FF_PROFILE_H264_CAVLC_444: 1195cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles " 1196cabdff1aSopenharmony_ci "are not supported.\n"); 1197cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1198cabdff1aSopenharmony_ci } 1199cabdff1aSopenharmony_ci 1200cabdff1aSopenharmony_ci if (avctx->level != FF_LEVEL_UNKNOWN && avctx->level & ~0xff) { 1201cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid level %d: must fit " 1202cabdff1aSopenharmony_ci "in 8-bit unsigned integer.\n", avctx->level); 1203cabdff1aSopenharmony_ci return AVERROR(EINVAL); 1204cabdff1aSopenharmony_ci } 1205cabdff1aSopenharmony_ci 1206cabdff1aSopenharmony_ci ctx->desired_packed_headers = 1207cabdff1aSopenharmony_ci VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS. 1208cabdff1aSopenharmony_ci VA_ENC_PACKED_HEADER_SLICE | // Slice headers. 1209cabdff1aSopenharmony_ci VA_ENC_PACKED_HEADER_MISC; // SEI. 1210cabdff1aSopenharmony_ci 1211cabdff1aSopenharmony_ci ctx->surface_width = FFALIGN(avctx->width, 16); 1212cabdff1aSopenharmony_ci ctx->surface_height = FFALIGN(avctx->height, 16); 1213cabdff1aSopenharmony_ci 1214cabdff1aSopenharmony_ci ctx->slice_block_height = ctx->slice_block_width = 16; 1215cabdff1aSopenharmony_ci 1216cabdff1aSopenharmony_ci if (priv->qp > 0) 1217cabdff1aSopenharmony_ci ctx->explicit_qp = priv->qp; 1218cabdff1aSopenharmony_ci 1219cabdff1aSopenharmony_ci return ff_vaapi_encode_init(avctx); 1220cabdff1aSopenharmony_ci} 1221cabdff1aSopenharmony_ci 1222cabdff1aSopenharmony_cistatic av_cold int vaapi_encode_h264_close(AVCodecContext *avctx) 1223cabdff1aSopenharmony_ci{ 1224cabdff1aSopenharmony_ci VAAPIEncodeH264Context *priv = avctx->priv_data; 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci ff_cbs_fragment_free(&priv->current_access_unit); 1227cabdff1aSopenharmony_ci ff_cbs_close(&priv->cbc); 1228cabdff1aSopenharmony_ci av_freep(&priv->sei_identifier_string); 1229cabdff1aSopenharmony_ci 1230cabdff1aSopenharmony_ci return ff_vaapi_encode_close(avctx); 1231cabdff1aSopenharmony_ci} 1232cabdff1aSopenharmony_ci 1233cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(VAAPIEncodeH264Context, x) 1234cabdff1aSopenharmony_ci#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) 1235cabdff1aSopenharmony_cistatic const AVOption vaapi_encode_h264_options[] = { 1236cabdff1aSopenharmony_ci VAAPI_ENCODE_COMMON_OPTIONS, 1237cabdff1aSopenharmony_ci VAAPI_ENCODE_RC_OPTIONS, 1238cabdff1aSopenharmony_ci 1239cabdff1aSopenharmony_ci { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)", 1240cabdff1aSopenharmony_ci OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, FLAGS }, 1241cabdff1aSopenharmony_ci { "quality", "Set encode quality (trades off against speed, higher is faster)", 1242cabdff1aSopenharmony_ci OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, 1243cabdff1aSopenharmony_ci { "coder", "Entropy coder type", 1244cabdff1aSopenharmony_ci OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" }, 1245cabdff1aSopenharmony_ci { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1246cabdff1aSopenharmony_ci { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1247cabdff1aSopenharmony_ci { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1248cabdff1aSopenharmony_ci { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, 1249cabdff1aSopenharmony_ci 1250cabdff1aSopenharmony_ci { "aud", "Include AUD", 1251cabdff1aSopenharmony_ci OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, 1252cabdff1aSopenharmony_ci 1253cabdff1aSopenharmony_ci { "sei", "Set SEI to include", 1254cabdff1aSopenharmony_ci OFFSET(sei), AV_OPT_TYPE_FLAGS, 1255cabdff1aSopenharmony_ci { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT }, 1256cabdff1aSopenharmony_ci 0, INT_MAX, FLAGS, "sei" }, 1257cabdff1aSopenharmony_ci { "identifier", "Include encoder version identifier", 1258cabdff1aSopenharmony_ci 0, AV_OPT_TYPE_CONST, { .i64 = SEI_IDENTIFIER }, 1259cabdff1aSopenharmony_ci INT_MIN, INT_MAX, FLAGS, "sei" }, 1260cabdff1aSopenharmony_ci { "timing", "Include timing parameters (buffering_period and pic_timing)", 1261cabdff1aSopenharmony_ci 0, AV_OPT_TYPE_CONST, { .i64 = SEI_TIMING }, 1262cabdff1aSopenharmony_ci INT_MIN, INT_MAX, FLAGS, "sei" }, 1263cabdff1aSopenharmony_ci { "recovery_point", "Include recovery points where appropriate", 1264cabdff1aSopenharmony_ci 0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT }, 1265cabdff1aSopenharmony_ci INT_MIN, INT_MAX, FLAGS, "sei" }, 1266cabdff1aSopenharmony_ci 1267cabdff1aSopenharmony_ci { "profile", "Set profile (profile_idc and constraint_set*_flag)", 1268cabdff1aSopenharmony_ci OFFSET(profile), AV_OPT_TYPE_INT, 1269cabdff1aSopenharmony_ci { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, FLAGS, "profile" }, 1270cabdff1aSopenharmony_ci 1271cabdff1aSopenharmony_ci#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 1272cabdff1aSopenharmony_ci { .i64 = value }, 0, 0, FLAGS, "profile" 1273cabdff1aSopenharmony_ci { PROFILE("constrained_baseline", FF_PROFILE_H264_CONSTRAINED_BASELINE) }, 1274cabdff1aSopenharmony_ci { PROFILE("main", FF_PROFILE_H264_MAIN) }, 1275cabdff1aSopenharmony_ci { PROFILE("high", FF_PROFILE_H264_HIGH) }, 1276cabdff1aSopenharmony_ci#undef PROFILE 1277cabdff1aSopenharmony_ci 1278cabdff1aSopenharmony_ci { "level", "Set level (level_idc)", 1279cabdff1aSopenharmony_ci OFFSET(level), AV_OPT_TYPE_INT, 1280cabdff1aSopenharmony_ci { .i64 = FF_LEVEL_UNKNOWN }, FF_LEVEL_UNKNOWN, 0xff, FLAGS, "level" }, 1281cabdff1aSopenharmony_ci 1282cabdff1aSopenharmony_ci#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 1283cabdff1aSopenharmony_ci { .i64 = value }, 0, 0, FLAGS, "level" 1284cabdff1aSopenharmony_ci { LEVEL("1", 10) }, 1285cabdff1aSopenharmony_ci { LEVEL("1.1", 11) }, 1286cabdff1aSopenharmony_ci { LEVEL("1.2", 12) }, 1287cabdff1aSopenharmony_ci { LEVEL("1.3", 13) }, 1288cabdff1aSopenharmony_ci { LEVEL("2", 20) }, 1289cabdff1aSopenharmony_ci { LEVEL("2.1", 21) }, 1290cabdff1aSopenharmony_ci { LEVEL("2.2", 22) }, 1291cabdff1aSopenharmony_ci { LEVEL("3", 30) }, 1292cabdff1aSopenharmony_ci { LEVEL("3.1", 31) }, 1293cabdff1aSopenharmony_ci { LEVEL("3.2", 32) }, 1294cabdff1aSopenharmony_ci { LEVEL("4", 40) }, 1295cabdff1aSopenharmony_ci { LEVEL("4.1", 41) }, 1296cabdff1aSopenharmony_ci { LEVEL("4.2", 42) }, 1297cabdff1aSopenharmony_ci { LEVEL("5", 50) }, 1298cabdff1aSopenharmony_ci { LEVEL("5.1", 51) }, 1299cabdff1aSopenharmony_ci { LEVEL("5.2", 52) }, 1300cabdff1aSopenharmony_ci { LEVEL("6", 60) }, 1301cabdff1aSopenharmony_ci { LEVEL("6.1", 61) }, 1302cabdff1aSopenharmony_ci { LEVEL("6.2", 62) }, 1303cabdff1aSopenharmony_ci#undef LEVEL 1304cabdff1aSopenharmony_ci 1305cabdff1aSopenharmony_ci { NULL }, 1306cabdff1aSopenharmony_ci}; 1307cabdff1aSopenharmony_ci 1308cabdff1aSopenharmony_cistatic const FFCodecDefault vaapi_encode_h264_defaults[] = { 1309cabdff1aSopenharmony_ci { "b", "0" }, 1310cabdff1aSopenharmony_ci { "bf", "2" }, 1311cabdff1aSopenharmony_ci { "g", "120" }, 1312cabdff1aSopenharmony_ci { "i_qfactor", "1" }, 1313cabdff1aSopenharmony_ci { "i_qoffset", "0" }, 1314cabdff1aSopenharmony_ci { "b_qfactor", "6/5" }, 1315cabdff1aSopenharmony_ci { "b_qoffset", "0" }, 1316cabdff1aSopenharmony_ci { "qmin", "-1" }, 1317cabdff1aSopenharmony_ci { "qmax", "-1" }, 1318cabdff1aSopenharmony_ci { NULL }, 1319cabdff1aSopenharmony_ci}; 1320cabdff1aSopenharmony_ci 1321cabdff1aSopenharmony_cistatic const AVClass vaapi_encode_h264_class = { 1322cabdff1aSopenharmony_ci .class_name = "h264_vaapi", 1323cabdff1aSopenharmony_ci .item_name = av_default_item_name, 1324cabdff1aSopenharmony_ci .option = vaapi_encode_h264_options, 1325cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 1326cabdff1aSopenharmony_ci}; 1327cabdff1aSopenharmony_ci 1328cabdff1aSopenharmony_ciconst FFCodec ff_h264_vaapi_encoder = { 1329cabdff1aSopenharmony_ci .p.name = "h264_vaapi", 1330cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"), 1331cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1332cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_H264, 1333cabdff1aSopenharmony_ci .priv_data_size = sizeof(VAAPIEncodeH264Context), 1334cabdff1aSopenharmony_ci .init = &vaapi_encode_h264_init, 1335cabdff1aSopenharmony_ci FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), 1336cabdff1aSopenharmony_ci .close = &vaapi_encode_h264_close, 1337cabdff1aSopenharmony_ci .p.priv_class = &vaapi_encode_h264_class, 1338cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | 1339cabdff1aSopenharmony_ci AV_CODEC_CAP_DR1, 1340cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, 1341cabdff1aSopenharmony_ci .defaults = vaapi_encode_h264_defaults, 1342cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 1343cabdff1aSopenharmony_ci AV_PIX_FMT_VAAPI, 1344cabdff1aSopenharmony_ci AV_PIX_FMT_NONE, 1345cabdff1aSopenharmony_ci }, 1346cabdff1aSopenharmony_ci .hw_configs = ff_vaapi_encode_hw_configs, 1347cabdff1aSopenharmony_ci .p.wrapper_name = "vaapi", 1348cabdff1aSopenharmony_ci}; 1349