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 |