h264_vaapi_video_encoder_delegate.cc 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h"
  5. #include <va/va.h>
  6. #include <va/va_enc_h264.h>
  7. #include <climits>
  8. #include <utility>
  9. #include "base/bits.h"
  10. #include "base/memory/ref_counted_memory.h"
  11. #include "base/numerics/checked_math.h"
  12. #include "build/build_config.h"
  13. #include "media/base/media_switches.h"
  14. #include "media/base/video_bitrate_allocation.h"
  15. #include "media/gpu/gpu_video_encode_accelerator_helpers.h"
  16. #include "media/gpu/macros.h"
  17. #include "media/gpu/vaapi/vaapi_common.h"
  18. #include "media/gpu/vaapi/vaapi_wrapper.h"
  19. #include "media/video/h264_level_limits.h"
  20. namespace media {
  21. namespace {
  22. // An IDR every 2048 frames (must be >= 16 per spec), no I frames and no B
  23. // frames. We choose IDR period to equal MaxFrameNum so it must be a power of 2.
  24. // Produce an IDR at least once per this many frames. Must be >= 16 (per spec).
  25. constexpr uint32_t kIDRPeriod = 2048;
  26. static_assert(kIDRPeriod >= 16u, "idr_period_frames must be >= 16");
  27. // Produce an I frame at least once per this many frames.
  28. constexpr uint32_t kIPeriod = 0;
  29. // How often do we need to have either an I or a P frame in the stream.
  30. // A period of 1 implies no B frames.
  31. constexpr uint32_t kIPPeriod = 1;
  32. // The qp range is 0-51 in H264. Select 26 because of the center value.
  33. constexpr uint8_t kDefaultQP = 26;
  34. // Note: Webrtc default values are 24 and 37 respectively, see
  35. // h264_encoder_impl.cc.
  36. // These values are selected to make our VEA tests pass.
  37. constexpr uint8_t kMinQP = 24;
  38. constexpr uint8_t kMaxQP = 42;
  39. // Subjectively chosen bitrate window size for rate control, in ms.
  40. constexpr uint32_t kCPBWindowSizeMs = 1500;
  41. // Subjectively chosen.
  42. // Generally use up to 2 reference frames.
  43. constexpr size_t kMaxRefIdxL0Size = 2;
  44. // HRD parameters (ch. E.2.2 in H264 spec).
  45. constexpr int kBitRateScale = 0; // bit_rate_scale for SPS HRD parameters.
  46. constexpr int kCPBSizeScale = 0; // cpb_size_scale for SPS HRD parameters.
  47. // 4:2:0
  48. constexpr int kChromaFormatIDC = 1;
  49. constexpr uint8_t kMinSupportedH264TemporalLayers = 2;
  50. constexpr uint8_t kMaxSupportedH264TemporalLayers = 3;
  51. template <typename VAEncMiscParam>
  52. VAEncMiscParam& AllocateMiscParameterBuffer(
  53. std::vector<uint8_t>& misc_buffer,
  54. VAEncMiscParameterType misc_param_type) {
  55. constexpr size_t buffer_size =
  56. sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParam);
  57. misc_buffer.resize(buffer_size);
  58. auto* va_buffer =
  59. reinterpret_cast<VAEncMiscParameterBuffer*>(misc_buffer.data());
  60. va_buffer->type = misc_param_type;
  61. return *reinterpret_cast<VAEncMiscParam*>(va_buffer->data);
  62. }
  63. void CreateVAEncRateControlParams(uint32_t bps,
  64. uint32_t target_percentage,
  65. uint32_t window_size,
  66. uint32_t initial_qp,
  67. uint32_t min_qp,
  68. uint32_t max_qp,
  69. uint32_t framerate,
  70. uint32_t buffer_size,
  71. std::vector<uint8_t> misc_buffers[3]) {
  72. auto& rate_control_param =
  73. AllocateMiscParameterBuffer<VAEncMiscParameterRateControl>(
  74. misc_buffers[0], VAEncMiscParameterTypeRateControl);
  75. rate_control_param.bits_per_second = bps;
  76. rate_control_param.target_percentage = target_percentage;
  77. rate_control_param.window_size = window_size;
  78. rate_control_param.initial_qp = initial_qp;
  79. rate_control_param.min_qp = min_qp;
  80. rate_control_param.max_qp = max_qp;
  81. rate_control_param.rc_flags.bits.disable_frame_skip = true;
  82. auto& framerate_param =
  83. AllocateMiscParameterBuffer<VAEncMiscParameterFrameRate>(
  84. misc_buffers[1], VAEncMiscParameterTypeFrameRate);
  85. framerate_param.framerate = framerate;
  86. auto& hrd_param = AllocateMiscParameterBuffer<VAEncMiscParameterHRD>(
  87. misc_buffers[2], VAEncMiscParameterTypeHRD);
  88. hrd_param.buffer_size = buffer_size;
  89. hrd_param.initial_buffer_fullness = buffer_size / 2;
  90. }
  91. static void InitVAPictureH264(VAPictureH264* va_pic) {
  92. *va_pic = {};
  93. va_pic->picture_id = VA_INVALID_ID;
  94. va_pic->flags = VA_PICTURE_H264_INVALID;
  95. }
  96. // Updates |frame_num| as spec section 7.4.3 and sets it to |pic.frame_num|.
  97. void UpdateAndSetFrameNum(H264Picture& pic, unsigned int& frame_num) {
  98. if (pic.idr)
  99. frame_num = 0;
  100. else if (pic.ref)
  101. frame_num++;
  102. DCHECK_LT(frame_num, kIDRPeriod);
  103. pic.frame_num = frame_num;
  104. }
  105. // Updates and fills variables in |pic|, |frame_num| and |ref_frame_idx| for
  106. // temporal layer encoding. |frame_num| is the frame_num in H.264 spec for
  107. // |pic|. |ref_frame_idx| is the index in |ref_pic_list0| of the frame
  108. // referenced by |pic|.
  109. void UpdatePictureForTemporalLayerEncoding(
  110. const size_t num_layers,
  111. H264Picture& pic,
  112. unsigned int& frame_num,
  113. absl::optional<size_t>& ref_frame_idx,
  114. const unsigned int num_encoded_frames,
  115. const base::circular_deque<scoped_refptr<H264Picture>>& ref_pic_list0) {
  116. DCHECK_GE(num_layers, kMinSupportedH264TemporalLayers);
  117. DCHECK_LE(num_layers, kMaxSupportedH264TemporalLayers);
  118. constexpr size_t kTemporalLayerCycle = 4;
  119. constexpr std::pair<H264Metadata, bool>
  120. kFrameMetadata[][kTemporalLayerCycle] = {
  121. {
  122. // For two temporal layers.
  123. {{.temporal_idx = 0, .layer_sync = false}, true},
  124. {{.temporal_idx = 1, .layer_sync = true}, false},
  125. {{.temporal_idx = 0, .layer_sync = false}, true},
  126. {{.temporal_idx = 1, .layer_sync = true}, false},
  127. },
  128. {
  129. // For three temporal layers.
  130. {{.temporal_idx = 0, .layer_sync = false}, true},
  131. {{.temporal_idx = 2, .layer_sync = true}, false},
  132. {{.temporal_idx = 1, .layer_sync = true}, true},
  133. {{.temporal_idx = 2, .layer_sync = false}, false},
  134. }};
  135. // Fill |pic.metadata_for_encoding| and |pic.ref|.
  136. H264Metadata metadata;
  137. std::tie(pic.metadata_for_encoding.emplace(), pic.ref) =
  138. kFrameMetadata[num_layers - 2][num_encoded_frames % kTemporalLayerCycle];
  139. UpdateAndSetFrameNum(pic, frame_num);
  140. if (pic.idr)
  141. return;
  142. // Fill reference frame related variables in |pic| and |ref_frame_idx|.
  143. DCHECK_EQ(pic.ref_pic_list_modification_flag_l0, 0);
  144. DCHECK_EQ(pic.abs_diff_pic_num_minus1, 0);
  145. DCHECK(!ref_pic_list0.empty());
  146. if (metadata.temporal_idx == 0)
  147. ref_frame_idx = base::checked_cast<size_t>(ref_pic_list0.size() - 1);
  148. else
  149. ref_frame_idx = 0;
  150. DCHECK_LT(*ref_frame_idx, ref_pic_list0.size());
  151. const H264Picture& ref_frame_pic = *ref_pic_list0[*ref_frame_idx];
  152. const int abs_diff_pic_num = pic.frame_num - ref_frame_pic.frame_num;
  153. if (*ref_frame_idx != 0 && abs_diff_pic_num > 0) {
  154. pic.ref_pic_list_modification_flag_l0 = 1;
  155. pic.abs_diff_pic_num_minus1 = abs_diff_pic_num - 1;
  156. }
  157. }
  158. scoped_refptr<H264Picture> GetH264Picture(
  159. const VaapiVideoEncoderDelegate::EncodeJob& job) {
  160. return base::WrapRefCounted(
  161. reinterpret_cast<H264Picture*>(job.picture().get()));
  162. }
  163. } // namespace
  164. H264VaapiVideoEncoderDelegate::EncodeParams::EncodeParams()
  165. : framerate(0),
  166. cpb_window_size_ms(kCPBWindowSizeMs),
  167. cpb_size_bits(0),
  168. initial_qp(kDefaultQP),
  169. min_qp(kMinQP),
  170. max_qp(kMaxQP),
  171. max_num_ref_frames(kMaxRefIdxL0Size),
  172. max_ref_pic_list0_size(kMaxRefIdxL0Size) {}
  173. H264VaapiVideoEncoderDelegate::H264VaapiVideoEncoderDelegate(
  174. scoped_refptr<VaapiWrapper> vaapi_wrapper,
  175. base::RepeatingClosure error_cb)
  176. : VaapiVideoEncoderDelegate(std::move(vaapi_wrapper), error_cb) {}
  177. H264VaapiVideoEncoderDelegate::~H264VaapiVideoEncoderDelegate() {
  178. // H264VaapiVideoEncoderDelegate can be destroyed on any thread.
  179. }
  180. bool H264VaapiVideoEncoderDelegate::Initialize(
  181. const VideoEncodeAccelerator::Config& config,
  182. const VaapiVideoEncoderDelegate::Config& ave_config) {
  183. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  184. switch (config.output_profile) {
  185. case H264PROFILE_BASELINE:
  186. case H264PROFILE_MAIN:
  187. case H264PROFILE_HIGH:
  188. break;
  189. default:
  190. NOTIMPLEMENTED() << "Unsupported profile "
  191. << GetProfileName(config.output_profile);
  192. return false;
  193. }
  194. if (config.input_visible_size.IsEmpty()) {
  195. DVLOGF(1) << "Input visible size could not be empty";
  196. return false;
  197. }
  198. if (config.HasSpatialLayer()) {
  199. DVLOGF(1) << "Spatial layer encoding is not supported";
  200. return false;
  201. }
  202. visible_size_ = config.input_visible_size;
  203. // For 4:2:0, the pixel sizes have to be even.
  204. if ((visible_size_.width() % 2 != 0) || (visible_size_.height() % 2 != 0)) {
  205. DVLOGF(1) << "The pixel sizes are not even: " << visible_size_.ToString();
  206. return false;
  207. }
  208. constexpr int kH264MacroblockSizeInPixels = 16;
  209. coded_size_ = gfx::Size(
  210. base::bits::AlignUp(visible_size_.width(), kH264MacroblockSizeInPixels),
  211. base::bits::AlignUp(visible_size_.height(), kH264MacroblockSizeInPixels));
  212. mb_width_ = coded_size_.width() / kH264MacroblockSizeInPixels;
  213. mb_height_ = coded_size_.height() / kH264MacroblockSizeInPixels;
  214. profile_ = config.output_profile;
  215. level_ = config.h264_output_level.value_or(H264SPS::kLevelIDC4p0);
  216. uint32_t initial_framerate = config.initial_framerate.value_or(
  217. VideoEncodeAccelerator::kDefaultFramerate);
  218. // Checks if |level_| is valid. If it is invalid, set |level_| to a minimum
  219. // level that comforts Table A-1 in H.264 spec with specified bitrate,
  220. // framerate and dimension.
  221. if (!CheckH264LevelLimits(profile_, level_, config.bitrate.target_bps(),
  222. initial_framerate, mb_width_ * mb_height_)) {
  223. absl::optional<uint8_t> valid_level =
  224. FindValidH264Level(profile_, config.bitrate.target_bps(),
  225. initial_framerate, mb_width_ * mb_height_);
  226. if (!valid_level) {
  227. VLOGF(1) << "Could not find a valid h264 level for"
  228. << " profile=" << profile_
  229. << " bitrate=" << config.bitrate.target_bps()
  230. << " framerate=" << initial_framerate
  231. << " size=" << config.input_visible_size.ToString();
  232. return false;
  233. }
  234. level_ = *valid_level;
  235. }
  236. num_temporal_layers_ = 1;
  237. if (config.HasTemporalLayer()) {
  238. DCHECK(!config.spatial_layers.empty());
  239. num_temporal_layers_ = config.spatial_layers[0].num_of_temporal_layers;
  240. if (num_temporal_layers_ > kMaxSupportedH264TemporalLayers ||
  241. num_temporal_layers_ < kMinSupportedH264TemporalLayers) {
  242. DVLOGF(1) << "Unsupported number of temporal layers: "
  243. << base::strict_cast<size_t>(num_temporal_layers_);
  244. return false;
  245. }
  246. }
  247. curr_params_.max_ref_pic_list0_size =
  248. num_temporal_layers_ > 1u
  249. ? num_temporal_layers_ - 1
  250. : std::min(kMaxRefIdxL0Size, ave_config.max_num_ref_frames & 0xffff);
  251. curr_params_.max_num_ref_frames = curr_params_.max_ref_pic_list0_size;
  252. bool submit_packed_sps = false;
  253. bool submit_packed_pps = false;
  254. bool submit_packed_slice = false;
  255. if (!vaapi_wrapper_->GetSupportedPackedHeaders(
  256. config.output_profile, submit_packed_sps, submit_packed_pps,
  257. submit_packed_slice)) {
  258. DVLOGF(1) << "Failed getting supported packed headers";
  259. return false;
  260. }
  261. // Submit packed headers only if packed SPS, PPS and slice header all are
  262. // supported.
  263. submit_packed_headers_ =
  264. submit_packed_sps && submit_packed_pps && submit_packed_slice;
  265. if (submit_packed_headers_) {
  266. packed_sps_ = base::MakeRefCounted<H264BitstreamBuffer>();
  267. packed_pps_ = base::MakeRefCounted<H264BitstreamBuffer>();
  268. } else {
  269. DVLOGF(2) << "Packed headers are not submitted to a driver";
  270. }
  271. UpdateSPS();
  272. UpdatePPS();
  273. // If we don't set the stored BitrateAllocation to the right type, UpdateRates
  274. // will mistakenly reject the bitrate when the requested type in the config is
  275. // not the default (constant bitrate).
  276. curr_params_.bitrate_allocation =
  277. VideoBitrateAllocation(config.bitrate.mode());
  278. return UpdateRates(AllocateBitrateForDefaultEncoding(config),
  279. initial_framerate);
  280. }
  281. gfx::Size H264VaapiVideoEncoderDelegate::GetCodedSize() const {
  282. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  283. DCHECK(!coded_size_.IsEmpty());
  284. return coded_size_;
  285. }
  286. size_t H264VaapiVideoEncoderDelegate::GetMaxNumOfRefFrames() const {
  287. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  288. return curr_params_.max_num_ref_frames;
  289. }
  290. std::vector<gfx::Size> H264VaapiVideoEncoderDelegate::GetSVCLayerResolutions() {
  291. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  292. return {visible_size_};
  293. }
  294. BitstreamBufferMetadata H264VaapiVideoEncoderDelegate::GetMetadata(
  295. const EncodeJob& encode_job,
  296. size_t payload_size) {
  297. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  298. auto metadata =
  299. VaapiVideoEncoderDelegate::GetMetadata(encode_job, payload_size);
  300. auto picture = GetH264Picture(encode_job);
  301. DCHECK(picture);
  302. metadata.h264 = picture->metadata_for_encoding;
  303. return metadata;
  304. }
  305. bool H264VaapiVideoEncoderDelegate::PrepareEncodeJob(EncodeJob& encode_job) {
  306. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  307. scoped_refptr<H264Picture> pic = GetH264Picture(encode_job);
  308. DCHECK(pic);
  309. if (encode_job.IsKeyframeRequested() || encoding_parameters_changed_)
  310. num_encoded_frames_ = 0;
  311. if (num_encoded_frames_ == 0) {
  312. pic->idr = true;
  313. // H264 spec mandates idr_pic_id to differ between two consecutive IDRs.
  314. idr_pic_id_ ^= 1;
  315. pic->idr_pic_id = idr_pic_id_;
  316. ref_pic_list0_.clear();
  317. encoding_parameters_changed_ = false;
  318. encode_job.ProduceKeyframe();
  319. }
  320. pic->type = pic->idr ? H264SliceHeader::kISlice : H264SliceHeader::kPSlice;
  321. absl::optional<size_t> ref_frame_index;
  322. if (num_temporal_layers_ > 1u) {
  323. UpdatePictureForTemporalLayerEncoding(num_temporal_layers_, *pic,
  324. frame_num_, ref_frame_index,
  325. num_encoded_frames_, ref_pic_list0_);
  326. } else {
  327. pic->ref = true;
  328. UpdateAndSetFrameNum(*pic, frame_num_);
  329. }
  330. pic->pic_order_cnt = num_encoded_frames_ * 2;
  331. pic->top_field_order_cnt = pic->pic_order_cnt;
  332. pic->pic_order_cnt_lsb = pic->pic_order_cnt;
  333. DVLOGF(4) << "Starting a new frame, type: " << pic->type
  334. << (encode_job.IsKeyframeRequested() ? " (keyframe)" : "")
  335. << " frame_num: " << pic->frame_num
  336. << " POC: " << pic->pic_order_cnt;
  337. // TODO(b/195407733): Use a software bitrate controller and specify QP.
  338. if (!SubmitFrameParameters(encode_job, curr_params_, current_sps_,
  339. current_pps_, pic, ref_pic_list0_,
  340. ref_frame_index)) {
  341. DVLOGF(1) << "Failed submitting frame parameters";
  342. return false;
  343. }
  344. if (pic->type == H264SliceHeader::kISlice && submit_packed_headers_) {
  345. // We always generate SPS and PPS with I(DR) frame. This will help for Seek
  346. // operation on the generated stream.
  347. if (!SubmitPackedHeaders(*packed_sps_, *packed_pps_)) {
  348. DVLOGF(1) << "Failed submitting keyframe headers";
  349. return false;
  350. }
  351. }
  352. // Store the picture on the list of reference pictures and keep the list
  353. // below maximum size, dropping oldest references.
  354. if (pic->ref) {
  355. ref_pic_list0_.push_front(pic);
  356. ref_pic_list0_.resize(
  357. std::min(curr_params_.max_ref_pic_list0_size, ref_pic_list0_.size()));
  358. }
  359. num_encoded_frames_++;
  360. num_encoded_frames_ %= kIDRPeriod;
  361. return true;
  362. }
  363. bool H264VaapiVideoEncoderDelegate::UpdateRates(
  364. const VideoBitrateAllocation& bitrate_allocation,
  365. uint32_t framerate) {
  366. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  367. if (bitrate_allocation.GetMode() !=
  368. curr_params_.bitrate_allocation.GetMode()) {
  369. DVLOGF(1) << "Unexpected bitrate mode, requested rate "
  370. << bitrate_allocation.GetSumBitrate().ToString()
  371. << ", expected mode to match "
  372. << curr_params_.bitrate_allocation.GetSumBitrate().ToString();
  373. return false;
  374. }
  375. uint32_t bitrate = bitrate_allocation.GetSumBps();
  376. if (bitrate == 0 || framerate == 0)
  377. return false;
  378. if (curr_params_.bitrate_allocation == bitrate_allocation &&
  379. curr_params_.framerate == framerate) {
  380. return true;
  381. }
  382. VLOGF(2) << "New bitrate allocation: " << bitrate_allocation.ToString()
  383. << ", New framerate: " << framerate;
  384. curr_params_.bitrate_allocation = bitrate_allocation;
  385. curr_params_.framerate = framerate;
  386. base::CheckedNumeric<uint32_t> cpb_size_bits(bitrate);
  387. cpb_size_bits /= 1000;
  388. cpb_size_bits *= curr_params_.cpb_window_size_ms;
  389. if (!cpb_size_bits.AssignIfValid(&curr_params_.cpb_size_bits)) {
  390. VLOGF(1) << "Too large bitrate: " << bitrate_allocation.GetSumBps();
  391. return false;
  392. }
  393. bool previous_encoding_parameters_changed = encoding_parameters_changed_;
  394. UpdateSPS();
  395. // If SPS parameters are updated, it is required to send the SPS with IDR
  396. // frame. However, as a special case, we do not generate IDR frame if only
  397. // bitrate and framerate parameters are updated. This is safe because these
  398. // will not make a difference on decoder processing. The updated SPS will be
  399. // sent a next periodic or requested I(DR) frame. On the other hand, bitrate
  400. // and framerate parameter
  401. // changes must be affected for encoding. UpdateSPS()+SubmitFrameParameters()
  402. // shall apply them to an encoder properly.
  403. encoding_parameters_changed_ = previous_encoding_parameters_changed;
  404. return true;
  405. }
  406. void H264VaapiVideoEncoderDelegate::UpdateSPS() {
  407. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  408. memset(&current_sps_, 0, sizeof(H264SPS));
  409. // Spec A.2 and A.3.
  410. switch (profile_) {
  411. case H264PROFILE_BASELINE:
  412. // Due to https://crbug.com/345569, we don't distinguish between
  413. // constrained and non-constrained baseline profiles. Since many codecs
  414. // can't do non-constrained, and constrained is usually what we mean (and
  415. // it's a subset of non-constrained), default to it.
  416. current_sps_.profile_idc = H264SPS::kProfileIDCConstrainedBaseline;
  417. current_sps_.constraint_set0_flag = true;
  418. current_sps_.constraint_set1_flag = true;
  419. break;
  420. case H264PROFILE_MAIN:
  421. current_sps_.profile_idc = H264SPS::kProfileIDCMain;
  422. current_sps_.constraint_set1_flag = true;
  423. break;
  424. case H264PROFILE_HIGH:
  425. current_sps_.profile_idc = H264SPS::kProfileIDCHigh;
  426. break;
  427. default:
  428. NOTREACHED();
  429. return;
  430. }
  431. H264SPS::GetLevelConfigFromProfileLevel(profile_, level_,
  432. &current_sps_.level_idc,
  433. &current_sps_.constraint_set3_flag);
  434. current_sps_.seq_parameter_set_id = 0;
  435. current_sps_.chroma_format_idc = kChromaFormatIDC;
  436. current_sps_.log2_max_frame_num_minus4 =
  437. base::bits::Log2Ceiling(kIDRPeriod) - 4;
  438. current_sps_.pic_order_cnt_type = 0;
  439. current_sps_.log2_max_pic_order_cnt_lsb_minus4 =
  440. base::bits::Log2Ceiling(kIDRPeriod * 2) - 4;
  441. current_sps_.max_num_ref_frames = curr_params_.max_num_ref_frames;
  442. current_sps_.frame_mbs_only_flag = true;
  443. current_sps_.gaps_in_frame_num_value_allowed_flag = false;
  444. DCHECK_GT(mb_width_, 0u);
  445. DCHECK_GT(mb_height_, 0u);
  446. current_sps_.pic_width_in_mbs_minus1 = mb_width_ - 1;
  447. DCHECK(current_sps_.frame_mbs_only_flag);
  448. current_sps_.pic_height_in_map_units_minus1 = mb_height_ - 1;
  449. if (visible_size_ != coded_size_) {
  450. // Visible size differs from coded size, fill crop information.
  451. current_sps_.frame_cropping_flag = true;
  452. DCHECK(!current_sps_.separate_colour_plane_flag);
  453. // Spec table 6-1. Only 4:2:0 for now.
  454. DCHECK_EQ(current_sps_.chroma_format_idc, 1);
  455. // Spec 7.4.2.1.1. Crop is in crop units, which is 2 pixels for 4:2:0.
  456. const unsigned int crop_unit_x = 2;
  457. const unsigned int crop_unit_y = 2 * (2 - current_sps_.frame_mbs_only_flag);
  458. current_sps_.frame_crop_left_offset = 0;
  459. current_sps_.frame_crop_right_offset =
  460. (coded_size_.width() - visible_size_.width()) / crop_unit_x;
  461. current_sps_.frame_crop_top_offset = 0;
  462. current_sps_.frame_crop_bottom_offset =
  463. (coded_size_.height() - visible_size_.height()) / crop_unit_y;
  464. }
  465. current_sps_.vui_parameters_present_flag = true;
  466. current_sps_.timing_info_present_flag = true;
  467. current_sps_.num_units_in_tick = 1;
  468. current_sps_.time_scale =
  469. curr_params_.framerate * 2; // See equation D-2 in spec.
  470. current_sps_.fixed_frame_rate_flag = true;
  471. current_sps_.nal_hrd_parameters_present_flag = true;
  472. // H.264 spec ch. E.2.2.
  473. current_sps_.cpb_cnt_minus1 = 0;
  474. current_sps_.bit_rate_scale = kBitRateScale;
  475. current_sps_.cpb_size_scale = kCPBSizeScale;
  476. // This implicitly converts from an unsigned rhs integer to a signed integer
  477. // lhs (|bit_rate_value_minus1|). This is safe because
  478. // |H264SPS::kBitRateScaleConstantTerm| is 6, so the bitshift is equivalent to
  479. // dividing by 2^6. Therefore the resulting value is guaranteed to be in the
  480. // range of a signed 32-bit integer.
  481. current_sps_.bit_rate_value_minus1[0] =
  482. (curr_params_.bitrate_allocation.GetSumBps() >>
  483. (kBitRateScale + H264SPS::kBitRateScaleConstantTerm)) -
  484. 1;
  485. current_sps_.cpb_size_value_minus1[0] =
  486. (curr_params_.cpb_size_bits >>
  487. (kCPBSizeScale + H264SPS::kCPBSizeScaleConstantTerm)) -
  488. 1;
  489. switch (curr_params_.bitrate_allocation.GetMode()) {
  490. case (Bitrate::Mode::kConstant):
  491. current_sps_.cbr_flag[0] = true;
  492. break;
  493. case (Bitrate::Mode::kVariable):
  494. current_sps_.cbr_flag[0] = false;
  495. break;
  496. }
  497. current_sps_.initial_cpb_removal_delay_length_minus_1 =
  498. H264SPS::kDefaultInitialCPBRemovalDelayLength - 1;
  499. current_sps_.cpb_removal_delay_length_minus1 =
  500. H264SPS::kDefaultInitialCPBRemovalDelayLength - 1;
  501. current_sps_.dpb_output_delay_length_minus1 =
  502. H264SPS::kDefaultDPBOutputDelayLength - 1;
  503. current_sps_.time_offset_length = H264SPS::kDefaultTimeOffsetLength;
  504. current_sps_.low_delay_hrd_flag = false;
  505. if (submit_packed_headers_)
  506. GeneratePackedSPS();
  507. encoding_parameters_changed_ = true;
  508. }
  509. void H264VaapiVideoEncoderDelegate::UpdatePPS() {
  510. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  511. memset(&current_pps_, 0, sizeof(H264PPS));
  512. current_pps_.seq_parameter_set_id = current_sps_.seq_parameter_set_id;
  513. DCHECK_EQ(current_pps_.pic_parameter_set_id, 0);
  514. current_pps_.entropy_coding_mode_flag =
  515. current_sps_.profile_idc >= H264SPS::kProfileIDCMain;
  516. DCHECK_GT(curr_params_.max_ref_pic_list0_size, 0u);
  517. current_pps_.num_ref_idx_l0_default_active_minus1 =
  518. curr_params_.max_ref_pic_list0_size - 1;
  519. DCHECK_EQ(current_pps_.num_ref_idx_l1_default_active_minus1, 0);
  520. DCHECK_LE(curr_params_.initial_qp, 51u);
  521. current_pps_.pic_init_qp_minus26 =
  522. static_cast<int>(curr_params_.initial_qp) - 26;
  523. current_pps_.deblocking_filter_control_present_flag = true;
  524. current_pps_.transform_8x8_mode_flag =
  525. (current_sps_.profile_idc == H264SPS::kProfileIDCHigh);
  526. if (submit_packed_headers_)
  527. GeneratePackedPPS();
  528. encoding_parameters_changed_ = true;
  529. }
  530. void H264VaapiVideoEncoderDelegate::GeneratePackedSPS() {
  531. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  532. DCHECK(submit_packed_headers_);
  533. DCHECK(packed_sps_);
  534. packed_sps_->Reset();
  535. packed_sps_->BeginNALU(H264NALU::kSPS, 3);
  536. packed_sps_->AppendBits(8, current_sps_.profile_idc);
  537. packed_sps_->AppendBool(current_sps_.constraint_set0_flag);
  538. packed_sps_->AppendBool(current_sps_.constraint_set1_flag);
  539. packed_sps_->AppendBool(current_sps_.constraint_set2_flag);
  540. packed_sps_->AppendBool(current_sps_.constraint_set3_flag);
  541. packed_sps_->AppendBool(current_sps_.constraint_set4_flag);
  542. packed_sps_->AppendBool(current_sps_.constraint_set5_flag);
  543. packed_sps_->AppendBits(2, 0); // reserved_zero_2bits
  544. packed_sps_->AppendBits(8, current_sps_.level_idc);
  545. packed_sps_->AppendUE(current_sps_.seq_parameter_set_id);
  546. if (current_sps_.profile_idc == H264SPS::kProfileIDCHigh) {
  547. packed_sps_->AppendUE(current_sps_.chroma_format_idc);
  548. if (current_sps_.chroma_format_idc == 3)
  549. packed_sps_->AppendBool(current_sps_.separate_colour_plane_flag);
  550. packed_sps_->AppendUE(current_sps_.bit_depth_luma_minus8);
  551. packed_sps_->AppendUE(current_sps_.bit_depth_chroma_minus8);
  552. packed_sps_->AppendBool(current_sps_.qpprime_y_zero_transform_bypass_flag);
  553. packed_sps_->AppendBool(current_sps_.seq_scaling_matrix_present_flag);
  554. CHECK(!current_sps_.seq_scaling_matrix_present_flag);
  555. }
  556. packed_sps_->AppendUE(current_sps_.log2_max_frame_num_minus4);
  557. packed_sps_->AppendUE(current_sps_.pic_order_cnt_type);
  558. if (current_sps_.pic_order_cnt_type == 0)
  559. packed_sps_->AppendUE(current_sps_.log2_max_pic_order_cnt_lsb_minus4);
  560. else if (current_sps_.pic_order_cnt_type == 1)
  561. NOTREACHED();
  562. packed_sps_->AppendUE(current_sps_.max_num_ref_frames);
  563. packed_sps_->AppendBool(current_sps_.gaps_in_frame_num_value_allowed_flag);
  564. packed_sps_->AppendUE(current_sps_.pic_width_in_mbs_minus1);
  565. packed_sps_->AppendUE(current_sps_.pic_height_in_map_units_minus1);
  566. packed_sps_->AppendBool(current_sps_.frame_mbs_only_flag);
  567. if (!current_sps_.frame_mbs_only_flag)
  568. packed_sps_->AppendBool(current_sps_.mb_adaptive_frame_field_flag);
  569. packed_sps_->AppendBool(current_sps_.direct_8x8_inference_flag);
  570. packed_sps_->AppendBool(current_sps_.frame_cropping_flag);
  571. if (current_sps_.frame_cropping_flag) {
  572. packed_sps_->AppendUE(current_sps_.frame_crop_left_offset);
  573. packed_sps_->AppendUE(current_sps_.frame_crop_right_offset);
  574. packed_sps_->AppendUE(current_sps_.frame_crop_top_offset);
  575. packed_sps_->AppendUE(current_sps_.frame_crop_bottom_offset);
  576. }
  577. packed_sps_->AppendBool(current_sps_.vui_parameters_present_flag);
  578. if (current_sps_.vui_parameters_present_flag) {
  579. packed_sps_->AppendBool(false); // aspect_ratio_info_present_flag
  580. packed_sps_->AppendBool(false); // overscan_info_present_flag
  581. packed_sps_->AppendBool(false); // video_signal_type_present_flag
  582. packed_sps_->AppendBool(false); // chroma_loc_info_present_flag
  583. packed_sps_->AppendBool(current_sps_.timing_info_present_flag);
  584. if (current_sps_.timing_info_present_flag) {
  585. packed_sps_->AppendBits(32, current_sps_.num_units_in_tick);
  586. packed_sps_->AppendBits(32, current_sps_.time_scale);
  587. packed_sps_->AppendBool(current_sps_.fixed_frame_rate_flag);
  588. }
  589. packed_sps_->AppendBool(current_sps_.nal_hrd_parameters_present_flag);
  590. if (current_sps_.nal_hrd_parameters_present_flag) {
  591. packed_sps_->AppendUE(current_sps_.cpb_cnt_minus1);
  592. packed_sps_->AppendBits(4, current_sps_.bit_rate_scale);
  593. packed_sps_->AppendBits(4, current_sps_.cpb_size_scale);
  594. CHECK_LT(base::checked_cast<size_t>(current_sps_.cpb_cnt_minus1),
  595. std::size(current_sps_.bit_rate_value_minus1));
  596. for (int i = 0; i <= current_sps_.cpb_cnt_minus1; ++i) {
  597. packed_sps_->AppendUE(current_sps_.bit_rate_value_minus1[i]);
  598. packed_sps_->AppendUE(current_sps_.cpb_size_value_minus1[i]);
  599. packed_sps_->AppendBool(current_sps_.cbr_flag[i]);
  600. }
  601. packed_sps_->AppendBits(
  602. 5, current_sps_.initial_cpb_removal_delay_length_minus_1);
  603. packed_sps_->AppendBits(5, current_sps_.cpb_removal_delay_length_minus1);
  604. packed_sps_->AppendBits(5, current_sps_.dpb_output_delay_length_minus1);
  605. packed_sps_->AppendBits(5, current_sps_.time_offset_length);
  606. }
  607. packed_sps_->AppendBool(false); // vcl_hrd_parameters_flag
  608. if (current_sps_.nal_hrd_parameters_present_flag)
  609. packed_sps_->AppendBool(current_sps_.low_delay_hrd_flag);
  610. packed_sps_->AppendBool(false); // pic_struct_present_flag
  611. packed_sps_->AppendBool(true); // bitstream_restriction_flag
  612. packed_sps_->AppendBool(false); // motion_vectors_over_pic_boundaries_flag
  613. packed_sps_->AppendUE(2); // max_bytes_per_pic_denom
  614. packed_sps_->AppendUE(1); // max_bits_per_mb_denom
  615. packed_sps_->AppendUE(16); // log2_max_mv_length_horizontal
  616. packed_sps_->AppendUE(16); // log2_max_mv_length_vertical
  617. // Explicitly set max_num_reorder_frames to 0 to allow the decoder to
  618. // output pictures early.
  619. packed_sps_->AppendUE(0); // max_num_reorder_frames
  620. // The value of max_dec_frame_buffering shall be greater than or equal to
  621. // max_num_ref_frames.
  622. const unsigned int max_dec_frame_buffering =
  623. current_sps_.max_num_ref_frames;
  624. packed_sps_->AppendUE(max_dec_frame_buffering);
  625. }
  626. packed_sps_->FinishNALU();
  627. }
  628. void H264VaapiVideoEncoderDelegate::GeneratePackedPPS() {
  629. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  630. DCHECK(submit_packed_headers_);
  631. DCHECK(packed_pps_);
  632. packed_pps_->Reset();
  633. packed_pps_->BeginNALU(H264NALU::kPPS, 3);
  634. packed_pps_->AppendUE(current_pps_.pic_parameter_set_id);
  635. packed_pps_->AppendUE(current_pps_.seq_parameter_set_id);
  636. packed_pps_->AppendBool(current_pps_.entropy_coding_mode_flag);
  637. packed_pps_->AppendBool(
  638. current_pps_.bottom_field_pic_order_in_frame_present_flag);
  639. CHECK_EQ(current_pps_.num_slice_groups_minus1, 0);
  640. packed_pps_->AppendUE(current_pps_.num_slice_groups_minus1);
  641. packed_pps_->AppendUE(current_pps_.num_ref_idx_l0_default_active_minus1);
  642. packed_pps_->AppendUE(current_pps_.num_ref_idx_l1_default_active_minus1);
  643. packed_pps_->AppendBool(current_pps_.weighted_pred_flag);
  644. packed_pps_->AppendBits(2, current_pps_.weighted_bipred_idc);
  645. packed_pps_->AppendSE(current_pps_.pic_init_qp_minus26);
  646. packed_pps_->AppendSE(current_pps_.pic_init_qs_minus26);
  647. packed_pps_->AppendSE(current_pps_.chroma_qp_index_offset);
  648. packed_pps_->AppendBool(current_pps_.deblocking_filter_control_present_flag);
  649. packed_pps_->AppendBool(current_pps_.constrained_intra_pred_flag);
  650. packed_pps_->AppendBool(current_pps_.redundant_pic_cnt_present_flag);
  651. packed_pps_->AppendBool(current_pps_.transform_8x8_mode_flag);
  652. packed_pps_->AppendBool(current_pps_.pic_scaling_matrix_present_flag);
  653. DCHECK(!current_pps_.pic_scaling_matrix_present_flag);
  654. packed_pps_->AppendSE(current_pps_.second_chroma_qp_index_offset);
  655. packed_pps_->FinishNALU();
  656. }
  657. scoped_refptr<H264BitstreamBuffer>
  658. H264VaapiVideoEncoderDelegate::GeneratePackedSliceHeader(
  659. const VAEncPictureParameterBufferH264& pic_param,
  660. const VAEncSliceParameterBufferH264& slice_param,
  661. const H264Picture& pic) {
  662. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  663. auto packed_slice_header = base::MakeRefCounted<H264BitstreamBuffer>();
  664. const bool is_idr = !!pic_param.pic_fields.bits.idr_pic_flag;
  665. const bool is_ref = !!pic_param.pic_fields.bits.reference_pic_flag;
  666. // IDR:3, Non-IDR I slice:2, P slice:1, non ref frame: 0.
  667. size_t nal_ref_idc = 0;
  668. H264NALU::Type nalu_type = H264NALU::Type::kUnspecified;
  669. if (slice_param.slice_type == H264SliceHeader::kISlice) {
  670. nal_ref_idc = is_idr ? 3 : 2;
  671. nalu_type = is_idr ? H264NALU::kIDRSlice : H264NALU::kNonIDRSlice;
  672. } else {
  673. // B frames is not used, so this is P frame.
  674. nal_ref_idc = is_ref;
  675. nalu_type = H264NALU::kNonIDRSlice;
  676. }
  677. packed_slice_header->BeginNALU(nalu_type, nal_ref_idc);
  678. packed_slice_header->AppendUE(
  679. slice_param.macroblock_address); // first_mb_in_slice
  680. packed_slice_header->AppendUE(slice_param.slice_type);
  681. packed_slice_header->AppendUE(slice_param.pic_parameter_set_id);
  682. packed_slice_header->AppendBits(current_sps_.log2_max_frame_num_minus4 + 4,
  683. pic_param.frame_num); // frame_num
  684. DCHECK(current_sps_.frame_mbs_only_flag);
  685. if (is_idr)
  686. packed_slice_header->AppendUE(slice_param.idr_pic_id);
  687. DCHECK_EQ(current_sps_.pic_order_cnt_type, 0);
  688. packed_slice_header->AppendBits(
  689. current_sps_.log2_max_pic_order_cnt_lsb_minus4 + 4,
  690. pic_param.CurrPic.TopFieldOrderCnt);
  691. DCHECK(!current_pps_.bottom_field_pic_order_in_frame_present_flag);
  692. DCHECK(!current_pps_.redundant_pic_cnt_present_flag);
  693. if (slice_param.slice_type == H264SliceHeader::kPSlice) {
  694. packed_slice_header->AppendBits(
  695. 1, slice_param.num_ref_idx_active_override_flag);
  696. if (slice_param.num_ref_idx_active_override_flag)
  697. packed_slice_header->AppendUE(slice_param.num_ref_idx_l0_active_minus1);
  698. }
  699. if (slice_param.slice_type != H264SliceHeader::kISlice) {
  700. packed_slice_header->AppendBits(1, pic.ref_pic_list_modification_flag_l0);
  701. // modification flag for P slice.
  702. if (pic.ref_pic_list_modification_flag_l0) {
  703. // modification_of_pic_num_idc
  704. packed_slice_header->AppendUE(0);
  705. // abs_diff_pic_num_minus1
  706. packed_slice_header->AppendUE(pic.abs_diff_pic_num_minus1);
  707. // modification_of_pic_num_idc
  708. packed_slice_header->AppendUE(3);
  709. }
  710. }
  711. DCHECK_NE(slice_param.slice_type, H264SliceHeader::kBSlice);
  712. DCHECK(!pic_param.pic_fields.bits.weighted_pred_flag ||
  713. !(slice_param.slice_type == H264SliceHeader::kPSlice));
  714. // dec_ref_pic_marking
  715. if (nal_ref_idc != 0) {
  716. if (is_idr) {
  717. packed_slice_header->AppendBool(false); // no_output_of_prior_pics_flag
  718. packed_slice_header->AppendBool(false); // long_term_reference_flag
  719. } else {
  720. packed_slice_header->AppendBool(
  721. false); // adaptive_ref_pic_marking_mode_flag
  722. }
  723. }
  724. if (pic_param.pic_fields.bits.entropy_coding_mode_flag &&
  725. slice_param.slice_type != H264SliceHeader::kISlice) {
  726. packed_slice_header->AppendUE(slice_param.cabac_init_idc);
  727. }
  728. packed_slice_header->AppendSE(slice_param.slice_qp_delta);
  729. if (pic_param.pic_fields.bits.deblocking_filter_control_present_flag) {
  730. packed_slice_header->AppendUE(slice_param.disable_deblocking_filter_idc);
  731. if (slice_param.disable_deblocking_filter_idc != 1) {
  732. packed_slice_header->AppendSE(slice_param.slice_alpha_c0_offset_div2);
  733. packed_slice_header->AppendSE(slice_param.slice_beta_offset_div2);
  734. }
  735. }
  736. packed_slice_header->Flush();
  737. return packed_slice_header;
  738. }
  739. bool H264VaapiVideoEncoderDelegate::SubmitFrameParameters(
  740. EncodeJob& job,
  741. const H264VaapiVideoEncoderDelegate::EncodeParams& encode_params,
  742. const H264SPS& sps,
  743. const H264PPS& pps,
  744. scoped_refptr<H264Picture> pic,
  745. const base::circular_deque<scoped_refptr<H264Picture>>& ref_pic_list0,
  746. const absl::optional<size_t>& ref_frame_index) {
  747. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  748. const Bitrate bitrate = encode_params.bitrate_allocation.GetSumBitrate();
  749. uint32_t bitrate_bps = bitrate.target_bps();
  750. uint32_t target_percentage = 100u;
  751. if (bitrate.mode() == Bitrate::Mode::kVariable) {
  752. // In VA-API, the sequence parameter's bits_per_second represents the
  753. // maximum bitrate. Above, we use the target_bps for |bitrate_bps|; this is
  754. // because 1) for constant bitrates, peak and target are equal, and 2)
  755. // |Bitrate| class does not store a peak_bps for constant bitrates. Here,
  756. // we use the peak, because it exists for variable bitrates.
  757. bitrate_bps = bitrate.peak_bps();
  758. DCHECK_NE(bitrate.peak_bps(), 0u);
  759. base::CheckedNumeric<uint32_t> checked_percentage =
  760. base::CheckDiv(base::CheckMul<uint32_t>(bitrate.target_bps(), 100u),
  761. bitrate.peak_bps());
  762. if (!checked_percentage.AssignIfValid(&target_percentage)) {
  763. DVLOGF(1)
  764. << "Integer overflow while computing target percentage for bitrate.";
  765. return false;
  766. }
  767. target_percentage = checked_percentage.ValueOrDefault(100u);
  768. }
  769. VAEncSequenceParameterBufferH264 seq_param = {};
  770. #define SPS_TO_SP(a) seq_param.a = sps.a;
  771. SPS_TO_SP(seq_parameter_set_id);
  772. SPS_TO_SP(level_idc);
  773. seq_param.intra_period = kIPeriod;
  774. seq_param.intra_idr_period = kIDRPeriod;
  775. seq_param.ip_period = kIPPeriod;
  776. seq_param.bits_per_second = bitrate_bps;
  777. SPS_TO_SP(max_num_ref_frames);
  778. absl::optional<gfx::Size> coded_size = sps.GetCodedSize();
  779. if (!coded_size) {
  780. DVLOGF(1) << "Invalid coded size";
  781. return false;
  782. }
  783. constexpr int kH264MacroblockSizeInPixels = 16;
  784. seq_param.picture_width_in_mbs =
  785. coded_size->width() / kH264MacroblockSizeInPixels;
  786. seq_param.picture_height_in_mbs =
  787. coded_size->height() / kH264MacroblockSizeInPixels;
  788. #define SPS_TO_SP_FS(a) seq_param.seq_fields.bits.a = sps.a;
  789. SPS_TO_SP_FS(chroma_format_idc);
  790. SPS_TO_SP_FS(frame_mbs_only_flag);
  791. SPS_TO_SP_FS(log2_max_frame_num_minus4);
  792. SPS_TO_SP_FS(pic_order_cnt_type);
  793. SPS_TO_SP_FS(log2_max_pic_order_cnt_lsb_minus4);
  794. #undef SPS_TO_SP_FS
  795. SPS_TO_SP(bit_depth_luma_minus8);
  796. SPS_TO_SP(bit_depth_chroma_minus8);
  797. SPS_TO_SP(frame_cropping_flag);
  798. if (sps.frame_cropping_flag) {
  799. SPS_TO_SP(frame_crop_left_offset);
  800. SPS_TO_SP(frame_crop_right_offset);
  801. SPS_TO_SP(frame_crop_top_offset);
  802. SPS_TO_SP(frame_crop_bottom_offset);
  803. }
  804. SPS_TO_SP(vui_parameters_present_flag);
  805. #define SPS_TO_SP_VF(a) seq_param.vui_fields.bits.a = sps.a;
  806. SPS_TO_SP_VF(timing_info_present_flag);
  807. #undef SPS_TO_SP_VF
  808. SPS_TO_SP(num_units_in_tick);
  809. SPS_TO_SP(time_scale);
  810. #undef SPS_TO_SP
  811. VAEncPictureParameterBufferH264 pic_param = {};
  812. auto va_surface_id = pic->AsVaapiH264Picture()->GetVASurfaceID();
  813. pic_param.CurrPic.picture_id = va_surface_id;
  814. pic_param.CurrPic.TopFieldOrderCnt = pic->top_field_order_cnt;
  815. pic_param.CurrPic.BottomFieldOrderCnt = pic->bottom_field_order_cnt;
  816. pic_param.CurrPic.flags = 0;
  817. pic_param.coded_buf = job.coded_buffer_id();
  818. pic_param.pic_parameter_set_id = pps.pic_parameter_set_id;
  819. pic_param.seq_parameter_set_id = pps.seq_parameter_set_id;
  820. pic_param.frame_num = pic->frame_num;
  821. pic_param.pic_init_qp = pps.pic_init_qp_minus26 + 26;
  822. pic_param.num_ref_idx_l0_active_minus1 =
  823. pps.num_ref_idx_l0_default_active_minus1;
  824. pic_param.pic_fields.bits.idr_pic_flag = pic->idr;
  825. pic_param.pic_fields.bits.reference_pic_flag = pic->ref;
  826. #define PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = pps.a;
  827. PPS_TO_PP_PF(entropy_coding_mode_flag);
  828. PPS_TO_PP_PF(transform_8x8_mode_flag);
  829. PPS_TO_PP_PF(deblocking_filter_control_present_flag);
  830. #undef PPS_TO_PP_PF
  831. VAEncSliceParameterBufferH264 slice_param = {};
  832. slice_param.num_macroblocks =
  833. seq_param.picture_width_in_mbs * seq_param.picture_height_in_mbs;
  834. slice_param.macroblock_info = VA_INVALID_ID;
  835. slice_param.slice_type = pic->type;
  836. slice_param.pic_parameter_set_id = pps.pic_parameter_set_id;
  837. slice_param.idr_pic_id = pic->idr_pic_id;
  838. slice_param.pic_order_cnt_lsb = pic->pic_order_cnt_lsb;
  839. slice_param.num_ref_idx_active_override_flag = true;
  840. if (slice_param.slice_type == H264SliceHeader::kPSlice) {
  841. slice_param.num_ref_idx_l0_active_minus1 =
  842. ref_frame_index.has_value() ? 0 : ref_pic_list0.size() - 1;
  843. } else {
  844. slice_param.num_ref_idx_l0_active_minus1 = 0;
  845. }
  846. for (VAPictureH264& picture : pic_param.ReferenceFrames)
  847. InitVAPictureH264(&picture);
  848. for (VAPictureH264& picture : slice_param.RefPicList0)
  849. InitVAPictureH264(&picture);
  850. for (VAPictureH264& picture : slice_param.RefPicList1)
  851. InitVAPictureH264(&picture);
  852. for (size_t i = 0, j = 0; i < ref_pic_list0.size(); ++i) {
  853. H264Picture& ref_pic = *ref_pic_list0[i];
  854. VAPictureH264 va_pic_h264;
  855. InitVAPictureH264(&va_pic_h264);
  856. va_pic_h264.picture_id = ref_pic.AsVaapiH264Picture()->GetVASurfaceID();
  857. va_pic_h264.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
  858. va_pic_h264.frame_idx = ref_pic.frame_num;
  859. va_pic_h264.TopFieldOrderCnt = ref_pic.top_field_order_cnt;
  860. va_pic_h264.BottomFieldOrderCnt = ref_pic.bottom_field_order_cnt;
  861. // Initialize the current entry on slice and picture reference lists to
  862. // |ref_pic| and advance list pointers.
  863. pic_param.ReferenceFrames[i] = va_pic_h264;
  864. if (!ref_frame_index || *ref_frame_index == i)
  865. slice_param.RefPicList0[j++] = va_pic_h264;
  866. }
  867. std::vector<uint8_t> misc_buffers[3];
  868. CreateVAEncRateControlParams(
  869. bitrate_bps, target_percentage, encode_params.cpb_window_size_ms,
  870. base::strict_cast<uint32_t>(pic_param.pic_init_qp),
  871. base::strict_cast<uint32_t>(encode_params.min_qp),
  872. base::strict_cast<uint32_t>(encode_params.max_qp),
  873. encode_params.framerate,
  874. base::strict_cast<uint32_t>(encode_params.cpb_size_bits), misc_buffers);
  875. std::vector<VaapiWrapper::VABufferDescriptor> va_buffers = {
  876. {VAEncSequenceParameterBufferType, sizeof(seq_param), &seq_param},
  877. {VAEncPictureParameterBufferType, sizeof(pic_param), &pic_param},
  878. {VAEncSliceParameterBufferType, sizeof(slice_param), &slice_param},
  879. {VAEncMiscParameterBufferType, misc_buffers[0].size(),
  880. misc_buffers[0].data()},
  881. {VAEncMiscParameterBufferType, misc_buffers[1].size(),
  882. misc_buffers[1].data()},
  883. {VAEncMiscParameterBufferType, misc_buffers[2].size(),
  884. misc_buffers[2].data()}};
  885. scoped_refptr<H264BitstreamBuffer> packed_slice_header;
  886. VAEncPackedHeaderParameterBuffer packed_slice_param_buffer;
  887. if (submit_packed_headers_) {
  888. packed_slice_header =
  889. GeneratePackedSliceHeader(pic_param, slice_param, *pic);
  890. packed_slice_param_buffer.type = VAEncPackedHeaderSlice;
  891. packed_slice_param_buffer.bit_length = packed_slice_header->BitsInBuffer();
  892. packed_slice_param_buffer.has_emulation_bytes = 0;
  893. va_buffers.push_back({VAEncPackedHeaderParameterBufferType,
  894. sizeof(packed_slice_param_buffer),
  895. &packed_slice_param_buffer});
  896. va_buffers.push_back({VAEncPackedHeaderDataBufferType,
  897. packed_slice_header->BytesInBuffer(),
  898. packed_slice_header->data()});
  899. }
  900. return vaapi_wrapper_->SubmitBuffers(va_buffers);
  901. }
  902. bool H264VaapiVideoEncoderDelegate::SubmitPackedHeaders(
  903. const H264BitstreamBuffer& packed_sps,
  904. const H264BitstreamBuffer& packed_pps) {
  905. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  906. DCHECK(submit_packed_headers_);
  907. // Submit SPS.
  908. VAEncPackedHeaderParameterBuffer packed_sps_param = {};
  909. packed_sps_param.type = VAEncPackedHeaderSequence;
  910. packed_sps_param.bit_length = packed_sps.BytesInBuffer() * CHAR_BIT;
  911. VAEncPackedHeaderParameterBuffer packed_pps_param = {};
  912. packed_pps_param.type = VAEncPackedHeaderPicture;
  913. packed_pps_param.bit_length = packed_pps.BytesInBuffer() * CHAR_BIT;
  914. return vaapi_wrapper_->SubmitBuffers(
  915. {{VAEncPackedHeaderParameterBufferType, sizeof(packed_sps_param),
  916. &packed_sps_param},
  917. {VAEncPackedHeaderDataBufferType, packed_sps.BytesInBuffer(),
  918. packed_sps.data()},
  919. {VAEncPackedHeaderParameterBufferType, sizeof(packed_pps_param),
  920. &packed_pps_param},
  921. {VAEncPackedHeaderDataBufferType, packed_pps.BytesInBuffer(),
  922. packed_pps.data()}});
  923. }
  924. } // namespace media