| Index: media/gpu/vt_video_decode_accelerator_mac.cc
|
| diff --git a/media/gpu/vt_video_decode_accelerator_mac.cc b/media/gpu/vt_video_decode_accelerator_mac.cc
|
| index e8bcaf7c77a88fbca0cd8e0f0cd442333c7f7e45..48a138f6e3e55ffa405461e3bf885ea64f2ced2f 100644
|
| --- a/media/gpu/vt_video_decode_accelerator_mac.cc
|
| +++ b/media/gpu/vt_video_decode_accelerator_mac.cc
|
| @@ -42,8 +42,10 @@ using media_gpu::StubPathMap;
|
|
|
| namespace media {
|
|
|
| +namespace {
|
| +
|
| // Only H.264 with 4:2:0 chroma sampling is supported.
|
| -static const VideoCodecProfile kSupportedProfiles[] = {
|
| +const VideoCodecProfile kSupportedProfiles[] = {
|
| H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_EXTENDED,
|
| H264PROFILE_HIGH,
|
| // TODO(hubbe): Try to re-enable this again somehow. Currently it seems
|
| @@ -56,21 +58,21 @@ static const VideoCodecProfile kSupportedProfiles[] = {
|
| };
|
|
|
| // Size to use for NALU length headers in AVC format (can be 1, 2, or 4).
|
| -static const int kNALUHeaderLength = 4;
|
| +const int kNALUHeaderLength = 4;
|
|
|
| // We request 5 picture buffers from the client, each of which has a texture ID
|
| // that we can bind decoded frames to. We need enough to satisfy preroll, and
|
| // enough to avoid unnecessary stalling, but no more than that. The resource
|
| // requirements are low, as we don't need the textures to be backed by storage.
|
| -static const int kNumPictureBuffers = limits::kMaxVideoFrames + 1;
|
| +const int kNumPictureBuffers = limits::kMaxVideoFrames + 1;
|
|
|
| // Maximum number of frames to queue for reordering before we stop asking for
|
| // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the
|
| // reorder queue.)
|
| -static const int kMaxReorderQueueSize = 16;
|
| +const int kMaxReorderQueueSize = 16;
|
|
|
| // Build an |image_config| dictionary for VideoToolbox initialization.
|
| -static base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig(
|
| +base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig(
|
| CMVideoDimensions coded_dimensions) {
|
| base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
|
|
|
| @@ -106,11 +108,11 @@ static base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig(
|
| // successful.
|
| //
|
| // TODO(sandersd): Merge with ConfigureDecoder(), as the code is very similar.
|
| -static bool CreateVideoToolboxSession(const uint8_t* sps,
|
| - size_t sps_size,
|
| - const uint8_t* pps,
|
| - size_t pps_size,
|
| - bool require_hardware) {
|
| +bool CreateVideoToolboxSession(const uint8_t* sps,
|
| + size_t sps_size,
|
| + const uint8_t* pps,
|
| + size_t pps_size,
|
| + bool require_hardware) {
|
| const uint8_t* data_ptrs[] = {sps, pps};
|
| const size_t data_sizes[] = {sps_size, pps_size};
|
|
|
| @@ -172,7 +174,7 @@ static bool CreateVideoToolboxSession(const uint8_t* sps,
|
| // must actually create a decompression session. If creating a decompression
|
| // session fails, hardware decoding will be disabled (Initialize() will always
|
| // return false).
|
| -static bool InitializeVideoToolboxInternal() {
|
| +bool InitializeVideoToolboxInternal() {
|
| if (!IsVtInitialized()) {
|
| // CoreVideo is also required, but the loader stops after the first path is
|
| // loaded. Instead we rely on the transitive dependency from VideoToolbox to
|
| @@ -213,34 +215,48 @@ static bool InitializeVideoToolboxInternal() {
|
| return true;
|
| }
|
|
|
| -bool InitializeVideoToolbox() {
|
| - // InitializeVideoToolbox() is called only from the GPU process main thread;
|
| - // once for sandbox warmup, and then once each time a VTVideoDecodeAccelerator
|
| - // is initialized.
|
| - static bool attempted = false;
|
| - static bool succeeded = false;
|
| -
|
| - if (!attempted) {
|
| - attempted = true;
|
| - succeeded = InitializeVideoToolboxInternal();
|
| +// TODO(sandersd): Share this computation with the VAAPI decoder.
|
| +int32_t ComputeReorderWindow(const H264SPS* sps) {
|
| + // TODO(sandersd): Compute MaxDpbFrames.
|
| + int32_t max_dpb_frames = kMaxReorderQueueSize;
|
| +
|
| + // See AVC spec section E.2.1 definition of |max_num_reorder_frames|.
|
| + if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
|
| + return std::min(sps->max_num_reorder_frames, max_dpb_frames);
|
| + } else if (sps->constraint_set3_flag) {
|
| + if (sps->profile_idc == 44 || sps->profile_idc == 86 ||
|
| + sps->profile_idc == 100 || sps->profile_idc == 110 ||
|
| + sps->profile_idc == 122 || sps->profile_idc == 244) {
|
| + return 0;
|
| + }
|
| }
|
| -
|
| - return succeeded;
|
| + return max_dpb_frames;
|
| }
|
|
|
| // Route decoded frame callbacks back into the VTVideoDecodeAccelerator.
|
| -static void OutputThunk(void* decompression_output_refcon,
|
| - void* source_frame_refcon,
|
| - OSStatus status,
|
| - VTDecodeInfoFlags info_flags,
|
| - CVImageBufferRef image_buffer,
|
| - CMTime presentation_time_stamp,
|
| - CMTime presentation_duration) {
|
| +void OutputThunk(void* decompression_output_refcon,
|
| + void* source_frame_refcon,
|
| + OSStatus status,
|
| + VTDecodeInfoFlags info_flags,
|
| + CVImageBufferRef image_buffer,
|
| + CMTime presentation_time_stamp,
|
| + CMTime presentation_duration) {
|
| VTVideoDecodeAccelerator* vda =
|
| reinterpret_cast<VTVideoDecodeAccelerator*>(decompression_output_refcon);
|
| vda->Output(source_frame_refcon, status, image_buffer);
|
| }
|
|
|
| +} // namespace
|
| +
|
| +bool InitializeVideoToolbox() {
|
| + // InitializeVideoToolbox() is called only from the GPU process main thread:
|
| + // once for sandbox warmup, and then once each time a VTVideoDecodeAccelerator
|
| + // is initialized. This ensures that everything is loaded whether or not the
|
| + // sandbox is enabled.
|
| + static bool succeeded = InitializeVideoToolboxInternal();
|
| + return succeeded;
|
| +}
|
| +
|
| VTVideoDecodeAccelerator::Task::Task(TaskType type) : type(type) {}
|
|
|
| VTVideoDecodeAccelerator::Task::Task(const Task& other) = default;
|
| @@ -597,11 +613,7 @@ void VTVideoDecodeAccelerator::DecodeTask(const BitstreamBuffer& bitstream,
|
| if (nalu.nal_unit_type == H264NALU::kIDRSlice)
|
| frame->is_idr = true;
|
|
|
| - if (sps->vui_parameters_present_flag &&
|
| - sps->bitstream_restriction_flag) {
|
| - frame->reorder_window =
|
| - std::min(sps->max_num_reorder_frames, kMaxReorderQueueSize - 1);
|
| - }
|
| + frame->reorder_window = ComputeReorderWindow(sps);
|
| }
|
| has_slice = true;
|
| default:
|
|
|