h265_vaapi_video_decoder_delegate.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. // Copyright 2020 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/h265_vaapi_video_decoder_delegate.h"
  5. #include "build/chromeos_buildflags.h"
  6. #include "media/base/cdm_context.h"
  7. #include "media/gpu/decode_surface_handler.h"
  8. #include "media/gpu/macros.h"
  9. #include "media/gpu/vaapi/vaapi_common.h"
  10. #include "media/gpu/vaapi/vaapi_wrapper.h"
  11. namespace media {
  12. namespace {
  13. // Equation 5-8 in spec.
  14. int Clip3(int x, int y, int z) {
  15. if (z < x)
  16. return x;
  17. if (z > y)
  18. return y;
  19. return z;
  20. }
  21. // Fill |va_pic| with default/neutral values.
  22. void InitVAPicture(VAPictureHEVC* va_pic) {
  23. va_pic->picture_id = VA_INVALID_ID;
  24. va_pic->flags = VA_PICTURE_HEVC_INVALID;
  25. }
  26. constexpr int kInvalidRefPicIndex = -1;
  27. } // namespace
  28. using DecodeStatus = H265Decoder::H265Accelerator::Status;
  29. H265VaapiVideoDecoderDelegate::H265VaapiVideoDecoderDelegate(
  30. DecodeSurfaceHandler<VASurface>* const vaapi_dec,
  31. scoped_refptr<VaapiWrapper> vaapi_wrapper,
  32. ProtectedSessionUpdateCB on_protected_session_update_cb,
  33. CdmContext* cdm_context,
  34. EncryptionScheme encryption_scheme)
  35. : VaapiVideoDecoderDelegate(vaapi_dec,
  36. std::move(vaapi_wrapper),
  37. std::move(on_protected_session_update_cb),
  38. cdm_context,
  39. encryption_scheme) {
  40. ref_pic_list_pocs_.reserve(kMaxRefIdxActive);
  41. }
  42. H265VaapiVideoDecoderDelegate::~H265VaapiVideoDecoderDelegate() = default;
  43. scoped_refptr<H265Picture> H265VaapiVideoDecoderDelegate::CreateH265Picture() {
  44. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  45. const auto va_surface = vaapi_dec_->CreateSurface();
  46. if (!va_surface)
  47. return nullptr;
  48. return new VaapiH265Picture(std::move(va_surface));
  49. }
  50. bool H265VaapiVideoDecoderDelegate::IsChromaSamplingSupported(
  51. VideoChromaSampling chroma_sampling) {
  52. return chroma_sampling == VideoChromaSampling::k420;
  53. }
  54. DecodeStatus H265VaapiVideoDecoderDelegate::SubmitFrameMetadata(
  55. const H265SPS* sps,
  56. const H265PPS* pps,
  57. const H265SliceHeader* slice_hdr,
  58. const H265Picture::Vector& ref_pic_list,
  59. scoped_refptr<H265Picture> pic) {
  60. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  61. DCHECK(!last_slice_data_);
  62. VAPictureParameterBufferHEVC pic_param;
  63. memset(&pic_param, 0, sizeof(pic_param));
  64. #if BUILDFLAG(IS_CHROMEOS_ASH)
  65. memset(&crypto_params_, 0, sizeof(crypto_params_));
  66. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  67. int highest_tid = sps->sps_max_sub_layers_minus1;
  68. #define FROM_SPS_TO_PP(a) pic_param.a = sps->a
  69. #define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a
  70. #define FROM_PPS_TO_PP(a) pic_param.a = pps->a
  71. #define FROM_SPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = sps->a
  72. #define FROM_PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = pps->a
  73. #define FROM_SPS_TO_PP_SPF(a) pic_param.slice_parsing_fields.bits.a = sps->a
  74. #define FROM_PPS_TO_PP_SPF(a) pic_param.slice_parsing_fields.bits.a = pps->a
  75. #define FROM_PPS_TO_PP_SPF2(a, b) pic_param.slice_parsing_fields.bits.b = pps->a
  76. FROM_SPS_TO_PP(pic_width_in_luma_samples);
  77. FROM_SPS_TO_PP(pic_height_in_luma_samples);
  78. FROM_SPS_TO_PP_PF(chroma_format_idc);
  79. FROM_SPS_TO_PP_PF(separate_colour_plane_flag);
  80. FROM_SPS_TO_PP_PF(pcm_enabled_flag);
  81. FROM_SPS_TO_PP_PF(scaling_list_enabled_flag);
  82. FROM_PPS_TO_PP_PF(transform_skip_enabled_flag);
  83. FROM_SPS_TO_PP_PF(amp_enabled_flag);
  84. FROM_SPS_TO_PP_PF(strong_intra_smoothing_enabled_flag);
  85. FROM_PPS_TO_PP_PF(sign_data_hiding_enabled_flag);
  86. FROM_PPS_TO_PP_PF(constrained_intra_pred_flag);
  87. FROM_PPS_TO_PP_PF(cu_qp_delta_enabled_flag);
  88. FROM_PPS_TO_PP_PF(weighted_pred_flag);
  89. FROM_PPS_TO_PP_PF(weighted_bipred_flag);
  90. FROM_PPS_TO_PP_PF(transquant_bypass_enabled_flag);
  91. FROM_PPS_TO_PP_PF(tiles_enabled_flag);
  92. FROM_PPS_TO_PP_PF(entropy_coding_sync_enabled_flag);
  93. FROM_PPS_TO_PP_PF(pps_loop_filter_across_slices_enabled_flag);
  94. FROM_PPS_TO_PP_PF(loop_filter_across_tiles_enabled_flag);
  95. FROM_SPS_TO_PP_PF(pcm_loop_filter_disabled_flag);
  96. pic_param.pic_fields.bits.NoPicReorderingFlag =
  97. (sps->sps_max_num_reorder_pics[highest_tid] == 0) ? 1 : 0;
  98. FROM_SPS_TO_PP2(sps_max_dec_pic_buffering_minus1[highest_tid],
  99. sps_max_dec_pic_buffering_minus1);
  100. FROM_SPS_TO_PP(bit_depth_luma_minus8);
  101. FROM_SPS_TO_PP(bit_depth_chroma_minus8);
  102. FROM_SPS_TO_PP(pcm_sample_bit_depth_luma_minus1);
  103. FROM_SPS_TO_PP(pcm_sample_bit_depth_chroma_minus1);
  104. FROM_SPS_TO_PP(log2_min_luma_coding_block_size_minus3);
  105. FROM_SPS_TO_PP(log2_diff_max_min_luma_coding_block_size);
  106. FROM_SPS_TO_PP2(log2_min_luma_transform_block_size_minus2,
  107. log2_min_transform_block_size_minus2);
  108. FROM_SPS_TO_PP2(log2_diff_max_min_luma_transform_block_size,
  109. log2_diff_max_min_transform_block_size);
  110. FROM_SPS_TO_PP(log2_min_pcm_luma_coding_block_size_minus3);
  111. FROM_SPS_TO_PP(log2_diff_max_min_pcm_luma_coding_block_size);
  112. FROM_SPS_TO_PP(max_transform_hierarchy_depth_intra);
  113. FROM_SPS_TO_PP(max_transform_hierarchy_depth_inter);
  114. FROM_PPS_TO_PP(init_qp_minus26);
  115. FROM_PPS_TO_PP(diff_cu_qp_delta_depth);
  116. FROM_PPS_TO_PP(pps_cb_qp_offset);
  117. FROM_PPS_TO_PP(pps_cr_qp_offset);
  118. FROM_PPS_TO_PP(log2_parallel_merge_level_minus2);
  119. FROM_PPS_TO_PP(num_tile_columns_minus1);
  120. FROM_PPS_TO_PP(num_tile_rows_minus1);
  121. if (pps->uniform_spacing_flag) {
  122. // We need to calculate this ourselves per 6.5.1 in the spec. We subtract 1
  123. // as well so it matches the 'minus1' usage in the struct.
  124. for (int i = 0; i <= pps->num_tile_columns_minus1; ++i) {
  125. pic_param.column_width_minus1[i] = (((i + 1) * sps->pic_width_in_ctbs_y) /
  126. (pps->num_tile_columns_minus1 + 1)) -
  127. ((i * sps->pic_width_in_ctbs_y) /
  128. (pps->num_tile_columns_minus1 + 1)) -
  129. 1;
  130. }
  131. for (int j = 0; j <= pps->num_tile_rows_minus1; ++j) {
  132. pic_param.row_height_minus1[j] =
  133. (((j + 1) * sps->pic_height_in_ctbs_y) /
  134. (pps->num_tile_rows_minus1 + 1)) -
  135. ((j * sps->pic_height_in_ctbs_y) / (pps->num_tile_rows_minus1 + 1)) -
  136. 1;
  137. }
  138. } else {
  139. for (int i = 0; i <= pps->num_tile_columns_minus1; ++i)
  140. FROM_PPS_TO_PP(column_width_minus1[i]);
  141. for (int i = 0; i <= pps->num_tile_rows_minus1; ++i)
  142. FROM_PPS_TO_PP(row_height_minus1[i]);
  143. }
  144. FROM_PPS_TO_PP_SPF(lists_modification_present_flag);
  145. FROM_SPS_TO_PP_SPF(long_term_ref_pics_present_flag);
  146. FROM_SPS_TO_PP_SPF(sps_temporal_mvp_enabled_flag);
  147. FROM_PPS_TO_PP_SPF(cabac_init_present_flag);
  148. FROM_PPS_TO_PP_SPF(output_flag_present_flag);
  149. FROM_PPS_TO_PP_SPF(dependent_slice_segments_enabled_flag);
  150. FROM_PPS_TO_PP_SPF(pps_slice_chroma_qp_offsets_present_flag);
  151. FROM_SPS_TO_PP_SPF(sample_adaptive_offset_enabled_flag);
  152. FROM_PPS_TO_PP_SPF(deblocking_filter_override_enabled_flag);
  153. FROM_PPS_TO_PP_SPF2(pps_deblocking_filter_disabled_flag,
  154. pps_disable_deblocking_filter_flag);
  155. FROM_PPS_TO_PP_SPF(slice_segment_header_extension_present_flag);
  156. pic_param.slice_parsing_fields.bits.RapPicFlag =
  157. pic->nal_unit_type_ >= H265NALU::BLA_W_LP &&
  158. pic->nal_unit_type_ <= H265NALU::CRA_NUT;
  159. pic_param.slice_parsing_fields.bits.IdrPicFlag =
  160. pic->nal_unit_type_ >= H265NALU::IDR_W_RADL &&
  161. pic->nal_unit_type_ <= H265NALU::IDR_N_LP;
  162. pic_param.slice_parsing_fields.bits.IntraPicFlag = pic->irap_pic_;
  163. FROM_SPS_TO_PP(log2_max_pic_order_cnt_lsb_minus4);
  164. FROM_SPS_TO_PP(num_short_term_ref_pic_sets);
  165. FROM_SPS_TO_PP2(num_long_term_ref_pics_sps, num_long_term_ref_pic_sps);
  166. FROM_PPS_TO_PP(num_ref_idx_l0_default_active_minus1);
  167. FROM_PPS_TO_PP(num_ref_idx_l1_default_active_minus1);
  168. FROM_PPS_TO_PP(pps_beta_offset_div2);
  169. FROM_PPS_TO_PP(pps_tc_offset_div2);
  170. FROM_PPS_TO_PP(num_extra_slice_header_bits);
  171. #undef FROM_SPS_TO_PP
  172. #undef FROM_SPS_TO_PP2
  173. #undef FROM_PPS_TO_PP
  174. #undef FROM_SPS_TO_PP_PF
  175. #undef FROM_PPS_TO_PP_PF
  176. #undef FROM_SPS_TO_PP_SPF
  177. #undef FROM_PPS_TO_PP_SPF
  178. #undef FROM_PPS_TO_PP_SPF2
  179. if (slice_hdr->short_term_ref_pic_set_sps_flag)
  180. pic_param.st_rps_bits = 0;
  181. else
  182. pic_param.st_rps_bits = slice_hdr->st_rps_bits;
  183. InitVAPicture(&pic_param.CurrPic);
  184. FillVAPicture(&pic_param.CurrPic, std::move(pic));
  185. // Init reference pictures' array.
  186. for (size_t i = 0; i < std::size(pic_param.ReferenceFrames); ++i)
  187. InitVAPicture(&pic_param.ReferenceFrames[i]);
  188. // And fill it with picture info from DPB.
  189. FillVARefFramesFromRefList(ref_pic_list, pic_param.ReferenceFrames);
  190. if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, &pic_param)) {
  191. DLOG(ERROR) << "Failure on submitting pic param buffer";
  192. return DecodeStatus::kFail;
  193. }
  194. if (!sps->scaling_list_enabled_flag)
  195. return DecodeStatus::kOk;
  196. VAIQMatrixBufferHEVC iq_matrix_buf;
  197. memset(&iq_matrix_buf, 0, sizeof(iq_matrix_buf));
  198. // We already populated the IQMatrix with default values in the parser if they
  199. // are not present in the stream, so just fill them all in.
  200. const H265ScalingListData& scaling_list =
  201. pps->pps_scaling_list_data_present_flag ? pps->scaling_list_data
  202. : sps->scaling_list_data;
  203. // We need another one of these since we can't use |scaling_list| above in
  204. // the static_assert checks below.
  205. H265ScalingListData checker;
  206. static_assert((std::size(checker.scaling_list_4x4) ==
  207. std::size(iq_matrix_buf.ScalingList4x4)) &&
  208. (std::size(checker.scaling_list_4x4[0]) ==
  209. std::size(iq_matrix_buf.ScalingList4x4[0])) &&
  210. (std::size(checker.scaling_list_8x8) ==
  211. std::size(iq_matrix_buf.ScalingList8x8)) &&
  212. (std::size(checker.scaling_list_8x8[0]) ==
  213. std::size(iq_matrix_buf.ScalingList8x8[0])) &&
  214. (std::size(checker.scaling_list_16x16) ==
  215. std::size(iq_matrix_buf.ScalingList16x16)) &&
  216. (std::size(checker.scaling_list_16x16[0]) ==
  217. std::size(iq_matrix_buf.ScalingList16x16[0])) &&
  218. (std::size(checker.scaling_list_32x32) / 3 ==
  219. std::size(iq_matrix_buf.ScalingList32x32)) &&
  220. (std::size(checker.scaling_list_32x32[0]) ==
  221. std::size(iq_matrix_buf.ScalingList32x32[0])) &&
  222. (std::size(checker.scaling_list_dc_coef_16x16) ==
  223. std::size(iq_matrix_buf.ScalingListDC16x16)) &&
  224. (std::size(checker.scaling_list_dc_coef_32x32) / 3 ==
  225. std::size(iq_matrix_buf.ScalingListDC32x32)),
  226. "Mismatched HEVC scaling list matrix sizes");
  227. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; ++i) {
  228. for (int j = 0; j < H265ScalingListData::kScalingListSizeId0Count; ++j)
  229. iq_matrix_buf.ScalingList4x4[i][j] = scaling_list.scaling_list_4x4[i][j];
  230. }
  231. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; ++i) {
  232. for (int j = 0; j < H265ScalingListData::kScalingListSizeId1To3Count; ++j)
  233. iq_matrix_buf.ScalingList8x8[i][j] = scaling_list.scaling_list_8x8[i][j];
  234. }
  235. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; ++i) {
  236. for (int j = 0; j < H265ScalingListData::kScalingListSizeId1To3Count; ++j)
  237. iq_matrix_buf.ScalingList16x16[i][j] =
  238. scaling_list.scaling_list_16x16[i][j];
  239. }
  240. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; i += 3) {
  241. for (int j = 0; j < H265ScalingListData::kScalingListSizeId1To3Count; ++j)
  242. iq_matrix_buf.ScalingList32x32[i / 3][j] =
  243. scaling_list.scaling_list_32x32[i][j];
  244. }
  245. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; ++i)
  246. iq_matrix_buf.ScalingListDC16x16[i] =
  247. scaling_list.scaling_list_dc_coef_16x16[i];
  248. for (int i = 0; i < H265ScalingListData::kNumScalingListMatrices; i += 3) {
  249. iq_matrix_buf.ScalingListDC32x32[i / 3] =
  250. scaling_list.scaling_list_dc_coef_32x32[i];
  251. }
  252. return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, &iq_matrix_buf)
  253. ? DecodeStatus::kOk
  254. : DecodeStatus::kFail;
  255. }
  256. DecodeStatus H265VaapiVideoDecoderDelegate::SubmitSlice(
  257. const H265SPS* sps,
  258. const H265PPS* pps,
  259. const H265SliceHeader* slice_hdr,
  260. const H265Picture::Vector& ref_pic_list0,
  261. const H265Picture::Vector& ref_pic_list1,
  262. const H265Picture::Vector& ref_pic_set_lt_curr,
  263. const H265Picture::Vector& ref_pic_set_st_curr_after,
  264. const H265Picture::Vector& ref_pic_set_st_curr_before,
  265. scoped_refptr<H265Picture> pic,
  266. const uint8_t* data,
  267. size_t size,
  268. const std::vector<SubsampleEntry>& subsamples) {
  269. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  270. if (!SubmitPriorSliceDataIfPresent(false)) {
  271. DLOG(ERROR) << "Failure submitting prior slice data";
  272. return DecodeStatus::kFail;
  273. }
  274. #if BUILDFLAG(IS_CHROMEOS_ASH)
  275. if (IsEncryptedSession()) {
  276. const ProtectedSessionState state =
  277. SetupDecryptDecode(/*full_sample=*/false, size, &crypto_params_,
  278. &encryption_segment_info_, subsamples);
  279. if (state == ProtectedSessionState::kFailed) {
  280. LOG(ERROR) << "SubmitSlice fails because we couldn't setup the protected "
  281. "session";
  282. return DecodeStatus::kFail;
  283. } else if (state != ProtectedSessionState::kCreated) {
  284. return DecodeStatus::kTryAgain;
  285. }
  286. }
  287. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  288. memset(&slice_param_, 0, sizeof(slice_param_));
  289. slice_param_.slice_data_size = slice_hdr->nalu_size;
  290. slice_param_.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
  291. slice_param_.slice_data_byte_offset = slice_hdr->header_size;
  292. #define SHDR_TO_SP(a) slice_param_.a = slice_hdr->a
  293. #define SHDR_TO_SP2(a, b) slice_param_.b = slice_hdr->a
  294. #define SHDR_TO_SP_LSF(a) slice_param_.LongSliceFlags.fields.a = slice_hdr->a
  295. #define SHDR_TO_SP_LSF2(a, b) \
  296. slice_param_.LongSliceFlags.fields.a = slice_hdr->b
  297. SHDR_TO_SP(slice_segment_address);
  298. const auto ref_pic_list0_size = ref_pic_list0.size();
  299. const auto ref_pic_list1_size = ref_pic_list1.size();
  300. // Fill in ref pic lists.
  301. if (ref_pic_list0_size > std::size(slice_param_.RefPicList[0]) ||
  302. ref_pic_list1_size > std::size(slice_param_.RefPicList[1])) {
  303. DLOG(ERROR) << "Error, slice reference picture list is larger than 15";
  304. return DecodeStatus::kFail;
  305. }
  306. constexpr int kVaInvalidRefPicIndex = 0xFF;
  307. std::fill_n(slice_param_.RefPicList[0], std::size(slice_param_.RefPicList[0]),
  308. kVaInvalidRefPicIndex);
  309. std::fill_n(slice_param_.RefPicList[1], std::size(slice_param_.RefPicList[1]),
  310. kVaInvalidRefPicIndex);
  311. // There may be null entries in |ref_pic_list0| or |ref_pic_list1| for missing
  312. // reference pictures, just leave those marked as 0xFF and the accelerator
  313. // will do the right thing to deal with missing reference pictures.
  314. for (size_t i = 0; i < ref_pic_list0_size; ++i) {
  315. if (ref_pic_list0[i]) {
  316. int idx = GetRefPicIndex(ref_pic_list0[i]->pic_order_cnt_val_);
  317. if (idx == kInvalidRefPicIndex) {
  318. DLOG(ERROR)
  319. << "Error, slice reference picture is not in reference list";
  320. return DecodeStatus::kFail;
  321. }
  322. slice_param_.RefPicList[0][i] = idx;
  323. }
  324. }
  325. for (size_t i = 0; i < ref_pic_list1_size; ++i) {
  326. if (ref_pic_list1[i]) {
  327. int idx = GetRefPicIndex(ref_pic_list1[i]->pic_order_cnt_val_);
  328. if (idx == kInvalidRefPicIndex) {
  329. DLOG(ERROR)
  330. << "Error, slice reference picture is not in reference list";
  331. return DecodeStatus::kFail;
  332. }
  333. slice_param_.RefPicList[1][i] = idx;
  334. }
  335. }
  336. SHDR_TO_SP_LSF(dependent_slice_segment_flag);
  337. SHDR_TO_SP_LSF(slice_type);
  338. SHDR_TO_SP_LSF2(color_plane_id, colour_plane_id);
  339. SHDR_TO_SP_LSF(slice_sao_luma_flag);
  340. SHDR_TO_SP_LSF(slice_sao_chroma_flag);
  341. SHDR_TO_SP_LSF(mvd_l1_zero_flag);
  342. SHDR_TO_SP_LSF(cabac_init_flag);
  343. SHDR_TO_SP_LSF(slice_temporal_mvp_enabled_flag);
  344. SHDR_TO_SP_LSF(slice_deblocking_filter_disabled_flag);
  345. SHDR_TO_SP_LSF(collocated_from_l0_flag);
  346. SHDR_TO_SP_LSF(slice_loop_filter_across_slices_enabled_flag);
  347. if (!slice_hdr->slice_temporal_mvp_enabled_flag)
  348. slice_param_.collocated_ref_idx = kVaInvalidRefPicIndex;
  349. else
  350. SHDR_TO_SP(collocated_ref_idx);
  351. slice_param_.num_ref_idx_l0_active_minus1 =
  352. ref_pic_list0_size ? (ref_pic_list0_size - 1) : 0;
  353. slice_param_.num_ref_idx_l1_active_minus1 =
  354. ref_pic_list1_size ? (ref_pic_list1_size - 1) : 0;
  355. SHDR_TO_SP(slice_qp_delta);
  356. SHDR_TO_SP(slice_cb_qp_offset);
  357. SHDR_TO_SP(slice_cr_qp_offset);
  358. SHDR_TO_SP(slice_beta_offset_div2);
  359. SHDR_TO_SP(slice_tc_offset_div2);
  360. SHDR_TO_SP2(pred_weight_table.luma_log2_weight_denom, luma_log2_weight_denom);
  361. SHDR_TO_SP2(pred_weight_table.delta_chroma_log2_weight_denom,
  362. delta_chroma_log2_weight_denom);
  363. for (int i = 0; i < kMaxRefIdxActive; ++i) {
  364. SHDR_TO_SP2(pred_weight_table.delta_luma_weight_l0[i],
  365. delta_luma_weight_l0[i]);
  366. SHDR_TO_SP2(pred_weight_table.luma_offset_l0[i], luma_offset_l0[i]);
  367. if (slice_hdr->IsBSlice()) {
  368. SHDR_TO_SP2(pred_weight_table.delta_luma_weight_l1[i],
  369. delta_luma_weight_l1[i]);
  370. SHDR_TO_SP2(pred_weight_table.luma_offset_l1[i], luma_offset_l1[i]);
  371. }
  372. for (int j = 0; j < 2; ++j) {
  373. SHDR_TO_SP2(pred_weight_table.delta_chroma_weight_l0[i][j],
  374. delta_chroma_weight_l0[i][j]);
  375. int chroma_weight_l0 =
  376. (1 << slice_hdr->pred_weight_table.chroma_log2_weight_denom) +
  377. slice_hdr->pred_weight_table.delta_chroma_weight_l0[i][j];
  378. slice_param_.ChromaOffsetL0[i][j] =
  379. Clip3(-sps->wp_offset_half_range_c, sps->wp_offset_half_range_c - 1,
  380. (sps->wp_offset_half_range_c +
  381. slice_hdr->pred_weight_table.delta_chroma_offset_l0[i][j] -
  382. ((sps->wp_offset_half_range_c * chroma_weight_l0) >>
  383. slice_hdr->pred_weight_table.chroma_log2_weight_denom)));
  384. if (slice_hdr->IsBSlice()) {
  385. SHDR_TO_SP2(pred_weight_table.delta_chroma_weight_l1[i][j],
  386. delta_chroma_weight_l1[i][j]);
  387. int chroma_weight_l1 =
  388. (1 << slice_hdr->pred_weight_table.chroma_log2_weight_denom) +
  389. slice_hdr->pred_weight_table.delta_chroma_weight_l1[i][j];
  390. slice_param_.ChromaOffsetL1[i][j] =
  391. Clip3(-sps->wp_offset_half_range_c, sps->wp_offset_half_range_c - 1,
  392. (sps->wp_offset_half_range_c +
  393. slice_hdr->pred_weight_table.delta_chroma_offset_l1[i][j] -
  394. ((sps->wp_offset_half_range_c * chroma_weight_l1) >>
  395. slice_hdr->pred_weight_table.chroma_log2_weight_denom)));
  396. }
  397. }
  398. }
  399. SHDR_TO_SP(five_minus_max_num_merge_cand);
  400. // TODO(jkardatzke): Remove this guard once Chrome has libva uprev'd to 2.6.0.
  401. #if BUILDFLAG(IS_CHROMEOS_ASH)
  402. slice_param_.slice_data_num_emu_prevn_bytes =
  403. slice_hdr->header_emulation_prevention_bytes;
  404. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  405. if (IsTranscrypted()) {
  406. // We use the encrypted region of the data as the actual slice data.
  407. CHECK_EQ(subsamples.size(), 1u);
  408. last_slice_data_ = data + subsamples[0].clear_bytes;
  409. last_slice_size_ = subsamples[0].cypher_bytes;
  410. last_transcrypt_params_ = GetDecryptKeyId();
  411. return DecodeStatus::kOk;
  412. }
  413. last_slice_data_ = data;
  414. last_slice_size_ = size;
  415. return DecodeStatus::kOk;
  416. }
  417. DecodeStatus H265VaapiVideoDecoderDelegate::SubmitDecode(
  418. scoped_refptr<H265Picture> pic) {
  419. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  420. if (!SubmitPriorSliceDataIfPresent(true)) {
  421. DLOG(ERROR) << "Failure submitting prior slice data";
  422. return DecodeStatus::kFail;
  423. }
  424. #if BUILDFLAG(IS_CHROMEOS_ASH)
  425. if (IsEncryptedSession() &&
  426. !vaapi_wrapper_->SubmitBuffer(VAEncryptionParameterBufferType,
  427. sizeof(crypto_params_), &crypto_params_)) {
  428. return DecodeStatus::kFail;
  429. }
  430. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  431. const VaapiH265Picture* vaapi_pic = pic->AsVaapiH265Picture();
  432. CHECK(
  433. gfx::Rect(vaapi_pic->va_surface()->size()).Contains(pic->visible_rect()));
  434. const bool success = vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(
  435. vaapi_pic->GetVASurfaceID());
  436. ref_pic_list_pocs_.clear();
  437. #if BUILDFLAG(IS_CHROMEOS_ASH)
  438. encryption_segment_info_.clear();
  439. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  440. if (!success && NeedsProtectedSessionRecovery())
  441. return DecodeStatus::kTryAgain;
  442. if (success && IsEncryptedSession())
  443. ProtectedDecodedSucceeded();
  444. return success ? DecodeStatus::kOk : DecodeStatus::kFail;
  445. }
  446. bool H265VaapiVideoDecoderDelegate::OutputPicture(
  447. scoped_refptr<H265Picture> pic) {
  448. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  449. const VaapiH265Picture* vaapi_pic = pic->AsVaapiH265Picture();
  450. vaapi_dec_->SurfaceReady(vaapi_pic->va_surface(), vaapi_pic->bitstream_id(),
  451. vaapi_pic->visible_rect(),
  452. vaapi_pic->get_colorspace());
  453. return true;
  454. }
  455. void H265VaapiVideoDecoderDelegate::Reset() {
  456. DETACH_FROM_SEQUENCE(sequence_checker_);
  457. vaapi_wrapper_->DestroyPendingBuffers();
  458. ref_pic_list_pocs_.clear();
  459. #if BUILDFLAG(IS_CHROMEOS_ASH)
  460. encryption_segment_info_.clear();
  461. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  462. last_slice_data_ = nullptr;
  463. last_slice_size_ = 0;
  464. last_transcrypt_params_.clear();
  465. }
  466. DecodeStatus H265VaapiVideoDecoderDelegate::SetStream(
  467. base::span<const uint8_t> /*stream*/,
  468. const DecryptConfig* decrypt_config) {
  469. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  470. if (!decrypt_config)
  471. return Status::kOk;
  472. return SetDecryptConfig(decrypt_config->Clone()) ? Status::kOk
  473. : Status::kFail;
  474. }
  475. void H265VaapiVideoDecoderDelegate::FillVAPicture(
  476. VAPictureHEVC* va_pic,
  477. scoped_refptr<H265Picture> pic) {
  478. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  479. va_pic->picture_id = pic->AsVaapiH265Picture()->GetVASurfaceID();
  480. va_pic->pic_order_cnt = pic->pic_order_cnt_val_;
  481. va_pic->flags = 0;
  482. switch (pic->ref_) {
  483. case H265Picture::kShortTermCurrBefore:
  484. va_pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
  485. break;
  486. case H265Picture::kShortTermCurrAfter:
  487. va_pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_AFTER;
  488. break;
  489. case H265Picture::kLongTermCurr:
  490. va_pic->flags |= VA_PICTURE_HEVC_RPS_LT_CURR;
  491. break;
  492. default: // We don't flag the other ref pic types.
  493. break;
  494. }
  495. if (pic->IsLongTermRef())
  496. va_pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
  497. }
  498. void H265VaapiVideoDecoderDelegate::FillVARefFramesFromRefList(
  499. const H265Picture::Vector& ref_pic_list,
  500. VAPictureHEVC* va_pics) {
  501. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  502. ref_pic_list_pocs_.clear();
  503. for (auto& it : ref_pic_list) {
  504. if (!it->IsUnused()) {
  505. FillVAPicture(&va_pics[ref_pic_list_pocs_.size()], it);
  506. ref_pic_list_pocs_.push_back(it->pic_order_cnt_val_);
  507. }
  508. }
  509. }
  510. int H265VaapiVideoDecoderDelegate::GetRefPicIndex(int poc) {
  511. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  512. for (size_t i = 0; i < ref_pic_list_pocs_.size(); ++i) {
  513. if (ref_pic_list_pocs_[i] == poc)
  514. return static_cast<int>(i);
  515. }
  516. return kInvalidRefPicIndex;
  517. }
  518. bool H265VaapiVideoDecoderDelegate::SubmitPriorSliceDataIfPresent(
  519. bool last_slice) {
  520. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  521. if (!last_slice_data_) {
  522. // No prior slice data to submit.
  523. return true;
  524. }
  525. if (last_slice)
  526. slice_param_.LongSliceFlags.fields.LastSliceOfPic = 1;
  527. bool success;
  528. if (IsTranscrypted()) {
  529. success = vaapi_wrapper_->SubmitBuffers(
  530. {{VAProtectedSliceDataBufferType, last_transcrypt_params_.length(),
  531. last_transcrypt_params_.data()},
  532. {VASliceParameterBufferType, sizeof(slice_param_), &slice_param_},
  533. {VASliceDataBufferType, last_slice_size_, last_slice_data_}});
  534. } else {
  535. success = vaapi_wrapper_->SubmitBuffers(
  536. {{VASliceParameterBufferType, sizeof(slice_param_), &slice_param_},
  537. {VASliceDataBufferType, last_slice_size_, last_slice_data_}});
  538. }
  539. last_slice_data_ = nullptr;
  540. last_slice_size_ = 0;
  541. last_transcrypt_params_.clear();
  542. return success;
  543. }
  544. } // namespace media