| 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 173 |
| 174 static IMFSample* CreateEmptySample() { | 174 static IMFSample* CreateEmptySample() { |
| 175 base::win::ScopedComPtr<IMFSample> sample; | 175 base::win::ScopedComPtr<IMFSample> sample; |
| 176 HRESULT hr = MFCreateSample(sample.Receive()); | 176 HRESULT hr = MFCreateSample(sample.Receive()); |
| 177 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); | 177 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); |
| 178 return sample.Detach(); | 178 return sample.Detach(); |
| 179 } | 179 } |
| 180 | 180 |
| 181 // Creates a Media Foundation sample with one buffer of length |buffer_length| | 181 // Creates a Media Foundation sample with one buffer of length |buffer_length| |
| 182 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. | 182 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. |
| 183 static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) { | 183 static IMFSample* CreateEmptySampleWithBuffer(uint32_t buffer_length, |
| 184 CHECK_GT(buffer_length, 0); | 184 int align) { |
| 185 CHECK_GT(buffer_length, 0U); |
| 185 | 186 |
| 186 base::win::ScopedComPtr<IMFSample> sample; | 187 base::win::ScopedComPtr<IMFSample> sample; |
| 187 sample.Attach(CreateEmptySample()); | 188 sample.Attach(CreateEmptySample()); |
| 188 | 189 |
| 189 base::win::ScopedComPtr<IMFMediaBuffer> buffer; | 190 base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
| 190 HRESULT hr = E_FAIL; | 191 HRESULT hr = E_FAIL; |
| 191 if (align == 0) { | 192 if (align == 0) { |
| 192 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer | 193 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer |
| 193 // with the align argument being 0. | 194 // with the align argument being 0. |
| 194 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); | 195 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 205 buffer->SetCurrentLength(0); | 206 buffer->SetCurrentLength(0); |
| 206 return sample.Detach(); | 207 return sample.Detach(); |
| 207 } | 208 } |
| 208 | 209 |
| 209 // Creates a Media Foundation sample with one buffer containing a copy of the | 210 // Creates a Media Foundation sample with one buffer containing a copy of the |
| 210 // given Annex B stream data. | 211 // given Annex B stream data. |
| 211 // If duration and sample time are not known, provide 0. | 212 // If duration and sample time are not known, provide 0. |
| 212 // |min_size| specifies the minimum size of the buffer (might be required by | 213 // |min_size| specifies the minimum size of the buffer (might be required by |
| 213 // the decoder for input). If no alignment is required, provide 0. | 214 // the decoder for input). If no alignment is required, provide 0. |
| 214 static IMFSample* CreateInputSample(const uint8_t* stream, | 215 static IMFSample* CreateInputSample(const uint8_t* stream, |
| 215 int size, | 216 uint32_t size, |
| 216 int min_size, | 217 uint32_t min_size, |
| 217 int alignment) { | 218 int alignment) { |
| 218 CHECK(stream); | 219 CHECK(stream); |
| 219 CHECK_GT(size, 0); | 220 CHECK_GT(size, 0U); |
| 220 base::win::ScopedComPtr<IMFSample> sample; | 221 base::win::ScopedComPtr<IMFSample> sample; |
| 221 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), | 222 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), |
| 222 alignment)); | 223 alignment)); |
| 223 RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL); | 224 RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL); |
| 224 | 225 |
| 225 base::win::ScopedComPtr<IMFMediaBuffer> buffer; | 226 base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
| 226 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); | 227 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); |
| 227 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); | 228 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); |
| 228 | 229 |
| 229 DWORD max_length = 0; | 230 DWORD max_length = 0; |
| 230 DWORD current_length = 0; | 231 DWORD current_length = 0; |
| 231 uint8_t* destination = NULL; | 232 uint8_t* destination = NULL; |
| 232 hr = buffer->Lock(&destination, &max_length, ¤t_length); | 233 hr = buffer->Lock(&destination, &max_length, ¤t_length); |
| 233 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); | 234 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); |
| 234 | 235 |
| 235 CHECK_EQ(current_length, 0u); | 236 CHECK_EQ(current_length, 0u); |
| 236 CHECK_GE(static_cast<int>(max_length), size); | 237 CHECK_GE(max_length, size); |
| 237 memcpy(destination, stream, size); | 238 memcpy(destination, stream, size); |
| 238 | 239 |
| 240 hr = buffer->SetCurrentLength(size); |
| 241 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); |
| 242 |
| 239 hr = buffer->Unlock(); | 243 hr = buffer->Unlock(); |
| 240 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); | 244 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); |
| 241 | 245 |
| 242 hr = buffer->SetCurrentLength(size); | |
| 243 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); | |
| 244 | |
| 245 return sample.Detach(); | 246 return sample.Detach(); |
| 246 } | 247 } |
| 247 | 248 |
| 248 static IMFSample* CreateSampleFromInputBuffer( | 249 static IMFSample* CreateSampleFromInputBuffer( |
| 249 const media::BitstreamBuffer& bitstream_buffer, | 250 const media::BitstreamBuffer& bitstream_buffer, |
| 250 DWORD stream_size, | 251 uint32_t stream_size, |
| 251 DWORD alignment) { | 252 DWORD alignment) { |
| 252 base::SharedMemory shm(bitstream_buffer.handle(), true); | 253 base::SharedMemory shm(bitstream_buffer.handle(), true); |
| 253 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), | 254 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), |
| 254 "Failed in base::SharedMemory::Map", NULL); | 255 "Failed in base::SharedMemory::Map", NULL); |
| 255 | 256 |
| 256 return CreateInputSample(reinterpret_cast<const uint8_t*>(shm.memory()), | 257 return CreateInputSample(reinterpret_cast<const uint8_t*>(shm.memory()), |
| 257 bitstream_buffer.size(), stream_size, alignment); | 258 bitstream_buffer.size(), |
| 259 std::min<uint32_t>(bitstream_buffer.size(), |
| 260 stream_size), |
| 261 alignment); |
| 258 } | 262 } |
| 259 | 263 |
| 260 // Helper function to create a COM object instance from a DLL. The alternative | 264 // Helper function to create a COM object instance from a DLL. The alternative |
| 261 // is to use the CoCreateInstance API which requires the COM apartment to be | 265 // is to use the CoCreateInstance API which requires the COM apartment to be |
| 262 // initialized which is not the case on the GPU main thread. We want to avoid | 266 // initialized which is not the case on the GPU main thread. We want to avoid |
| 263 // initializing COM as it may have sideeffects. | 267 // initializing COM as it may have sideeffects. |
| 264 HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid, | 268 HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid, |
| 265 void** object) { | 269 void** object) { |
| 266 if (!dll || !object) | 270 if (!dll || !object) |
| 267 return E_INVALIDARG; | 271 return E_INVALIDARG; |
| (...skipping 2109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2377 } | 2381 } |
| 2378 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); | 2382 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); |
| 2379 return true; | 2383 return true; |
| 2380 } | 2384 } |
| 2381 media_type.Release(); | 2385 media_type.Release(); |
| 2382 } | 2386 } |
| 2383 return false; | 2387 return false; |
| 2384 } | 2388 } |
| 2385 | 2389 |
| 2386 } // namespace content | 2390 } // namespace content |
| OLD | NEW |