Chromium Code Reviews| Index: content/common/gpu/media/vt_video_decode_accelerator_mac.cc |
| diff --git a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc |
| index 19b65c5bb12ec83a5da17ef83bee84eedac65dca..e74e6f64d55e610d4dc49d3cfe01c99f06b053a3 100644 |
| --- a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc |
| +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc |
| @@ -302,6 +302,8 @@ VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( |
| session_(nullptr), |
| last_sps_id_(-1), |
| last_pps_id_(-1), |
| + config_changed_(false), |
| + missing_idr_logged_(false), |
| gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| decoder_thread_("VTDecoderThread"), |
| weak_this_factory_(this) { |
| @@ -610,37 +612,53 @@ void VTVideoDecodeAccelerator::DecodeTask( |
| } |
| // Initialize VideoToolbox. |
| - bool config_changed = false; |
| if (!sps.empty() && sps != last_sps_) { |
| last_sps_.swap(sps); |
| last_spsext_.swap(spsext); |
| - config_changed = true; |
| + config_changed_ = true; |
| } |
| if (!pps.empty() && pps != last_pps_) { |
| last_pps_.swap(pps); |
| - config_changed = true; |
| + config_changed_ = true; |
| } |
| - if (config_changed) { |
| + if (config_changed_) { |
| if (last_sps_.empty()) { |
| + config_changed_ = false; |
| DLOG(ERROR) << "Invalid configuration; no SPS"; |
| NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); |
| return; |
| } |
| if (last_pps_.empty()) { |
| + config_changed_ = false; |
| DLOG(ERROR) << "Invalid configuration; no PPS"; |
| NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); |
| return; |
| } |
| - // If it's not an IDR frame, we can't reconfigure the decoder anyway. We |
| - // assume that any config change not on an IDR must be compatible. |
| - if (frame->is_idr && !ConfigureDecoder()) |
| - return; |
| + // Only reconfigure at IDRs to avoid corruption. |
| + if (frame->is_idr) { |
| + config_changed_ = false; |
| + |
| + // ConfigureDecoder() calls NotifyError() on failure. |
| + if (!ConfigureDecoder()) |
| + return; |
| + } |
| + } |
| + |
| + // If no IDR has been seen yet, skip decoding. |
| + if (has_slice && !session_ && config_changed_) { |
| + if (!missing_idr_logged_) { |
| + LOG(ERROR) << "Illegal attempt to decode without IDR. " |
| + << "Discarding decode requests until next IDR."; |
| + missing_idr_logged_ = true; |
|
DaleCurtis
2016/02/05 23:50:08
Do you want to reset this to false after the first
sandersd (OOO until July 31)
2016/02/05 23:53:52
We could do that, but I'm mostly just concerned wi
|
| + } |
| + has_slice = false; |
| } |
| - // If there are no image slices, drop the bitstream buffer by returning an |
| + // If there is nothing to decode, drop the bitstream buffer by returning an |
| // empty frame. |
| if (!has_slice) { |
| + // Keep everything in order by flushing first. |
| if (!FinishDelayedFrames()) |
| return; |
| gpu_task_runner_->PostTask(FROM_HERE, base::Bind( |