OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/dxva_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
6 | 6 |
7 #if !defined(OS_WIN) | 7 #if !defined(OS_WIN) |
8 #error This file should only be built on Windows. | 8 #error This file should only be built on Windows. |
9 #endif // !defined(OS_WIN) | 9 #endif // !defined(OS_WIN) |
10 | 10 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer | 89 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer |
90 // with the align argument being 0. | 90 // with the align argument being 0. |
91 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); | 91 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); |
92 } else { | 92 } else { |
93 hr = MFCreateAlignedMemoryBuffer(buffer_length, | 93 hr = MFCreateAlignedMemoryBuffer(buffer_length, |
94 align - 1, | 94 align - 1, |
95 buffer.Receive()); | 95 buffer.Receive()); |
96 } | 96 } |
97 RETURN_ON_HR_FAILURE(hr, "Failed to create memory buffer for sample", NULL); | 97 RETURN_ON_HR_FAILURE(hr, "Failed to create memory buffer for sample", NULL); |
98 | 98 |
99 hr = sample->AddBuffer(buffer); | 99 hr = sample->AddBuffer(buffer.get()); |
100 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL); | 100 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL); |
101 | 101 |
102 return sample.Detach(); | 102 return sample.Detach(); |
103 } | 103 } |
104 | 104 |
105 // Creates a Media Foundation sample with one buffer containing a copy of the | 105 // Creates a Media Foundation sample with one buffer containing a copy of the |
106 // given Annex B stream data. | 106 // given Annex B stream data. |
107 // If duration and sample time are not known, provide 0. | 107 // If duration and sample time are not known, provide 0. |
108 // |min_size| specifies the minimum size of the buffer (might be required by | 108 // |min_size| specifies the minimum size of the buffer (might be required by |
109 // the decoder for input). If no alignment is required, provide 0. | 109 // the decoder for input). If no alignment is required, provide 0. |
110 static IMFSample* CreateInputSample(const uint8* stream, int size, | 110 static IMFSample* CreateInputSample(const uint8* stream, int size, |
111 int min_size, int alignment) { | 111 int min_size, int alignment) { |
112 CHECK(stream); | 112 CHECK(stream); |
113 CHECK_GT(size, 0); | 113 CHECK_GT(size, 0); |
114 base::win::ScopedComPtr<IMFSample> sample; | 114 base::win::ScopedComPtr<IMFSample> sample; |
115 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), | 115 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), |
116 alignment)); | 116 alignment)); |
117 RETURN_ON_FAILURE(sample, "Failed to create empty sample", NULL); | 117 RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL); |
118 | 118 |
119 base::win::ScopedComPtr<IMFMediaBuffer> buffer; | 119 base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
120 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); | 120 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); |
121 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); | 121 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); |
122 | 122 |
123 DWORD max_length = 0; | 123 DWORD max_length = 0; |
124 DWORD current_length = 0; | 124 DWORD current_length = 0; |
125 uint8* destination = NULL; | 125 uint8* destination = NULL; |
126 hr = buffer->Lock(&destination, &max_length, ¤t_length); | 126 hr = buffer->Lock(&destination, &max_length, ¤t_length); |
127 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); | 127 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); | 322 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
323 | 323 |
324 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); | 324 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); |
325 | 325 |
326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
327 | 327 |
328 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface; | 328 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface; |
329 hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive()); | 329 hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive()); |
330 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); | 330 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); |
331 | 331 |
332 hr = decoder.device_->StretchRect( | 332 hr = decoder.device_->StretchRect(dest_surface, NULL, d3d_surface.get(), NULL, |
nasko
2014/11/12 23:18:24
nit: The params all fit on one line, so not sure w
dcheng
2014/11/12 23:22:49
I'm pretty sure this is because we recently change
| |
333 dest_surface, NULL, d3d_surface, NULL, D3DTEXF_NONE); | 333 D3DTEXF_NONE); |
334 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", | 334 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", |
335 false); | 335 false); |
336 | 336 |
337 // Ideally, this should be done immediately before the draw call that uses | 337 // Ideally, this should be done immediately before the draw call that uses |
338 // the texture. Flush it once here though. | 338 // the texture. Flush it once here though. |
339 hr = decoder.query_->Issue(D3DISSUE_END); | 339 hr = decoder.query_->Issue(D3DISSUE_END); |
340 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); | 340 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); |
341 | 341 |
342 // The DXVA decoder has its own device which it uses for decoding. ANGLE | 342 // The DXVA decoder has its own device which it uses for decoding. ANGLE |
343 // has its own device which we don't have access to. | 343 // has its own device which we don't have access to. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 D3DCREATE_MULTITHREADED, | 403 D3DCREATE_MULTITHREADED, |
404 &present_params, | 404 &present_params, |
405 NULL, | 405 NULL, |
406 device_.Receive()); | 406 device_.Receive()); |
407 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false); | 407 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false); |
408 | 408 |
409 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_, | 409 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_, |
410 device_manager_.Receive()); | 410 device_manager_.Receive()); |
411 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false); | 411 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false); |
412 | 412 |
413 hr = device_manager_->ResetDevice(device_, dev_manager_reset_token_); | 413 hr = device_manager_->ResetDevice(device_.get(), dev_manager_reset_token_); |
414 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); | 414 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); |
415 | 415 |
416 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); | 416 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); |
417 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); | 417 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); |
418 // Ensure query_ API works (to avoid an infinite loop later in | 418 // Ensure query_ API works (to avoid an infinite loop later in |
419 // CopyOutputSampleDataToPictureBuffer). | 419 // CopyOutputSampleDataToPictureBuffer). |
420 hr = query_->Issue(D3DISSUE_END); | 420 hr = query_->Issue(D3DISSUE_END); |
421 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); | 421 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); |
422 return true; | 422 return true; |
423 } | 423 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 DCHECK(CalledOnValidThread()); | 506 DCHECK(CalledOnValidThread()); |
507 | 507 |
508 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kNormal || state_ == kStopped || | 508 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kNormal || state_ == kStopped || |
509 state_ == kFlushing), | 509 state_ == kFlushing), |
510 "Invalid state: " << state_, ILLEGAL_STATE,); | 510 "Invalid state: " << state_, ILLEGAL_STATE,); |
511 | 511 |
512 base::win::ScopedComPtr<IMFSample> sample; | 512 base::win::ScopedComPtr<IMFSample> sample; |
513 sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer, | 513 sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer, |
514 input_stream_info_.cbSize, | 514 input_stream_info_.cbSize, |
515 input_stream_info_.cbAlignment)); | 515 input_stream_info_.cbAlignment)); |
516 RETURN_AND_NOTIFY_ON_FAILURE(sample, "Failed to create input sample", | 516 RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample", |
517 PLATFORM_FAILURE,); | 517 PLATFORM_FAILURE, ); |
nasko
2014/11/12 23:18:24
nit: Do we really need the extra space after ","?
dcheng
2014/11/12 23:22:49
Would prefer to avoid fighting clang-format here t
| |
518 | 518 |
519 RETURN_AND_NOTIFY_ON_HR_FAILURE(sample->SetSampleTime(bitstream_buffer.id()), | 519 RETURN_AND_NOTIFY_ON_HR_FAILURE(sample->SetSampleTime(bitstream_buffer.id()), |
520 "Failed to associate input buffer id with sample", PLATFORM_FAILURE,); | 520 "Failed to associate input buffer id with sample", PLATFORM_FAILURE,); |
521 | 521 |
522 DecodeInternal(sample); | 522 DecodeInternal(sample); |
523 } | 523 } |
524 | 524 |
525 void DXVAVideoDecodeAccelerator::AssignPictureBuffers( | 525 void DXVAVideoDecodeAccelerator::AssignPictureBuffers( |
526 const std::vector<media::PictureBuffer>& buffers) { | 526 const std::vector<media::PictureBuffer>& buffers) { |
527 DCHECK(CalledOnValidThread()); | 527 DCHECK(CalledOnValidThread()); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 | 746 |
747 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | 747 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); |
748 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); | 748 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); |
749 | 749 |
750 // Not sure about this. msdn recommends setting this value on the input | 750 // Not sure about this. msdn recommends setting this value on the input |
751 // media type. | 751 // media type. |
752 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, | 752 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, |
753 MFVideoInterlace_MixedInterlaceOrProgressive); | 753 MFVideoInterlace_MixedInterlaceOrProgressive); |
754 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); | 754 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); |
755 | 755 |
756 hr = decoder_->SetInputType(0, media_type, 0); // No flags | 756 hr = decoder_->SetInputType(0, media_type.get(), 0); // No flags |
757 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); | 757 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); |
758 return true; | 758 return true; |
759 } | 759 } |
760 | 760 |
761 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( | 761 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( |
762 const GUID& subtype) { | 762 const GUID& subtype) { |
763 base::win::ScopedComPtr<IMFMediaType> out_media_type; | 763 base::win::ScopedComPtr<IMFMediaType> out_media_type; |
764 | 764 |
765 for (uint32 i = 0; | 765 for (uint32 i = 0; |
766 SUCCEEDED(decoder_->GetOutputAvailableType(0, i, | 766 SUCCEEDED(decoder_->GetOutputAvailableType(0, i, |
767 out_media_type.Receive())); | 767 out_media_type.Receive())); |
768 ++i) { | 768 ++i) { |
769 GUID out_subtype = {0}; | 769 GUID out_subtype = {0}; |
770 HRESULT hr = out_media_type->GetGUID(MF_MT_SUBTYPE, &out_subtype); | 770 HRESULT hr = out_media_type->GetGUID(MF_MT_SUBTYPE, &out_subtype); |
771 RETURN_ON_HR_FAILURE(hr, "Failed to get output major type", false); | 771 RETURN_ON_HR_FAILURE(hr, "Failed to get output major type", false); |
772 | 772 |
773 if (out_subtype == subtype) { | 773 if (out_subtype == subtype) { |
774 hr = decoder_->SetOutputType(0, out_media_type, 0); // No flags | 774 hr = decoder_->SetOutputType(0, out_media_type.get(), 0); // No flags |
775 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder output type", false); | 775 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder output type", false); |
776 return true; | 776 return true; |
777 } | 777 } |
778 out_media_type.Release(); | 778 out_media_type.Release(); |
779 } | 779 } |
780 return false; | 780 return false; |
781 } | 781 } |
782 | 782 |
783 bool DXVAVideoDecodeAccelerator::SendMFTMessage(MFT_MESSAGE_TYPE msg, | 783 bool DXVAVideoDecodeAccelerator::SendMFTMessage(MFT_MESSAGE_TYPE msg, |
784 int32 param) { | 784 int32 param) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 } | 874 } |
875 | 875 |
876 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) { | 876 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) { |
877 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); | 877 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); |
878 | 878 |
879 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 879 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
880 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); | 880 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); |
881 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); | 881 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); |
882 | 882 |
883 base::win::ScopedComPtr<IDirect3DSurface9> surface; | 883 base::win::ScopedComPtr<IDirect3DSurface9> surface; |
884 hr = MFGetService(output_buffer, MR_BUFFER_SERVICE, | 884 hr = MFGetService(output_buffer.get(), MR_BUFFER_SERVICE, |
885 IID_PPV_ARGS(surface.Receive())); | 885 IID_PPV_ARGS(surface.Receive())); |
886 RETURN_ON_HR_FAILURE(hr, "Failed to get D3D surface from output sample", | 886 RETURN_ON_HR_FAILURE(hr, "Failed to get D3D surface from output sample", |
887 false); | 887 false); |
888 | 888 |
889 LONGLONG input_buffer_id = 0; | 889 LONGLONG input_buffer_id = 0; |
890 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), | 890 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), |
891 "Failed to get input buffer id associated with sample", | 891 "Failed to get input buffer id associated with sample", |
892 false); | 892 false); |
893 | 893 |
894 pending_output_samples_.push_back( | 894 pending_output_samples_.push_back( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
937 if (index->second->available()) { | 937 if (index->second->available()) { |
938 PendingSampleInfo sample_info = pending_output_samples_.front(); | 938 PendingSampleInfo sample_info = pending_output_samples_.front(); |
939 | 939 |
940 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 940 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
941 HRESULT hr = sample_info.output_sample->GetBufferByIndex( | 941 HRESULT hr = sample_info.output_sample->GetBufferByIndex( |
942 0, output_buffer.Receive()); | 942 0, output_buffer.Receive()); |
943 RETURN_AND_NOTIFY_ON_HR_FAILURE( | 943 RETURN_AND_NOTIFY_ON_HR_FAILURE( |
944 hr, "Failed to get buffer from output sample", PLATFORM_FAILURE,); | 944 hr, "Failed to get buffer from output sample", PLATFORM_FAILURE,); |
945 | 945 |
946 base::win::ScopedComPtr<IDirect3DSurface9> surface; | 946 base::win::ScopedComPtr<IDirect3DSurface9> surface; |
947 hr = MFGetService(output_buffer, MR_BUFFER_SERVICE, | 947 hr = MFGetService(output_buffer.get(), MR_BUFFER_SERVICE, |
948 IID_PPV_ARGS(surface.Receive())); | 948 IID_PPV_ARGS(surface.Receive())); |
949 RETURN_AND_NOTIFY_ON_HR_FAILURE( | 949 RETURN_AND_NOTIFY_ON_HR_FAILURE( |
950 hr, "Failed to get D3D surface from output sample", | 950 hr, "Failed to get D3D surface from output sample", |
951 PLATFORM_FAILURE,); | 951 PLATFORM_FAILURE,); |
952 | 952 |
953 D3DSURFACE_DESC surface_desc; | 953 D3DSURFACE_DESC surface_desc; |
954 hr = surface->GetDesc(&surface_desc); | 954 hr = surface->GetDesc(&surface_desc); |
955 RETURN_AND_NOTIFY_ON_HR_FAILURE( | 955 RETURN_AND_NOTIFY_ON_HR_FAILURE( |
956 hr, "Failed to get surface description", PLATFORM_FAILURE,); | 956 hr, "Failed to get surface description", PLATFORM_FAILURE,); |
957 | 957 |
958 if (surface_desc.Width != | 958 if (surface_desc.Width != |
959 static_cast<uint32>(index->second->size().width()) || | 959 static_cast<uint32>(index->second->size().width()) || |
960 surface_desc.Height != | 960 surface_desc.Height != |
961 static_cast<uint32>(index->second->size().height())) { | 961 static_cast<uint32>(index->second->size().height())) { |
962 HandleResolutionChanged(surface_desc.Width, surface_desc.Height); | 962 HandleResolutionChanged(surface_desc.Width, surface_desc.Height); |
963 return; | 963 return; |
964 } | 964 } |
965 | 965 |
966 RETURN_AND_NOTIFY_ON_FAILURE( | 966 RETURN_AND_NOTIFY_ON_FAILURE( |
967 index->second->CopyOutputSampleDataToPictureBuffer(*this, surface), | 967 index->second->CopyOutputSampleDataToPictureBuffer(*this, |
968 "Failed to copy output sample", | 968 surface.get()), |
969 PLATFORM_FAILURE, ); | 969 "Failed to copy output sample", PLATFORM_FAILURE, ); |
970 | 970 |
971 media::Picture output_picture(index->second->id(), | 971 media::Picture output_picture(index->second->id(), |
972 sample_info.input_buffer_id, | 972 sample_info.input_buffer_id, |
973 gfx::Rect(index->second->size())); | 973 gfx::Rect(index->second->size())); |
974 base::MessageLoop::current()->PostTask( | 974 base::MessageLoop::current()->PostTask( |
975 FROM_HERE, | 975 FROM_HERE, |
976 base::Bind(&DXVAVideoDecodeAccelerator::NotifyPictureReady, | 976 base::Bind(&DXVAVideoDecodeAccelerator::NotifyPictureReady, |
977 weak_this_factory_.GetWeakPtr(), | 977 weak_this_factory_.GetWeakPtr(), |
978 output_picture)); | 978 output_picture)); |
979 | 979 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1108 if (!pending_output_samples_.empty() || !pending_input_buffers_.empty()) { | 1108 if (!pending_output_samples_.empty() || !pending_input_buffers_.empty()) { |
1109 pending_input_buffers_.push_back(sample); | 1109 pending_input_buffers_.push_back(sample); |
1110 return; | 1110 return; |
1111 } | 1111 } |
1112 | 1112 |
1113 if (!inputs_before_decode_) { | 1113 if (!inputs_before_decode_) { |
1114 TRACE_EVENT_BEGIN_ETW("DXVAVideoDecodeAccelerator.Decoding", this, ""); | 1114 TRACE_EVENT_BEGIN_ETW("DXVAVideoDecodeAccelerator.Decoding", this, ""); |
1115 } | 1115 } |
1116 inputs_before_decode_++; | 1116 inputs_before_decode_++; |
1117 | 1117 |
1118 HRESULT hr = decoder_->ProcessInput(0, sample, 0); | 1118 HRESULT hr = decoder_->ProcessInput(0, sample.get(), 0); |
1119 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it | 1119 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it |
1120 // has enough data to produce one or more output samples. In this case the | 1120 // has enough data to produce one or more output samples. In this case the |
1121 // recommended options are to | 1121 // recommended options are to |
1122 // 1. Generate new output by calling IMFTransform::ProcessOutput until it | 1122 // 1. Generate new output by calling IMFTransform::ProcessOutput until it |
1123 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. | 1123 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. |
1124 // 2. Flush the input data | 1124 // 2. Flush the input data |
1125 // We implement the first option, i.e to retrieve the output sample and then | 1125 // We implement the first option, i.e to retrieve the output sample and then |
1126 // process the input again. Failure in either of these steps is treated as a | 1126 // process the input again. Failure in either of these steps is treated as a |
1127 // decoder failure. | 1127 // decoder failure. |
1128 if (hr == MF_E_NOTACCEPTING) { | 1128 if (hr == MF_E_NOTACCEPTING) { |
1129 DoDecode(); | 1129 DoDecode(); |
1130 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kStopped || state_ == kNormal), | 1130 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kStopped || state_ == kNormal), |
1131 "Failed to process output. Unexpected decoder state: " << state_, | 1131 "Failed to process output. Unexpected decoder state: " << state_, |
1132 PLATFORM_FAILURE,); | 1132 PLATFORM_FAILURE,); |
1133 hr = decoder_->ProcessInput(0, sample, 0); | 1133 hr = decoder_->ProcessInput(0, sample.get(), 0); |
1134 // If we continue to get the MF_E_NOTACCEPTING error we do the following:- | 1134 // If we continue to get the MF_E_NOTACCEPTING error we do the following:- |
1135 // 1. Add the input sample to the pending queue. | 1135 // 1. Add the input sample to the pending queue. |
1136 // 2. If we don't have any output samples we post the | 1136 // 2. If we don't have any output samples we post the |
1137 // DecodePendingInputBuffers task to process the pending input samples. | 1137 // DecodePendingInputBuffers task to process the pending input samples. |
1138 // If we have an output sample then the above task is posted when the | 1138 // If we have an output sample then the above task is posted when the |
1139 // output samples are sent to the client. | 1139 // output samples are sent to the client. |
1140 // This is because we only support 1 pending output sample at any | 1140 // This is because we only support 1 pending output sample at any |
1141 // given time due to the limitation with the Microsoft media foundation | 1141 // given time due to the limitation with the Microsoft media foundation |
1142 // decoder where it recycles the output Decoder surfaces. | 1142 // decoder where it recycles the output Decoder surfaces. |
1143 if (hr == MF_E_NOTACCEPTING) { | 1143 if (hr == MF_E_NOTACCEPTING) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 int32 picture_buffer_id) { | 1218 int32 picture_buffer_id) { |
1219 OutputBuffers::iterator it = stale_output_picture_buffers_.find( | 1219 OutputBuffers::iterator it = stale_output_picture_buffers_.find( |
1220 picture_buffer_id); | 1220 picture_buffer_id); |
1221 DCHECK(it != stale_output_picture_buffers_.end()); | 1221 DCHECK(it != stale_output_picture_buffers_.end()); |
1222 DVLOG(1) << "Dismissing picture id: " << it->second->id(); | 1222 DVLOG(1) << "Dismissing picture id: " << it->second->id(); |
1223 client_->DismissPictureBuffer(it->second->id()); | 1223 client_->DismissPictureBuffer(it->second->id()); |
1224 stale_output_picture_buffers_.erase(it); | 1224 stale_output_picture_buffers_.erase(it); |
1225 } | 1225 } |
1226 | 1226 |
1227 } // namespace content | 1227 } // namespace content |
OLD | NEW |