| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
| 13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 14 #include "content/common/gpu/gpu_channel.h" | 14 #include "content/common/gpu/gpu_channel.h" |
| 15 #include "content/common/gpu/media/accelerated_video_decoder.h" | 15 #include "content/common/gpu/media/accelerated_video_decoder.h" |
| 16 #include "content/common/gpu/media/h264_decoder.h" | 16 #include "content/common/gpu/media/h264_decoder.h" |
| 17 #include "content/common/gpu/media/vaapi_picture.h" | 17 #include "content/common/gpu/media/vaapi_picture.h" |
| 18 #include "content/common/gpu/media/vp8_decoder.h" | 18 #include "content/common/gpu/media/vp8_decoder.h" |
| 19 #include "content/common/gpu/media/vp9_decoder.h" | |
| 20 #include "media/base/bind_to_current_loop.h" | 19 #include "media/base/bind_to_current_loop.h" |
| 21 #include "media/video/picture.h" | 20 #include "media/video/picture.h" |
| 22 #include "third_party/libva/va/va_dec_vp8.h" | 21 #include "third_party/libva/va/va_dec_vp8.h" |
| 23 #include "ui/gl/gl_bindings.h" | 22 #include "ui/gl/gl_bindings.h" |
| 24 #include "ui/gl/gl_image.h" | 23 #include "ui/gl/gl_image.h" |
| 25 | 24 |
| 26 namespace content { | 25 namespace content { |
| 27 | 26 |
| 28 namespace { | 27 namespace { |
| 29 // UMA errors that the VaapiVideoDecodeAccelerator class reports. | 28 // UMA errors that the VaapiVideoDecodeAccelerator class reports. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 private: | 191 private: |
| 193 scoped_refptr<VaapiDecodeSurface> VP8PictureToVaapiDecodeSurface( | 192 scoped_refptr<VaapiDecodeSurface> VP8PictureToVaapiDecodeSurface( |
| 194 const scoped_refptr<VP8Picture>& pic); | 193 const scoped_refptr<VP8Picture>& pic); |
| 195 | 194 |
| 196 VaapiWrapper* vaapi_wrapper_; | 195 VaapiWrapper* vaapi_wrapper_; |
| 197 VaapiVideoDecodeAccelerator* vaapi_dec_; | 196 VaapiVideoDecodeAccelerator* vaapi_dec_; |
| 198 | 197 |
| 199 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Accelerator); | 198 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Accelerator); |
| 200 }; | 199 }; |
| 201 | 200 |
| 202 class VaapiVP9Picture : public VP9Picture { | |
| 203 public: | |
| 204 VaapiVP9Picture( | |
| 205 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& | |
| 206 dec_surface); | |
| 207 | |
| 208 VaapiVP9Picture* AsVaapiVP9Picture() override { return this; } | |
| 209 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { | |
| 210 return dec_surface_; | |
| 211 } | |
| 212 | |
| 213 private: | |
| 214 ~VaapiVP9Picture() override; | |
| 215 | |
| 216 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; | |
| 217 | |
| 218 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Picture); | |
| 219 }; | |
| 220 | |
| 221 VaapiVP9Picture::VaapiVP9Picture( | |
| 222 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& | |
| 223 dec_surface) | |
| 224 : dec_surface_(dec_surface) {} | |
| 225 | |
| 226 VaapiVP9Picture::~VaapiVP9Picture() {} | |
| 227 | |
| 228 class VaapiVideoDecodeAccelerator::VaapiVP9Accelerator | |
| 229 : public VP9Decoder::VP9Accelerator { | |
| 230 public: | |
| 231 VaapiVP9Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, | |
| 232 VaapiWrapper* vaapi_wrapper); | |
| 233 ~VaapiVP9Accelerator() override; | |
| 234 | |
| 235 // VP9Decoder::VP9Accelerator implementation. | |
| 236 scoped_refptr<VP9Picture> CreateVP9Picture() override; | |
| 237 | |
| 238 bool SubmitDecode( | |
| 239 const scoped_refptr<VP9Picture>& pic, | |
| 240 const media::Vp9Segmentation& seg, | |
| 241 const media::Vp9LoopFilter& lf, | |
| 242 const std::vector<scoped_refptr<VP9Picture>>& ref_pictures) override; | |
| 243 | |
| 244 bool OutputPicture(const scoped_refptr<VP9Picture>& pic) override; | |
| 245 | |
| 246 private: | |
| 247 scoped_refptr<VaapiDecodeSurface> VP9PictureToVaapiDecodeSurface( | |
| 248 const scoped_refptr<VP9Picture>& pic); | |
| 249 | |
| 250 VaapiWrapper* vaapi_wrapper_; | |
| 251 VaapiVideoDecodeAccelerator* vaapi_dec_; | |
| 252 | |
| 253 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator); | |
| 254 }; | |
| 255 | |
| 256 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0), size(0) { | 201 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0), size(0) { |
| 257 } | 202 } |
| 258 | 203 |
| 259 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { | 204 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { |
| 260 } | 205 } |
| 261 | 206 |
| 262 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { | 207 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { |
| 263 if (message_loop_ != base::MessageLoop::current()) { | 208 if (message_loop_ != base::MessageLoop::current()) { |
| 264 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 209 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
| 265 message_loop_->PostTask(FROM_HERE, base::Bind( | 210 message_loop_->PostTask(FROM_HERE, base::Bind( |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 294 } |
| 350 | 295 |
| 351 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { | 296 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { |
| 352 h264_accelerator_.reset( | 297 h264_accelerator_.reset( |
| 353 new VaapiH264Accelerator(this, vaapi_wrapper_.get())); | 298 new VaapiH264Accelerator(this, vaapi_wrapper_.get())); |
| 354 decoder_.reset(new H264Decoder(h264_accelerator_.get())); | 299 decoder_.reset(new H264Decoder(h264_accelerator_.get())); |
| 355 } else if (profile >= media::VP8PROFILE_MIN && | 300 } else if (profile >= media::VP8PROFILE_MIN && |
| 356 profile <= media::VP8PROFILE_MAX) { | 301 profile <= media::VP8PROFILE_MAX) { |
| 357 vp8_accelerator_.reset(new VaapiVP8Accelerator(this, vaapi_wrapper_.get())); | 302 vp8_accelerator_.reset(new VaapiVP8Accelerator(this, vaapi_wrapper_.get())); |
| 358 decoder_.reset(new VP8Decoder(vp8_accelerator_.get())); | 303 decoder_.reset(new VP8Decoder(vp8_accelerator_.get())); |
| 359 } else if (profile >= media::VP9PROFILE_MIN && | |
| 360 profile <= media::VP9PROFILE_MAX) { | |
| 361 vp9_accelerator_.reset(new VaapiVP9Accelerator(this, vaapi_wrapper_.get())); | |
| 362 decoder_.reset(new VP9Decoder(vp9_accelerator_.get())); | |
| 363 } else { | 304 } else { |
| 364 DLOG(ERROR) << "Unsupported profile " << profile; | 305 DLOG(ERROR) << "Unsupported profile " << profile; |
| 365 return false; | 306 return false; |
| 366 } | 307 } |
| 367 | 308 |
| 368 CHECK(decoder_thread_.Start()); | 309 CHECK(decoder_thread_.Start()); |
| 369 decoder_thread_task_runner_ = decoder_thread_.task_runner(); | 310 decoder_thread_task_runner_ = decoder_thread_.task_runner(); |
| 370 | 311 |
| 371 state_ = kIdle; | 312 state_ = kIdle; |
| 372 return true; | 313 return true; |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 const media::H264SPS* sps, | 980 const media::H264SPS* sps, |
| 1040 const media::H264PPS* pps, | 981 const media::H264PPS* pps, |
| 1041 const H264DPB& dpb, | 982 const H264DPB& dpb, |
| 1042 const H264Picture::Vector& ref_pic_listp0, | 983 const H264Picture::Vector& ref_pic_listp0, |
| 1043 const H264Picture::Vector& ref_pic_listb0, | 984 const H264Picture::Vector& ref_pic_listb0, |
| 1044 const H264Picture::Vector& ref_pic_listb1, | 985 const H264Picture::Vector& ref_pic_listb1, |
| 1045 const scoped_refptr<H264Picture>& pic) { | 986 const scoped_refptr<H264Picture>& pic) { |
| 1046 VAPictureParameterBufferH264 pic_param; | 987 VAPictureParameterBufferH264 pic_param; |
| 1047 memset(&pic_param, 0, sizeof(pic_param)); | 988 memset(&pic_param, 0, sizeof(pic_param)); |
| 1048 | 989 |
| 1049 #define FROM_SPS_TO_PP(a) pic_param.a = sps->a | 990 #define FROM_SPS_TO_PP(a) pic_param.a = sps->a; |
| 1050 #define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a | 991 #define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a; |
| 1051 FROM_SPS_TO_PP2(pic_width_in_mbs_minus1, picture_width_in_mbs_minus1); | 992 FROM_SPS_TO_PP2(pic_width_in_mbs_minus1, picture_width_in_mbs_minus1); |
| 1052 // This assumes non-interlaced video | 993 // This assumes non-interlaced video |
| 1053 FROM_SPS_TO_PP2(pic_height_in_map_units_minus1, picture_height_in_mbs_minus1); | 994 FROM_SPS_TO_PP2(pic_height_in_map_units_minus1, picture_height_in_mbs_minus1); |
| 1054 FROM_SPS_TO_PP(bit_depth_luma_minus8); | 995 FROM_SPS_TO_PP(bit_depth_luma_minus8); |
| 1055 FROM_SPS_TO_PP(bit_depth_chroma_minus8); | 996 FROM_SPS_TO_PP(bit_depth_chroma_minus8); |
| 1056 #undef FROM_SPS_TO_PP | 997 #undef FROM_SPS_TO_PP |
| 1057 #undef FROM_SPS_TO_PP2 | 998 #undef FROM_SPS_TO_PP2 |
| 1058 | 999 |
| 1059 #define FROM_SPS_TO_PP_SF(a) pic_param.seq_fields.bits.a = sps->a | 1000 #define FROM_SPS_TO_PP_SF(a) pic_param.seq_fields.bits.a = sps->a; |
| 1060 #define FROM_SPS_TO_PP_SF2(a, b) pic_param.seq_fields.bits.b = sps->a | 1001 #define FROM_SPS_TO_PP_SF2(a, b) pic_param.seq_fields.bits.b = sps->a; |
| 1061 FROM_SPS_TO_PP_SF(chroma_format_idc); | 1002 FROM_SPS_TO_PP_SF(chroma_format_idc); |
| 1062 FROM_SPS_TO_PP_SF2(separate_colour_plane_flag, | 1003 FROM_SPS_TO_PP_SF2(separate_colour_plane_flag, |
| 1063 residual_colour_transform_flag); | 1004 residual_colour_transform_flag); |
| 1064 FROM_SPS_TO_PP_SF(gaps_in_frame_num_value_allowed_flag); | 1005 FROM_SPS_TO_PP_SF(gaps_in_frame_num_value_allowed_flag); |
| 1065 FROM_SPS_TO_PP_SF(frame_mbs_only_flag); | 1006 FROM_SPS_TO_PP_SF(frame_mbs_only_flag); |
| 1066 FROM_SPS_TO_PP_SF(mb_adaptive_frame_field_flag); | 1007 FROM_SPS_TO_PP_SF(mb_adaptive_frame_field_flag); |
| 1067 FROM_SPS_TO_PP_SF(direct_8x8_inference_flag); | 1008 FROM_SPS_TO_PP_SF(direct_8x8_inference_flag); |
| 1068 pic_param.seq_fields.bits.MinLumaBiPredSize8x8 = (sps->level_idc >= 31); | 1009 pic_param.seq_fields.bits.MinLumaBiPredSize8x8 = (sps->level_idc >= 31); |
| 1069 FROM_SPS_TO_PP_SF(log2_max_frame_num_minus4); | 1010 FROM_SPS_TO_PP_SF(log2_max_frame_num_minus4); |
| 1070 FROM_SPS_TO_PP_SF(pic_order_cnt_type); | 1011 FROM_SPS_TO_PP_SF(pic_order_cnt_type); |
| 1071 FROM_SPS_TO_PP_SF(log2_max_pic_order_cnt_lsb_minus4); | 1012 FROM_SPS_TO_PP_SF(log2_max_pic_order_cnt_lsb_minus4); |
| 1072 FROM_SPS_TO_PP_SF(delta_pic_order_always_zero_flag); | 1013 FROM_SPS_TO_PP_SF(delta_pic_order_always_zero_flag); |
| 1073 #undef FROM_SPS_TO_PP_SF | 1014 #undef FROM_SPS_TO_PP_SF |
| 1074 #undef FROM_SPS_TO_PP_SF2 | 1015 #undef FROM_SPS_TO_PP_SF2 |
| 1075 | 1016 |
| 1076 #define FROM_PPS_TO_PP(a) pic_param.a = pps->a | 1017 #define FROM_PPS_TO_PP(a) pic_param.a = pps->a; |
| 1077 FROM_PPS_TO_PP(num_slice_groups_minus1); | 1018 FROM_PPS_TO_PP(num_slice_groups_minus1); |
| 1078 pic_param.slice_group_map_type = 0; | 1019 pic_param.slice_group_map_type = 0; |
| 1079 pic_param.slice_group_change_rate_minus1 = 0; | 1020 pic_param.slice_group_change_rate_minus1 = 0; |
| 1080 FROM_PPS_TO_PP(pic_init_qp_minus26); | 1021 FROM_PPS_TO_PP(pic_init_qp_minus26); |
| 1081 FROM_PPS_TO_PP(pic_init_qs_minus26); | 1022 FROM_PPS_TO_PP(pic_init_qs_minus26); |
| 1082 FROM_PPS_TO_PP(chroma_qp_index_offset); | 1023 FROM_PPS_TO_PP(chroma_qp_index_offset); |
| 1083 FROM_PPS_TO_PP(second_chroma_qp_index_offset); | 1024 FROM_PPS_TO_PP(second_chroma_qp_index_offset); |
| 1084 #undef FROM_PPS_TO_PP | 1025 #undef FROM_PPS_TO_PP |
| 1085 | 1026 |
| 1086 #define FROM_PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = pps->a | 1027 #define FROM_PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = pps->a; |
| 1087 #define FROM_PPS_TO_PP_PF2(a, b) pic_param.pic_fields.bits.b = pps->a | 1028 #define FROM_PPS_TO_PP_PF2(a, b) pic_param.pic_fields.bits.b = pps->a; |
| 1088 FROM_PPS_TO_PP_PF(entropy_coding_mode_flag); | 1029 FROM_PPS_TO_PP_PF(entropy_coding_mode_flag); |
| 1089 FROM_PPS_TO_PP_PF(weighted_pred_flag); | 1030 FROM_PPS_TO_PP_PF(weighted_pred_flag); |
| 1090 FROM_PPS_TO_PP_PF(weighted_bipred_idc); | 1031 FROM_PPS_TO_PP_PF(weighted_bipred_idc); |
| 1091 FROM_PPS_TO_PP_PF(transform_8x8_mode_flag); | 1032 FROM_PPS_TO_PP_PF(transform_8x8_mode_flag); |
| 1092 | 1033 |
| 1093 pic_param.pic_fields.bits.field_pic_flag = 0; | 1034 pic_param.pic_fields.bits.field_pic_flag = 0; |
| 1094 FROM_PPS_TO_PP_PF(constrained_intra_pred_flag); | 1035 FROM_PPS_TO_PP_PF(constrained_intra_pred_flag); |
| 1095 FROM_PPS_TO_PP_PF2(bottom_field_pic_order_in_frame_present_flag, | 1036 FROM_PPS_TO_PP_PF2(bottom_field_pic_order_in_frame_present_flag, |
| 1096 pic_order_present_flag); | 1037 pic_order_present_flag); |
| 1097 FROM_PPS_TO_PP_PF(deblocking_filter_control_present_flag); | 1038 FROM_PPS_TO_PP_PF(deblocking_filter_control_present_flag); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 const uint8_t* data, | 1100 const uint8_t* data, |
| 1160 size_t size) { | 1101 size_t size) { |
| 1161 VASliceParameterBufferH264 slice_param; | 1102 VASliceParameterBufferH264 slice_param; |
| 1162 memset(&slice_param, 0, sizeof(slice_param)); | 1103 memset(&slice_param, 0, sizeof(slice_param)); |
| 1163 | 1104 |
| 1164 slice_param.slice_data_size = slice_hdr->nalu_size; | 1105 slice_param.slice_data_size = slice_hdr->nalu_size; |
| 1165 slice_param.slice_data_offset = 0; | 1106 slice_param.slice_data_offset = 0; |
| 1166 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | 1107 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; |
| 1167 slice_param.slice_data_bit_offset = slice_hdr->header_bit_size; | 1108 slice_param.slice_data_bit_offset = slice_hdr->header_bit_size; |
| 1168 | 1109 |
| 1169 #define SHDRToSP(a) slice_param.a = slice_hdr->a | 1110 #define SHDRToSP(a) slice_param.a = slice_hdr->a; |
| 1170 SHDRToSP(first_mb_in_slice); | 1111 SHDRToSP(first_mb_in_slice); |
| 1171 slice_param.slice_type = slice_hdr->slice_type % 5; | 1112 slice_param.slice_type = slice_hdr->slice_type % 5; |
| 1172 SHDRToSP(direct_spatial_mv_pred_flag); | 1113 SHDRToSP(direct_spatial_mv_pred_flag); |
| 1173 | 1114 |
| 1174 // TODO posciak: make sure parser sets those even when override flags | 1115 // TODO posciak: make sure parser sets those even when override flags |
| 1175 // in slice header is off. | 1116 // in slice header is off. |
| 1176 SHDRToSP(num_ref_idx_l0_active_minus1); | 1117 SHDRToSP(num_ref_idx_l0_active_minus1); |
| 1177 SHDRToSP(num_ref_idx_l1_active_minus1); | 1118 SHDRToSP(num_ref_idx_l1_active_minus1); |
| 1178 SHDRToSP(cabac_init_idc); | 1119 SHDRToSP(cabac_init_idc); |
| 1179 SHDRToSP(slice_qp_delta); | 1120 SHDRToSP(slice_qp_delta); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 VP8PictureToVaapiDecodeSurface(alt_frame); | 1383 VP8PictureToVaapiDecodeSurface(alt_frame); |
| 1443 pic_param.alt_ref_frame = alt_frame_surface->va_surface()->id(); | 1384 pic_param.alt_ref_frame = alt_frame_surface->va_surface()->id(); |
| 1444 } else { | 1385 } else { |
| 1445 pic_param.alt_ref_frame = VA_INVALID_SURFACE; | 1386 pic_param.alt_ref_frame = VA_INVALID_SURFACE; |
| 1446 } | 1387 } |
| 1447 | 1388 |
| 1448 pic_param.out_of_loop_frame = VA_INVALID_SURFACE; | 1389 pic_param.out_of_loop_frame = VA_INVALID_SURFACE; |
| 1449 | 1390 |
| 1450 const media::Vp8LoopFilterHeader& lf_hdr = frame_hdr->loopfilter_hdr; | 1391 const media::Vp8LoopFilterHeader& lf_hdr = frame_hdr->loopfilter_hdr; |
| 1451 | 1392 |
| 1452 #define FHDR_TO_PP_PF(a, b) pic_param.pic_fields.bits.a = (b) | 1393 #define FHDR_TO_PP_PF(a, b) pic_param.pic_fields.bits.a = (b); |
| 1453 FHDR_TO_PP_PF(key_frame, frame_hdr->IsKeyframe() ? 0 : 1); | 1394 FHDR_TO_PP_PF(key_frame, frame_hdr->IsKeyframe() ? 0 : 1); |
| 1454 FHDR_TO_PP_PF(version, frame_hdr->version); | 1395 FHDR_TO_PP_PF(version, frame_hdr->version); |
| 1455 FHDR_TO_PP_PF(segmentation_enabled, sgmnt_hdr.segmentation_enabled); | 1396 FHDR_TO_PP_PF(segmentation_enabled, sgmnt_hdr.segmentation_enabled); |
| 1456 FHDR_TO_PP_PF(update_mb_segmentation_map, | 1397 FHDR_TO_PP_PF(update_mb_segmentation_map, |
| 1457 sgmnt_hdr.update_mb_segmentation_map); | 1398 sgmnt_hdr.update_mb_segmentation_map); |
| 1458 FHDR_TO_PP_PF(update_segment_feature_data, | 1399 FHDR_TO_PP_PF(update_segment_feature_data, |
| 1459 sgmnt_hdr.update_segment_feature_data); | 1400 sgmnt_hdr.update_segment_feature_data); |
| 1460 FHDR_TO_PP_PF(filter_type, lf_hdr.type); | 1401 FHDR_TO_PP_PF(filter_type, lf_hdr.type); |
| 1461 FHDR_TO_PP_PF(sharpness_level, lf_hdr.sharpness_level); | 1402 FHDR_TO_PP_PF(sharpness_level, lf_hdr.sharpness_level); |
| 1462 FHDR_TO_PP_PF(loop_filter_adj_enable, lf_hdr.loop_filter_adj_enable); | 1403 FHDR_TO_PP_PF(loop_filter_adj_enable, lf_hdr.loop_filter_adj_enable); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1492 arraysize(lf_hdr.mb_mode_delta) == | 1433 arraysize(lf_hdr.mb_mode_delta) == |
| 1493 arraysize(pic_param.loop_filter_deltas_mode) && | 1434 arraysize(pic_param.loop_filter_deltas_mode) && |
| 1494 arraysize(lf_hdr.ref_frame_delta) == | 1435 arraysize(lf_hdr.ref_frame_delta) == |
| 1495 arraysize(lf_hdr.mb_mode_delta), | 1436 arraysize(lf_hdr.mb_mode_delta), |
| 1496 "loop filter deltas arrays size mismatch"); | 1437 "loop filter deltas arrays size mismatch"); |
| 1497 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) { | 1438 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) { |
| 1498 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i]; | 1439 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i]; |
| 1499 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i]; | 1440 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i]; |
| 1500 } | 1441 } |
| 1501 | 1442 |
| 1502 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a | 1443 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a; |
| 1503 FHDR_TO_PP(prob_skip_false); | 1444 FHDR_TO_PP(prob_skip_false); |
| 1504 FHDR_TO_PP(prob_intra); | 1445 FHDR_TO_PP(prob_intra); |
| 1505 FHDR_TO_PP(prob_last); | 1446 FHDR_TO_PP(prob_last); |
| 1506 FHDR_TO_PP(prob_gf); | 1447 FHDR_TO_PP(prob_gf); |
| 1507 #undef FHDR_TO_PP | 1448 #undef FHDR_TO_PP |
| 1508 | 1449 |
| 1509 ARRAY_MEMCPY_CHECKED(pic_param.y_mode_probs, entr_hdr.y_mode_probs); | 1450 ARRAY_MEMCPY_CHECKED(pic_param.y_mode_probs, entr_hdr.y_mode_probs); |
| 1510 ARRAY_MEMCPY_CHECKED(pic_param.uv_mode_probs, entr_hdr.uv_mode_probs); | 1451 ARRAY_MEMCPY_CHECKED(pic_param.uv_mode_probs, entr_hdr.uv_mode_probs); |
| 1511 ARRAY_MEMCPY_CHECKED(pic_param.mv_probs, entr_hdr.mv_probs); | 1452 ARRAY_MEMCPY_CHECKED(pic_param.mv_probs, entr_hdr.mv_probs); |
| 1512 | 1453 |
| 1513 pic_param.bool_coder_ctx.range = frame_hdr->bool_dec_range; | 1454 pic_param.bool_coder_ctx.range = frame_hdr->bool_dec_range; |
| 1514 pic_param.bool_coder_ctx.value = frame_hdr->bool_dec_value; | 1455 pic_param.bool_coder_ctx.value = frame_hdr->bool_dec_value; |
| 1515 pic_param.bool_coder_ctx.count = frame_hdr->bool_dec_count; | 1456 pic_param.bool_coder_ctx.count = frame_hdr->bool_dec_count; |
| 1516 | 1457 |
| 1517 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, | 1458 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, |
| 1518 sizeof(pic_param), &pic_param)) | 1459 sizeof(VAPictureParameterBufferVP8), |
| 1460 &pic_param)) |
| 1519 return false; | 1461 return false; |
| 1520 | 1462 |
| 1521 VASliceParameterBufferVP8 slice_param; | 1463 VASliceParameterBufferVP8 slice_param; |
| 1522 memset(&slice_param, 0, sizeof(slice_param)); | 1464 memset(&slice_param, 0, sizeof(VASliceParameterBufferVP8)); |
| 1523 slice_param.slice_data_size = frame_hdr->frame_size; | 1465 slice_param.slice_data_size = frame_hdr->frame_size; |
| 1524 slice_param.slice_data_offset = frame_hdr->first_part_offset; | 1466 slice_param.slice_data_offset = frame_hdr->first_part_offset; |
| 1525 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | 1467 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; |
| 1526 slice_param.macroblock_offset = frame_hdr->macroblock_bit_offset; | 1468 slice_param.macroblock_offset = frame_hdr->macroblock_bit_offset; |
| 1527 // Number of DCT partitions plus control partition. | 1469 // Number of DCT partitions plus control partition. |
| 1528 slice_param.num_of_partitions = frame_hdr->num_of_dct_partitions + 1; | 1470 slice_param.num_of_partitions = frame_hdr->num_of_dct_partitions + 1; |
| 1529 | 1471 |
| 1530 // Per VAAPI, this size only includes the size of the macroblock data in | 1472 // Per VAAPI, this size only includes the size of the macroblock data in |
| 1531 // the first partition (in bytes), so we have to subtract the header size. | 1473 // the first partition (in bytes), so we have to subtract the header size. |
| 1532 slice_param.partition_size[0] = | 1474 slice_param.partition_size[0] = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1562 } | 1504 } |
| 1563 | 1505 |
| 1564 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> | 1506 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> |
| 1565 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator:: | 1507 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator:: |
| 1566 VP8PictureToVaapiDecodeSurface(const scoped_refptr<VP8Picture>& pic) { | 1508 VP8PictureToVaapiDecodeSurface(const scoped_refptr<VP8Picture>& pic) { |
| 1567 VaapiVP8Picture* vaapi_pic = pic->AsVaapiVP8Picture(); | 1509 VaapiVP8Picture* vaapi_pic = pic->AsVaapiVP8Picture(); |
| 1568 CHECK(vaapi_pic); | 1510 CHECK(vaapi_pic); |
| 1569 return vaapi_pic->dec_surface(); | 1511 return vaapi_pic->dec_surface(); |
| 1570 } | 1512 } |
| 1571 | 1513 |
| 1572 VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::VaapiVP9Accelerator( | |
| 1573 VaapiVideoDecodeAccelerator* vaapi_dec, | |
| 1574 VaapiWrapper* vaapi_wrapper) | |
| 1575 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { | |
| 1576 DCHECK(vaapi_wrapper_); | |
| 1577 DCHECK(vaapi_dec_); | |
| 1578 } | |
| 1579 | |
| 1580 VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::~VaapiVP9Accelerator() {} | |
| 1581 | |
| 1582 scoped_refptr<VP9Picture> | |
| 1583 VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::CreateVP9Picture() { | |
| 1584 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); | |
| 1585 if (!va_surface) | |
| 1586 return nullptr; | |
| 1587 | |
| 1588 return new VaapiVP9Picture(va_surface); | |
| 1589 } | |
| 1590 | |
| 1591 bool VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::SubmitDecode( | |
| 1592 const scoped_refptr<VP9Picture>& pic, | |
| 1593 const media::Vp9Segmentation& seg, | |
| 1594 const media::Vp9LoopFilter& lf, | |
| 1595 const std::vector<scoped_refptr<VP9Picture>>& ref_pictures) { | |
| 1596 VADecPictureParameterBufferVP9 pic_param; | |
| 1597 memset(&pic_param, 0, sizeof(pic_param)); | |
| 1598 | |
| 1599 const media::Vp9FrameHeader* frame_hdr = pic->frame_hdr.get(); | |
| 1600 DCHECK(frame_hdr); | |
| 1601 | |
| 1602 if (frame_hdr->profile != 0) { | |
| 1603 DVLOG(1) << "Unsupported profile" << frame_hdr->profile; | |
| 1604 return false; | |
| 1605 } | |
| 1606 | |
| 1607 pic_param.frame_width = base::checked_cast<uint16_t>(frame_hdr->width); | |
| 1608 pic_param.frame_height = base::checked_cast<uint16_t>(frame_hdr->height); | |
| 1609 | |
| 1610 CHECK_EQ(ref_pictures.size(), arraysize(pic_param.reference_frames)); | |
| 1611 for (size_t i = 0; i < arraysize(pic_param.reference_frames); ++i) { | |
| 1612 VASurfaceID va_surface_id; | |
| 1613 if (ref_pictures[i]) { | |
| 1614 scoped_refptr<VaapiDecodeSurface> surface = | |
| 1615 VP9PictureToVaapiDecodeSurface(ref_pictures[i]); | |
| 1616 va_surface_id = surface->va_surface()->id(); | |
| 1617 } else { | |
| 1618 va_surface_id = VA_INVALID_SURFACE; | |
| 1619 } | |
| 1620 | |
| 1621 pic_param.reference_frames[i] = va_surface_id; | |
| 1622 } | |
| 1623 | |
| 1624 #define FHDR_TO_PP_PF1(a) pic_param.pic_fields.bits.a = frame_hdr->a | |
| 1625 #define FHDR_TO_PP_PF2(a, b) pic_param.pic_fields.bits.a = b | |
| 1626 FHDR_TO_PP_PF2(subsampling_x, frame_hdr->subsampling_x == 1); | |
| 1627 FHDR_TO_PP_PF2(subsampling_y, frame_hdr->subsampling_y == 1); | |
| 1628 FHDR_TO_PP_PF2(frame_type, frame_hdr->IsKeyframe() ? 0 : 1); | |
| 1629 FHDR_TO_PP_PF1(show_frame); | |
| 1630 FHDR_TO_PP_PF1(error_resilient_mode); | |
| 1631 FHDR_TO_PP_PF1(intra_only); | |
| 1632 FHDR_TO_PP_PF1(allow_high_precision_mv); | |
| 1633 FHDR_TO_PP_PF2(mcomp_filter_type, frame_hdr->interp_filter); | |
| 1634 FHDR_TO_PP_PF1(frame_parallel_decoding_mode); | |
| 1635 FHDR_TO_PP_PF2(reset_frame_context, frame_hdr->reset_context); | |
| 1636 FHDR_TO_PP_PF1(refresh_frame_context); | |
| 1637 FHDR_TO_PP_PF1(frame_context_idx); | |
| 1638 FHDR_TO_PP_PF2(segmentation_enabled, seg.enabled); | |
| 1639 FHDR_TO_PP_PF2(segmentation_temporal_update, seg.temporal_update); | |
| 1640 FHDR_TO_PP_PF2(segmentation_update_map, seg.update_map); | |
| 1641 FHDR_TO_PP_PF2(last_ref_frame, frame_hdr->frame_refs[0]); | |
| 1642 FHDR_TO_PP_PF2(last_ref_frame_sign_bias, frame_hdr->ref_sign_biases[0]); | |
| 1643 FHDR_TO_PP_PF2(golden_ref_frame, frame_hdr->frame_refs[1]); | |
| 1644 FHDR_TO_PP_PF2(golden_ref_frame_sign_bias, frame_hdr->ref_sign_biases[1]); | |
| 1645 FHDR_TO_PP_PF2(alt_ref_frame, frame_hdr->frame_refs[2]); | |
| 1646 FHDR_TO_PP_PF2(alt_ref_frame_sign_bias, frame_hdr->ref_sign_biases[2]); | |
| 1647 FHDR_TO_PP_PF2(lossless_flag, frame_hdr->quant_params.IsLossless()); | |
| 1648 #undef FHDR_TO_PP_PF2 | |
| 1649 #undef FHDR_TO_PP_PF1 | |
| 1650 | |
| 1651 pic_param.filter_level = lf.filter_level; | |
| 1652 pic_param.sharpness_level = lf.sharpness_level; | |
| 1653 pic_param.log2_tile_rows = frame_hdr->log2_tile_rows; | |
| 1654 pic_param.log2_tile_columns = frame_hdr->log2_tile_cols; | |
| 1655 pic_param.frame_header_length_in_bytes = frame_hdr->uncompressed_header_size; | |
| 1656 pic_param.first_partition_size = frame_hdr->first_partition_size; | |
| 1657 | |
| 1658 ARRAY_MEMCPY_CHECKED(pic_param.mb_segment_tree_probs, seg.tree_probs); | |
| 1659 ARRAY_MEMCPY_CHECKED(pic_param.segment_pred_probs, seg.pred_probs); | |
| 1660 | |
| 1661 pic_param.profile = frame_hdr->profile; | |
| 1662 | |
| 1663 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, | |
| 1664 sizeof(pic_param), &pic_param)) | |
| 1665 return false; | |
| 1666 | |
| 1667 VASliceParameterBufferVP9 slice_param; | |
| 1668 memset(&slice_param, 0, sizeof(slice_param)); | |
| 1669 slice_param.slice_data_size = frame_hdr->frame_size; | |
| 1670 slice_param.slice_data_offset = 0; | |
| 1671 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | |
| 1672 | |
| 1673 static_assert(arraysize(media::Vp9Segmentation::feature_enabled) == | |
| 1674 arraysize(slice_param.seg_param), | |
| 1675 "seg_param array of incorrect size"); | |
| 1676 for (size_t i = 0; i < arraysize(slice_param.seg_param); ++i) { | |
| 1677 VASegmentParameterVP9& seg_param = slice_param.seg_param[i]; | |
| 1678 #define SEG_TO_SP_SF(a, b) seg_param.segment_flags.fields.a = b | |
| 1679 SEG_TO_SP_SF( | |
| 1680 segment_reference_enabled, | |
| 1681 seg.FeatureEnabled(i, media::Vp9Segmentation::SEG_LVL_REF_FRAME)); | |
| 1682 SEG_TO_SP_SF(segment_reference, | |
| 1683 seg.FeatureData(i, media::Vp9Segmentation::SEG_LVL_REF_FRAME)); | |
| 1684 SEG_TO_SP_SF(segment_reference_skipped, | |
| 1685 seg.FeatureEnabled(i, media::Vp9Segmentation::SEG_LVL_SKIP)); | |
| 1686 #undef SEG_TO_SP_SF | |
| 1687 | |
| 1688 ARRAY_MEMCPY_CHECKED(seg_param.filter_level, lf.lvl[i]); | |
| 1689 | |
| 1690 seg_param.luma_dc_quant_scale = seg.y_dequant[i][0]; | |
| 1691 seg_param.luma_ac_quant_scale = seg.y_dequant[i][1]; | |
| 1692 seg_param.chroma_dc_quant_scale = seg.uv_dequant[i][0]; | |
| 1693 seg_param.chroma_ac_quant_scale = seg.uv_dequant[i][1]; | |
| 1694 } | |
| 1695 | |
| 1696 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, | |
| 1697 sizeof(slice_param), &slice_param)) | |
| 1698 return false; | |
| 1699 | |
| 1700 void* non_const_ptr = const_cast<uint8*>(frame_hdr->data); | |
| 1701 if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, | |
| 1702 frame_hdr->frame_size, non_const_ptr)) | |
| 1703 return false; | |
| 1704 | |
| 1705 scoped_refptr<VaapiDecodeSurface> dec_surface = | |
| 1706 VP9PictureToVaapiDecodeSurface(pic); | |
| 1707 | |
| 1708 return vaapi_dec_->DecodeSurface(dec_surface); | |
| 1709 } | |
| 1710 | |
| 1711 bool VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::OutputPicture( | |
| 1712 const scoped_refptr<VP9Picture>& pic) { | |
| 1713 scoped_refptr<VaapiDecodeSurface> dec_surface = | |
| 1714 VP9PictureToVaapiDecodeSurface(pic); | |
| 1715 | |
| 1716 vaapi_dec_->SurfaceReady(dec_surface); | |
| 1717 return true; | |
| 1718 } | |
| 1719 | |
| 1720 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> | |
| 1721 VaapiVideoDecodeAccelerator::VaapiVP9Accelerator:: | |
| 1722 VP9PictureToVaapiDecodeSurface(const scoped_refptr<VP9Picture>& pic) { | |
| 1723 VaapiVP9Picture* vaapi_pic = pic->AsVaapiVP9Picture(); | |
| 1724 CHECK(vaapi_pic); | |
| 1725 return vaapi_pic->dec_surface(); | |
| 1726 } | |
| 1727 | |
| 1728 // static | 1514 // static |
| 1729 media::VideoDecodeAccelerator::SupportedProfiles | 1515 media::VideoDecodeAccelerator::SupportedProfiles |
| 1730 VaapiVideoDecodeAccelerator::GetSupportedProfiles() { | 1516 VaapiVideoDecodeAccelerator::GetSupportedProfiles() { |
| 1731 return VaapiWrapper::GetSupportedDecodeProfiles(); | 1517 return VaapiWrapper::GetSupportedDecodeProfiles(); |
| 1732 } | 1518 } |
| 1733 | 1519 |
| 1734 } // namespace content | 1520 } // namespace content |
| OLD | NEW |