| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/gpu/vt_video_decode_accelerator_mac.h" | 5 #include "media/gpu/vt_video_decode_accelerator_mac.h" |
| 6 | 6 |
| 7 #include <CoreVideo/CoreVideo.h> | 7 #include <CoreVideo/CoreVideo.h> |
| 8 #include <OpenGL/CGLIOSurface.h> | 8 #include <OpenGL/CGLIOSurface.h> |
| 9 #include <OpenGL/gl.h> | 9 #include <OpenGL/gl.h> |
| 10 #include <stddef.h> | 10 #include <stddef.h> |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 arraysize(pps_small), false)) { | 202 arraysize(pps_small), false)) { |
| 203 DLOG(WARNING) << "Failed to create software VideoToolbox session"; | 203 DLOG(WARNING) << "Failed to create software VideoToolbox session"; |
| 204 return false; | 204 return false; |
| 205 } | 205 } |
| 206 | 206 |
| 207 return true; | 207 return true; |
| 208 } | 208 } |
| 209 | 209 |
| 210 // TODO(sandersd): Share this computation with the VAAPI decoder. | 210 // TODO(sandersd): Share this computation with the VAAPI decoder. |
| 211 int32_t ComputeReorderWindow(const H264SPS* sps) { | 211 int32_t ComputeReorderWindow(const H264SPS* sps) { |
| 212 // When |pic_order_cnt_type| == 2, decode order always matches presentation |
| 213 // order. |
| 214 // TODO(sandersd): For |pic_order_cnt_type| == 1, analyze the delta cycle to |
| 215 // find the minimum required reorder window. |
| 216 if (sps->pic_order_cnt_type == 2) |
| 217 return 0; |
| 218 |
| 212 // TODO(sandersd): Compute MaxDpbFrames. | 219 // TODO(sandersd): Compute MaxDpbFrames. |
| 213 int32_t max_dpb_frames = 16; | 220 int32_t max_dpb_frames = 16; |
| 214 | 221 |
| 215 // See AVC spec section E.2.1 definition of |max_num_reorder_frames|. | 222 // See AVC spec section E.2.1 definition of |max_num_reorder_frames|. |
| 216 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { | 223 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { |
| 217 return std::min(sps->max_num_reorder_frames, max_dpb_frames); | 224 return std::min(sps->max_num_reorder_frames, max_dpb_frames); |
| 218 } else if (sps->constraint_set3_flag) { | 225 } else if (sps->constraint_set3_flag) { |
| 219 if (sps->profile_idc == 44 || sps->profile_idc == 86 || | 226 if (sps->profile_idc == 44 || sps->profile_idc == 86 || |
| 220 sps->profile_idc == 100 || sps->profile_idc == 110 || | 227 sps->profile_idc == 100 || sps->profile_idc == 110 || |
| 221 sps->profile_idc == 122 || sps->profile_idc == 244) { | 228 sps->profile_idc == 122 || sps->profile_idc == 244) { |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 // later, since it comes from the decoder configuration. | 592 // later, since it comes from the decoder configuration. |
| 586 int32_t pic_order_cnt; | 593 int32_t pic_order_cnt; |
| 587 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &pic_order_cnt)) { | 594 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &pic_order_cnt)) { |
| 588 DLOG(ERROR) << "Unable to compute POC"; | 595 DLOG(ERROR) << "Unable to compute POC"; |
| 589 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 596 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
| 590 return; | 597 return; |
| 591 } | 598 } |
| 592 | 599 |
| 593 frame->has_slice = true; | 600 frame->has_slice = true; |
| 594 frame->is_idr = nalu.nal_unit_type == media::H264NALU::kIDRSlice; | 601 frame->is_idr = nalu.nal_unit_type == media::H264NALU::kIDRSlice; |
| 602 frame->has_mmco5 = poc_.IsPendingMMCO5(); |
| 595 frame->pic_order_cnt = pic_order_cnt; | 603 frame->pic_order_cnt = pic_order_cnt; |
| 596 frame->reorder_window = ComputeReorderWindow(sps); | 604 frame->reorder_window = ComputeReorderWindow(sps); |
| 597 } | 605 } |
| 598 | 606 |
| 599 // Intentional fallthrough. | 607 // Intentional fallthrough. |
| 600 default: | 608 default: |
| 601 nalus.push_back(nalu); | 609 nalus.push_back(nalu); |
| 602 data_size += kNALUHeaderLength + nalu.size; | 610 data_size += kNALUHeaderLength + nalu.size; |
| 603 break; | 611 break; |
| 604 } | 612 } |
| 605 } | 613 } |
| 606 | 614 |
| 607 if (frame->is_idr) { | 615 if (frame->is_idr) |
| 608 waiting_for_idr_ = false; | 616 waiting_for_idr_ = false; |
| 609 } | |
| 610 | 617 |
| 611 // If no IDR has been seen yet, skip decoding. Note that Flash sends | 618 // If no IDR has been seen yet, skip decoding. Note that Flash sends |
| 612 // configuration changes as a bitstream with only SPS/PPS; we don't print | 619 // configuration changes as a bitstream with only SPS/PPS; we don't print |
| 613 // error messages for those. | 620 // error messages for those. |
| 614 if (frame->has_slice && waiting_for_idr_) { | 621 if (frame->has_slice && waiting_for_idr_) { |
| 615 if (!missing_idr_logged_) { | 622 if (!missing_idr_logged_) { |
| 616 LOG(ERROR) << "Illegal attempt to decode without IDR. " | 623 LOG(ERROR) << "Illegal attempt to decode without IDR. " |
| 617 << "Discarding decode requests until next IDR."; | 624 << "Discarding decode requests until next IDR."; |
| 618 missing_idr_logged_ = true; | 625 missing_idr_logged_ = true; |
| 619 } | 626 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 bool VTVideoDecodeAccelerator::ProcessTaskQueue() { | 941 bool VTVideoDecodeAccelerator::ProcessTaskQueue() { |
| 935 DVLOG(3) << __func__ << " size=" << task_queue_.size(); | 942 DVLOG(3) << __func__ << " size=" << task_queue_.size(); |
| 936 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); | 943 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); |
| 937 DCHECK_EQ(state_, STATE_DECODING); | 944 DCHECK_EQ(state_, STATE_DECODING); |
| 938 | 945 |
| 939 if (task_queue_.empty()) | 946 if (task_queue_.empty()) |
| 940 return false; | 947 return false; |
| 941 | 948 |
| 942 const Task& task = task_queue_.front(); | 949 const Task& task = task_queue_.front(); |
| 943 switch (task.type) { | 950 switch (task.type) { |
| 944 case TASK_FRAME: | 951 case TASK_FRAME: { |
| 945 if (reorder_queue_.size() < kMaxReorderQueueSize && | 952 bool reorder_queue_has_space = |
| 946 (!task.frame->is_idr || reorder_queue_.empty())) { | 953 reorder_queue_.size() < kMaxReorderQueueSize; |
| 954 bool reorder_queue_flush_needed = |
| 955 task.frame->is_idr || task.frame->has_mmco5; |
| 956 bool reorder_queue_flush_done = reorder_queue_.empty(); |
| 957 if (reorder_queue_has_space && |
| 958 (!reorder_queue_flush_needed || reorder_queue_flush_done)) { |
| 947 DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete"; | 959 DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete"; |
| 948 assigned_bitstream_ids_.erase(task.frame->bitstream_id); | 960 assigned_bitstream_ids_.erase(task.frame->bitstream_id); |
| 949 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); | 961 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); |
| 950 reorder_queue_.push(task.frame); | 962 reorder_queue_.push(task.frame); |
| 951 task_queue_.pop(); | 963 task_queue_.pop(); |
| 952 return true; | 964 return true; |
| 953 } | 965 } |
| 954 return false; | 966 return false; |
| 967 } |
| 955 | 968 |
| 956 case TASK_FLUSH: | 969 case TASK_FLUSH: |
| 957 DCHECK_EQ(task.type, pending_flush_tasks_.front()); | 970 DCHECK_EQ(task.type, pending_flush_tasks_.front()); |
| 958 if (reorder_queue_.size() == 0) { | 971 if (reorder_queue_.size() == 0) { |
| 959 DVLOG(1) << "Flush complete"; | 972 DVLOG(1) << "Flush complete"; |
| 960 pending_flush_tasks_.pop(); | 973 pending_flush_tasks_.pop(); |
| 961 client_->NotifyFlushDone(); | 974 client_->NotifyFlushDone(); |
| 962 task_queue_.pop(); | 975 task_queue_.pop(); |
| 963 return true; | 976 return true; |
| 964 } | 977 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 988 DCHECK_EQ(state_, STATE_DECODING); | 1001 DCHECK_EQ(state_, STATE_DECODING); |
| 989 | 1002 |
| 990 if (reorder_queue_.empty()) | 1003 if (reorder_queue_.empty()) |
| 991 return false; | 1004 return false; |
| 992 | 1005 |
| 993 // If the next task is a flush (because there is a pending flush or becuase | 1006 // If the next task is a flush (because there is a pending flush or becuase |
| 994 // the next frame is an IDR), then we don't need a full reorder buffer to send | 1007 // the next frame is an IDR), then we don't need a full reorder buffer to send |
| 995 // the next frame. | 1008 // the next frame. |
| 996 bool flushing = | 1009 bool flushing = |
| 997 !task_queue_.empty() && (task_queue_.front().type != TASK_FRAME || | 1010 !task_queue_.empty() && (task_queue_.front().type != TASK_FRAME || |
| 998 task_queue_.front().frame->is_idr); | 1011 task_queue_.front().frame->is_idr || |
| 1012 task_queue_.front().frame->has_mmco5); |
| 999 | 1013 |
| 1000 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); | 1014 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); |
| 1001 DVLOG(3) << __func__ << " size=" << reorder_queue_.size() | 1015 DVLOG(3) << __func__ << " size=" << reorder_queue_.size() |
| 1002 << " window=" << reorder_window << " flushing=" << flushing; | 1016 << " window=" << reorder_window << " flushing=" << flushing; |
| 1003 if (flushing || reorder_queue_.size() > reorder_window) { | 1017 if (flushing || reorder_queue_.size() > reorder_window) { |
| 1004 if (ProcessFrame(*reorder_queue_.top())) { | 1018 if (ProcessFrame(*reorder_queue_.top())) { |
| 1005 reorder_queue_.pop(); | 1019 reorder_queue_.pop(); |
| 1006 return true; | 1020 return true; |
| 1007 } | 1021 } |
| 1008 } | 1022 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 SupportedProfile profile; | 1193 SupportedProfile profile; |
| 1180 profile.profile = supported_profile; | 1194 profile.profile = supported_profile; |
| 1181 profile.min_resolution.SetSize(16, 16); | 1195 profile.min_resolution.SetSize(16, 16); |
| 1182 profile.max_resolution.SetSize(4096, 2160); | 1196 profile.max_resolution.SetSize(4096, 2160); |
| 1183 profiles.push_back(profile); | 1197 profiles.push_back(profile); |
| 1184 } | 1198 } |
| 1185 return profiles; | 1199 return profiles; |
| 1186 } | 1200 } |
| 1187 | 1201 |
| 1188 } // namespace media | 1202 } // namespace media |
| OLD | NEW |