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_win.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator_win.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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 239 |
240 hr = buffer->SetCurrentLength(size); | 240 hr = buffer->SetCurrentLength(size); |
241 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); | 241 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); |
242 | 242 |
243 hr = buffer->Unlock(); | 243 hr = buffer->Unlock(); |
244 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); | 244 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); |
245 | 245 |
246 return sample.Detach(); | 246 return sample.Detach(); |
247 } | 247 } |
248 | 248 |
249 static IMFSample* CreateSampleFromInputBuffer( | |
250 const media::BitstreamBuffer& bitstream_buffer, | |
251 uint32_t stream_size, | |
252 DWORD alignment) { | |
253 base::SharedMemory shm(bitstream_buffer.handle(), true); | |
254 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), | |
255 "Failed in base::SharedMemory::Map", NULL); | |
256 | |
257 return CreateInputSample(reinterpret_cast<const uint8_t*>(shm.memory()), | |
258 bitstream_buffer.size(), | |
259 std::min<uint32_t>(bitstream_buffer.size(), | |
260 stream_size), | |
261 alignment); | |
262 } | |
263 | |
264 // Helper function to create a COM object instance from a DLL. The alternative | 249 // Helper function to create a COM object instance from a DLL. The alternative |
265 // is to use the CoCreateInstance API which requires the COM apartment to be | 250 // is to use the CoCreateInstance API which requires the COM apartment to be |
266 // initialized which is not the case on the GPU main thread. We want to avoid | 251 // initialized which is not the case on the GPU main thread. We want to avoid |
267 // initializing COM as it may have sideeffects. | 252 // initializing COM as it may have sideeffects. |
268 HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid, | 253 HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid, |
269 void** object) { | 254 void** object) { |
270 if (!dll || !object) | 255 if (!dll || !object) |
271 return E_INVALIDARG; | 256 return E_INVALIDARG; |
272 | 257 |
273 using GetClassObject = HRESULT (WINAPI*)( | 258 using GetClassObject = HRESULT (WINAPI*)( |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 hr, | 920 hr, |
936 "Failed to set MF_LOW_LATENCY attribute on converter", | 921 "Failed to set MF_LOW_LATENCY attribute on converter", |
937 false); | 922 false); |
938 return true; | 923 return true; |
939 } | 924 } |
940 | 925 |
941 void DXVAVideoDecodeAccelerator::Decode( | 926 void DXVAVideoDecodeAccelerator::Decode( |
942 const media::BitstreamBuffer& bitstream_buffer) { | 927 const media::BitstreamBuffer& bitstream_buffer) { |
943 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 928 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
944 | 929 |
| 930 // SharedMemory will take over the ownership of handle. |
| 931 base::SharedMemory shm(bitstream_buffer.handle(), true); |
| 932 |
945 State state = GetState(); | 933 State state = GetState(); |
946 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped || | 934 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped || |
947 state == kFlushing), | 935 state == kFlushing), |
948 "Invalid state: " << state, ILLEGAL_STATE,); | 936 "Invalid state: " << state, ILLEGAL_STATE,); |
| 937 if (bitstream_buffer.id() < 0) { |
| 938 RETURN_AND_NOTIFY_ON_FAILURE( |
| 939 false, "Invalid bitstream_buffer, id: " << bitstream_buffer.id(), |
| 940 INVALID_ARGUMENT, ); |
| 941 } |
949 | 942 |
950 base::win::ScopedComPtr<IMFSample> sample; | 943 base::win::ScopedComPtr<IMFSample> sample; |
951 sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer, | 944 RETURN_AND_NOTIFY_ON_FAILURE(shm.Map(bitstream_buffer.size()), |
952 input_stream_info_.cbSize, | 945 "Failed in base::SharedMemory::Map", |
953 input_stream_info_.cbAlignment)); | 946 PLATFORM_FAILURE, ); |
| 947 |
| 948 sample.Attach(CreateInputSample( |
| 949 reinterpret_cast<const uint8_t*>(shm.memory()), bitstream_buffer.size(), |
| 950 std::min<uint32_t>(bitstream_buffer.size(), input_stream_info_.cbSize), |
| 951 input_stream_info_.cbAlignment)); |
954 RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample", | 952 RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample", |
955 PLATFORM_FAILURE, ); | 953 PLATFORM_FAILURE, ); |
956 | 954 |
957 RETURN_AND_NOTIFY_ON_HR_FAILURE(sample->SetSampleTime(bitstream_buffer.id()), | 955 RETURN_AND_NOTIFY_ON_HR_FAILURE(sample->SetSampleTime(bitstream_buffer.id()), |
958 "Failed to associate input buffer id with sample", PLATFORM_FAILURE,); | 956 "Failed to associate input buffer id with sample", PLATFORM_FAILURE,); |
959 | 957 |
960 decoder_thread_task_runner_->PostTask( | 958 decoder_thread_task_runner_->PostTask( |
961 FROM_HERE, | 959 FROM_HERE, |
962 base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal, | 960 base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal, |
963 base::Unretained(this), sample)); | 961 base::Unretained(this), sample)); |
(...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2381 } | 2379 } |
2382 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); | 2380 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); |
2383 return true; | 2381 return true; |
2384 } | 2382 } |
2385 media_type.Release(); | 2383 media_type.Release(); |
2386 } | 2384 } |
2387 return false; | 2385 return false; |
2388 } | 2386 } |
2389 | 2387 |
2390 } // namespace content | 2388 } // namespace content |
OLD | NEW |