| 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 |