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 "content/common/gpu/media/vt_video_decode_accelerator_mac.h" | 5 #include "content/common/gpu/media/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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 const BindGLImageCallback& bind_image_cb) | 294 const BindGLImageCallback& bind_image_cb) |
295 : make_context_current_cb_(make_context_current_cb), | 295 : make_context_current_cb_(make_context_current_cb), |
296 bind_image_cb_(bind_image_cb), | 296 bind_image_cb_(bind_image_cb), |
297 client_(nullptr), | 297 client_(nullptr), |
298 state_(STATE_DECODING), | 298 state_(STATE_DECODING), |
299 format_(nullptr), | 299 format_(nullptr), |
300 session_(nullptr), | 300 session_(nullptr), |
301 last_sps_id_(-1), | 301 last_sps_id_(-1), |
302 last_pps_id_(-1), | 302 last_pps_id_(-1), |
303 config_changed_(false), | 303 config_changed_(false), |
| 304 waiting_for_idr_(true), |
304 missing_idr_logged_(false), | 305 missing_idr_logged_(false), |
305 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 306 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
306 decoder_thread_("VTDecoderThread"), | 307 decoder_thread_("VTDecoderThread"), |
307 weak_this_factory_(this) { | 308 weak_this_factory_(this) { |
308 callback_.decompressionOutputCallback = OutputThunk; | 309 callback_.decompressionOutputCallback = OutputThunk; |
309 callback_.decompressionOutputRefCon = this; | 310 callback_.decompressionOutputRefCon = this; |
310 weak_this_ = weak_this_factory_.GetWeakPtr(); | 311 weak_this_ = weak_this_factory_.GetWeakPtr(); |
311 } | 312 } |
312 | 313 |
313 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 314 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 pps.assign(nalu.data, nalu.data + nalu.size); | 552 pps.assign(nalu.data, nalu.data + nalu.size); |
552 break; | 553 break; |
553 | 554 |
554 case media::H264NALU::kSliceDataA: | 555 case media::H264NALU::kSliceDataA: |
555 case media::H264NALU::kSliceDataB: | 556 case media::H264NALU::kSliceDataB: |
556 case media::H264NALU::kSliceDataC: | 557 case media::H264NALU::kSliceDataC: |
557 case media::H264NALU::kNonIDRSlice: | 558 case media::H264NALU::kNonIDRSlice: |
558 case media::H264NALU::kIDRSlice: | 559 case media::H264NALU::kIDRSlice: |
559 // Compute the |pic_order_cnt| for the picture from the first slice. | 560 // Compute the |pic_order_cnt| for the picture from the first slice. |
560 if (!has_slice) { | 561 if (!has_slice) { |
| 562 // Verify that we are not trying to decode a slice without an IDR. |
| 563 if (waiting_for_idr_) { |
| 564 if (nalu.nal_unit_type == media::H264NALU::kIDRSlice) { |
| 565 waiting_for_idr_ = false; |
| 566 } else { |
| 567 // We can't compute anything yet, bail on this frame. |
| 568 has_slice = true; |
| 569 break; |
| 570 } |
| 571 } |
| 572 |
561 media::H264SliceHeader slice_hdr; | 573 media::H264SliceHeader slice_hdr; |
562 result = parser_.ParseSliceHeader(nalu, &slice_hdr); | 574 result = parser_.ParseSliceHeader(nalu, &slice_hdr); |
563 if (result == media::H264Parser::kUnsupportedStream) { | 575 if (result == media::H264Parser::kUnsupportedStream) { |
564 DLOG(ERROR) << "Unsupported slice header"; | 576 DLOG(ERROR) << "Unsupported slice header"; |
565 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); | 577 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); |
566 return; | 578 return; |
567 } | 579 } |
568 if (result != media::H264Parser::kOk) { | 580 if (result != media::H264Parser::kOk) { |
569 DLOG(ERROR) << "Could not parse slice header"; | 581 DLOG(ERROR) << "Could not parse slice header"; |
570 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 582 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 return; | 651 return; |
640 } | 652 } |
641 | 653 |
642 // ConfigureDecoder() calls NotifyError() on failure. | 654 // ConfigureDecoder() calls NotifyError() on failure. |
643 if (!ConfigureDecoder()) | 655 if (!ConfigureDecoder()) |
644 return; | 656 return; |
645 } | 657 } |
646 } | 658 } |
647 | 659 |
648 // If no IDR has been seen yet, skip decoding. | 660 // If no IDR has been seen yet, skip decoding. |
649 if (has_slice && !session_ && config_changed_) { | 661 if (has_slice && (!session_ || waiting_for_idr_) && config_changed_) { |
650 if (!missing_idr_logged_) { | 662 if (!missing_idr_logged_) { |
651 LOG(ERROR) << "Illegal attempt to decode without IDR. " | 663 LOG(ERROR) << "Illegal attempt to decode without IDR. " |
652 << "Discarding decode requests until next IDR."; | 664 << "Discarding decode requests until next IDR."; |
653 missing_idr_logged_ = true; | 665 missing_idr_logged_ = true; |
654 } | 666 } |
655 has_slice = false; | 667 has_slice = false; |
656 } | 668 } |
657 | 669 |
658 // If there is nothing to decode, drop the bitstream buffer by returning an | 670 // If there is nothing to decode, drop the bitstream buffer by returning an |
659 // empty frame. | 671 // empty frame. |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 pending_flush_tasks_.pop(); | 947 pending_flush_tasks_.pop(); |
936 client_->NotifyFlushDone(); | 948 client_->NotifyFlushDone(); |
937 task_queue_.pop(); | 949 task_queue_.pop(); |
938 return true; | 950 return true; |
939 } | 951 } |
940 return false; | 952 return false; |
941 | 953 |
942 case TASK_RESET: | 954 case TASK_RESET: |
943 DCHECK_EQ(task.type, pending_flush_tasks_.front()); | 955 DCHECK_EQ(task.type, pending_flush_tasks_.front()); |
944 if (reorder_queue_.size() == 0) { | 956 if (reorder_queue_.size() == 0) { |
945 last_sps_id_ = -1; | 957 waiting_for_idr_ = true; |
946 last_pps_id_ = -1; | |
947 last_sps_.clear(); | |
948 last_spsext_.clear(); | |
949 last_pps_.clear(); | |
950 poc_.Reset(); | |
951 pending_flush_tasks_.pop(); | 958 pending_flush_tasks_.pop(); |
952 client_->NotifyResetDone(); | 959 client_->NotifyResetDone(); |
953 task_queue_.pop(); | 960 task_queue_.pop(); |
954 return true; | 961 return true; |
955 } | 962 } |
956 return false; | 963 return false; |
957 | 964 |
958 case TASK_DESTROY: | 965 case TASK_DESTROY: |
959 NOTREACHED() << "Can't destroy while in STATE_DECODING."; | 966 NOTREACHED() << "Can't destroy while in STATE_DECODING."; |
960 NotifyError(ILLEGAL_STATE, SFT_PLATFORM_ERROR); | 967 NotifyError(ILLEGAL_STATE, SFT_PLATFORM_ERROR); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 SupportedProfile profile; | 1153 SupportedProfile profile; |
1147 profile.profile = supported_profile; | 1154 profile.profile = supported_profile; |
1148 profile.min_resolution.SetSize(16, 16); | 1155 profile.min_resolution.SetSize(16, 16); |
1149 profile.max_resolution.SetSize(4096, 2160); | 1156 profile.max_resolution.SetSize(4096, 2160); |
1150 profiles.push_back(profile); | 1157 profiles.push_back(profile); |
1151 } | 1158 } |
1152 return profiles; | 1159 return profiles; |
1153 } | 1160 } |
1154 | 1161 |
1155 } // namespace content | 1162 } // namespace content |
OLD | NEW |