Chromium Code Reviews| 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 <algorithm> | 5 #include <algorithm> |
| 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& | 295 const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& |
| 296 bind_image) | 296 bind_image) |
| 297 : make_context_current_(make_context_current), | 297 : make_context_current_(make_context_current), |
| 298 bind_image_(bind_image), | 298 bind_image_(bind_image), |
| 299 client_(nullptr), | 299 client_(nullptr), |
| 300 state_(STATE_DECODING), | 300 state_(STATE_DECODING), |
| 301 format_(nullptr), | 301 format_(nullptr), |
| 302 session_(nullptr), | 302 session_(nullptr), |
| 303 last_sps_id_(-1), | 303 last_sps_id_(-1), |
| 304 last_pps_id_(-1), | 304 last_pps_id_(-1), |
| 305 config_changed_(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 DCHECK(!make_context_current_.is_null()); | 309 DCHECK(!make_context_current_.is_null()); |
| 309 callback_.decompressionOutputCallback = OutputThunk; | 310 callback_.decompressionOutputCallback = OutputThunk; |
| 310 callback_.decompressionOutputRefCon = this; | 311 callback_.decompressionOutputRefCon = this; |
| 311 weak_this_ = weak_this_factory_.GetWeakPtr(); | 312 weak_this_ = weak_this_factory_.GetWeakPtr(); |
| 312 } | 313 } |
| 313 | 314 |
| 314 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 315 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 } | 604 } |
| 604 has_slice = true; | 605 has_slice = true; |
| 605 default: | 606 default: |
| 606 nalus.push_back(nalu); | 607 nalus.push_back(nalu); |
| 607 data_size += kNALUHeaderLength + nalu.size; | 608 data_size += kNALUHeaderLength + nalu.size; |
| 608 break; | 609 break; |
| 609 } | 610 } |
| 610 } | 611 } |
| 611 | 612 |
| 612 // Initialize VideoToolbox. | 613 // Initialize VideoToolbox. |
| 613 bool config_changed = false; | |
| 614 if (!sps.empty() && sps != last_sps_) { | 614 if (!sps.empty() && sps != last_sps_) { |
| 615 last_sps_.swap(sps); | 615 last_sps_.swap(sps); |
| 616 last_spsext_.swap(spsext); | 616 last_spsext_.swap(spsext); |
| 617 config_changed = true; | 617 config_changed_ = true; |
| 618 } | 618 } |
| 619 if (!pps.empty() && pps != last_pps_) { | 619 if (!pps.empty() && pps != last_pps_) { |
| 620 last_pps_.swap(pps); | 620 last_pps_.swap(pps); |
| 621 config_changed = true; | 621 config_changed_ = true; |
| 622 } | 622 } |
| 623 if (config_changed) { | 623 if (config_changed_) { |
| 624 if (last_sps_.empty()) { | 624 if (last_sps_.empty()) { |
| 625 config_changed_ = false; | |
| 625 DLOG(ERROR) << "Invalid configuration; no SPS"; | 626 DLOG(ERROR) << "Invalid configuration; no SPS"; |
| 626 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); | 627 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); |
| 627 return; | 628 return; |
| 628 } | 629 } |
| 629 if (last_pps_.empty()) { | 630 if (last_pps_.empty()) { |
| 631 config_changed_ = false; | |
| 630 DLOG(ERROR) << "Invalid configuration; no PPS"; | 632 DLOG(ERROR) << "Invalid configuration; no PPS"; |
| 631 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); | 633 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); |
| 632 return; | 634 return; |
| 633 } | 635 } |
| 634 | 636 |
| 635 // If it's not an IDR frame, we can't reconfigure the decoder anyway. We | 637 // Only reconfigure at IDRs to avoid corruption. |
| 636 // assume that any config change not on an IDR must be compatible. | 638 if (frame->is_idr) { |
| 637 if (frame->is_idr && !ConfigureDecoder()) | 639 config_changed_ = false; |
| 638 return; | 640 |
| 641 // ConfigureDecoder() calls NotifyError() on failure. | |
| 642 if (!ConfigureDecoder()) | |
| 643 return; | |
| 644 } | |
| 639 } | 645 } |
| 640 | 646 |
| 641 // If there are no image slices, drop the bitstream buffer by returning an | 647 // If no IDR has been seen yet, skip decoding. |
| 648 if (has_slice && !session_ && config_changed_) { | |
| 649 LOG(ERROR) << "Illegal attempt to decode without IDR. Dropping frame."; | |
|
DaleCurtis
2016/02/05 22:35:27
DLOG(). Don't want to spam console on bad streams.
sandersd (OOO until July 31)
2016/02/05 23:24:54
I've changed it to be limited to once per VTVDA in
| |
| 650 has_slice = false; | |
| 651 } | |
| 652 | |
| 653 // If there is nothing to decode, drop the bitstream buffer by returning an | |
| 642 // empty frame. | 654 // empty frame. |
| 643 if (!has_slice) { | 655 if (!has_slice) { |
| 656 // Keep everything in order by flushing first. | |
| 644 if (!FinishDelayedFrames()) | 657 if (!FinishDelayedFrames()) |
| 645 return; | 658 return; |
| 646 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( | 659 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 647 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); | 660 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); |
| 648 return; | 661 return; |
| 649 } | 662 } |
| 650 | 663 |
| 651 // If the session is not configured by this point, fail. | 664 // If the session is not configured by this point, fail. |
| 652 if (!session_) { | 665 if (!session_) { |
| 653 DLOG(ERROR) << "Cannot decode without configuration"; | 666 DLOG(ERROR) << "Cannot decode without configuration"; |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1137 SupportedProfile profile; | 1150 SupportedProfile profile; |
| 1138 profile.profile = supported_profile; | 1151 profile.profile = supported_profile; |
| 1139 profile.min_resolution.SetSize(16, 16); | 1152 profile.min_resolution.SetSize(16, 16); |
| 1140 profile.max_resolution.SetSize(4096, 2160); | 1153 profile.max_resolution.SetSize(4096, 2160); |
| 1141 profiles.push_back(profile); | 1154 profiles.push_back(profile); |
| 1142 } | 1155 } |
| 1143 return profiles; | 1156 return profiles; |
| 1144 } | 1157 } |
| 1145 | 1158 |
| 1146 } // namespace content | 1159 } // namespace content |
| OLD | NEW |