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 |