| Index: media/gpu/dxva_video_decode_accelerator_win.cc
|
| diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc
|
| index e65f1e857c878fe4b0c712a73cbff69b40184c1d..acf9424c6c8706b7479704073012cf54134a9a9f 100644
|
| --- a/media/gpu/dxva_video_decode_accelerator_win.cc
|
| +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
|
| @@ -1778,49 +1778,60 @@ void DXVAVideoDecodeAccelerator::DoDecode(const gfx::ColorSpace& color_space) {
|
| if (D3D11Device())
|
| g_last_device_removed_reason = D3D11Device()->GetDeviceRemovedReason();
|
|
|
| - MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0};
|
| - DWORD status = 0;
|
| - HRESULT hr;
|
| - {
|
| - ScopedExceptionCatcher catcher(using_ms_vp9_mft_);
|
| - g_last_process_output_time = GetCurrentQPC();
|
| - hr = decoder_->ProcessOutput(0, // No flags
|
| - 1, // # of out streams to pull from
|
| - &output_data_buffer, &status);
|
| - }
|
| - IMFCollection* events = output_data_buffer.pEvents;
|
| - if (events != NULL) {
|
| - DVLOG(1) << "Got events from ProcessOuput, but discarding";
|
| - events->Release();
|
| - }
|
| base::win::ScopedComPtr<IMFSample> output_sample;
|
| - output_sample.Attach(output_data_buffer.pSample);
|
| - if (FAILED(hr)) {
|
| - // A stream change needs further ProcessInput calls to get back decoder
|
| - // output which is why we need to set the state to stopped.
|
| - if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
| - if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) &&
|
| - !SetDecoderOutputMediaType(MFVideoFormat_P010) &&
|
| - !SetDecoderOutputMediaType(MFVideoFormat_P016)) {
|
| - // Decoder didn't let us set NV12 output format. Not sure as to why
|
| - // this can happen. Give up in disgust.
|
| - NOTREACHED() << "Failed to set decoder output media type to NV12";
|
| + int retries = 10;
|
| + while (true) {
|
| + output_sample.Reset();
|
| + MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0};
|
| + DWORD status = 0;
|
| + HRESULT hr;
|
| + {
|
| + ScopedExceptionCatcher catcher(using_ms_vp9_mft_);
|
| + g_last_process_output_time = GetCurrentQPC();
|
| + hr = decoder_->ProcessOutput(0, // No flags
|
| + 1, // # of out streams to pull from
|
| + &output_data_buffer, &status);
|
| + }
|
| + IMFCollection* events = output_data_buffer.pEvents;
|
| + if (events != NULL) {
|
| + DVLOG(1) << "Got events from ProcessOuput, but discarding";
|
| + events->Release();
|
| + }
|
| + output_sample.Attach(output_data_buffer.pSample);
|
| + if (FAILED(hr)) {
|
| + // A stream change needs further ProcessInput calls to get back decoder
|
| + // output which is why we need to set the state to stopped.
|
| + if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
| + if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) &&
|
| + !SetDecoderOutputMediaType(MFVideoFormat_P010) &&
|
| + !SetDecoderOutputMediaType(MFVideoFormat_P016)) {
|
| + // Decoder didn't let us set NV12 output format. Not sure as to why
|
| + // this can happen. Give up in disgust.
|
| + NOTREACHED() << "Failed to set decoder output media type to NV12";
|
| + SetState(kStopped);
|
| + } else {
|
| + if (retries-- > 0) {
|
| + DVLOG(1) << "Received format change from the decoder, retrying.";
|
| + continue; // Retry
|
| + } else {
|
| + RETURN_AND_NOTIFY_ON_FAILURE(
|
| + false, "Received too many format changes from decoder.",
|
| + PLATFORM_FAILURE, );
|
| + }
|
| + }
|
| + return;
|
| + } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
| + // No more output from the decoder. Stop playback.
|
| SetState(kStopped);
|
| + return;
|
| } else {
|
| - DVLOG(1) << "Received output format change from the decoder."
|
| - " Recursively invoking DoDecode";
|
| - DoDecode(color_space);
|
| + NOTREACHED() << "Unhandled error in DoDecode()";
|
| + g_last_unhandled_error = hr;
|
| + return;
|
| }
|
| - return;
|
| - } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
| - // No more output from the decoder. Stop playback.
|
| - SetState(kStopped);
|
| - return;
|
| - } else {
|
| - NOTREACHED() << "Unhandled error in DoDecode()";
|
| - g_last_unhandled_error = hr;
|
| - return;
|
| }
|
| +
|
| + break; // No more retries needed.
|
| }
|
| TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this);
|
|
|
|
|