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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 if (reorder_queue_.size() < kMaxReorderQueueSize && |
946 (!task.frame->is_idr || reorder_queue_.empty())) { | 953 (!task.frame->is_idr || !task.frame->has_mmco5 || |
Pawel Osciak
2017/02/17 04:53:26
Should this be (!task.frame->is_idr && !task.frame
sandersd (OOO until July 31)
2017/02/18 00:46:34
I expanded the code, hopefully it is clear now.
| |
954 reorder_queue_.empty())) { | |
947 DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete"; | 955 DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete"; |
948 assigned_bitstream_ids_.erase(task.frame->bitstream_id); | 956 assigned_bitstream_ids_.erase(task.frame->bitstream_id); |
949 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); | 957 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); |
950 reorder_queue_.push(task.frame); | 958 reorder_queue_.push(task.frame); |
951 task_queue_.pop(); | 959 task_queue_.pop(); |
952 return true; | 960 return true; |
953 } | 961 } |
954 return false; | 962 return false; |
955 | 963 |
956 case TASK_FLUSH: | 964 case TASK_FLUSH: |
(...skipping 30 matching lines...) Expand all Loading... | |
987 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); | 995 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); |
988 DCHECK_EQ(state_, STATE_DECODING); | 996 DCHECK_EQ(state_, STATE_DECODING); |
989 | 997 |
990 if (reorder_queue_.empty()) | 998 if (reorder_queue_.empty()) |
991 return false; | 999 return false; |
992 | 1000 |
993 // If the next task is a flush (because there is a pending flush or becuase | 1001 // 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 | 1002 // the next frame is an IDR), then we don't need a full reorder buffer to send |
995 // the next frame. | 1003 // the next frame. |
996 bool flushing = | 1004 bool flushing = |
997 !task_queue_.empty() && (task_queue_.front().type != TASK_FRAME || | 1005 !task_queue_.empty() && |
998 task_queue_.front().frame->is_idr); | 1006 (task_queue_.front().type != TASK_FRAME || |
1007 task_queue_.front().frame->is_idr || task_queue_.front().has_mmco5); | |
999 | 1008 |
1000 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); | 1009 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); |
1001 DVLOG(3) << __func__ << " size=" << reorder_queue_.size() | 1010 DVLOG(3) << __func__ << " size=" << reorder_queue_.size() |
1002 << " window=" << reorder_window << " flushing=" << flushing; | 1011 << " window=" << reorder_window << " flushing=" << flushing; |
1003 if (flushing || reorder_queue_.size() > reorder_window) { | 1012 if (flushing || reorder_queue_.size() > reorder_window) { |
1004 if (ProcessFrame(*reorder_queue_.top())) { | 1013 if (ProcessFrame(*reorder_queue_.top())) { |
1005 reorder_queue_.pop(); | 1014 reorder_queue_.pop(); |
1006 return true; | 1015 return true; |
1007 } | 1016 } |
1008 } | 1017 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1179 SupportedProfile profile; | 1188 SupportedProfile profile; |
1180 profile.profile = supported_profile; | 1189 profile.profile = supported_profile; |
1181 profile.min_resolution.SetSize(16, 16); | 1190 profile.min_resolution.SetSize(16, 16); |
1182 profile.max_resolution.SetSize(4096, 2160); | 1191 profile.max_resolution.SetSize(4096, 2160); |
1183 profiles.push_back(profile); | 1192 profiles.push_back(profile); |
1184 } | 1193 } |
1185 return profiles; | 1194 return profiles; |
1186 } | 1195 } |
1187 | 1196 |
1188 } // namespace media | 1197 } // namespace media |
OLD | NEW |