Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 649533003: C++11 declares a type safe null pointer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed Presubmit errors Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 error_code, ret); 64 error_code, ret);
65 65
66 // Maximum number of iterations we allow before aborting the attempt to flush 66 // Maximum number of iterations we allow before aborting the attempt to flush
67 // the batched queries to the driver and allow torn/corrupt frames to be 67 // the batched queries to the driver and allow torn/corrupt frames to be
68 // rendered. 68 // rendered.
69 enum { kMaxIterationsForD3DFlush = 10 }; 69 enum { kMaxIterationsForD3DFlush = 10 };
70 70
71 static IMFSample* CreateEmptySample() { 71 static IMFSample* CreateEmptySample() {
72 base::win::ScopedComPtr<IMFSample> sample; 72 base::win::ScopedComPtr<IMFSample> sample;
73 HRESULT hr = MFCreateSample(sample.Receive()); 73 HRESULT hr = MFCreateSample(sample.Receive());
74 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); 74 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", nullptr);
75 return sample.Detach(); 75 return sample.Detach();
76 } 76 }
77 77
78 // Creates a Media Foundation sample with one buffer of length |buffer_length| 78 // Creates a Media Foundation sample with one buffer of length |buffer_length|
79 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. 79 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0.
80 static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) { 80 static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) {
81 CHECK_GT(buffer_length, 0); 81 CHECK_GT(buffer_length, 0);
82 82
83 base::win::ScopedComPtr<IMFSample> sample; 83 base::win::ScopedComPtr<IMFSample> sample;
84 sample.Attach(CreateEmptySample()); 84 sample.Attach(CreateEmptySample());
85 85
86 base::win::ScopedComPtr<IMFMediaBuffer> buffer; 86 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
87 HRESULT hr = E_FAIL; 87 HRESULT hr = E_FAIL;
88 if (align == 0) { 88 if (align == 0) {
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",
98 nullptr);
98 99
99 hr = sample->AddBuffer(buffer); 100 hr = sample->AddBuffer(buffer);
100 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL); 101 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", nullptr);
101 102
102 return sample.Detach(); 103 return sample.Detach();
103 } 104 }
104 105
105 // Creates a Media Foundation sample with one buffer containing a copy of the 106 // Creates a Media Foundation sample with one buffer containing a copy of the
106 // given Annex B stream data. 107 // given Annex B stream data.
107 // If duration and sample time are not known, provide 0. 108 // If duration and sample time are not known, provide 0.
108 // |min_size| specifies the minimum size of the buffer (might be required by 109 // |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. 110 // the decoder for input). If no alignment is required, provide 0.
110 static IMFSample* CreateInputSample(const uint8* stream, int size, 111 static IMFSample* CreateInputSample(const uint8* stream, int size,
111 int min_size, int alignment) { 112 int min_size, int alignment) {
112 CHECK(stream); 113 CHECK(stream);
113 CHECK_GT(size, 0); 114 CHECK_GT(size, 0);
114 base::win::ScopedComPtr<IMFSample> sample; 115 base::win::ScopedComPtr<IMFSample> sample;
115 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), 116 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size),
116 alignment)); 117 alignment));
117 RETURN_ON_FAILURE(sample, "Failed to create empty sample", NULL); 118 RETURN_ON_FAILURE(sample, "Failed to create empty sample", nullptr);
118 119
119 base::win::ScopedComPtr<IMFMediaBuffer> buffer; 120 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
120 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); 121 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
121 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); 122 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", nullptr);
122 123
123 DWORD max_length = 0; 124 DWORD max_length = 0;
124 DWORD current_length = 0; 125 DWORD current_length = 0;
125 uint8* destination = NULL; 126 uint8* destination = nullptr;
126 hr = buffer->Lock(&destination, &max_length, &current_length); 127 hr = buffer->Lock(&destination, &max_length, &current_length);
127 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); 128 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", nullptr);
128 129
129 CHECK_EQ(current_length, 0u); 130 CHECK_EQ(current_length, 0u);
130 CHECK_GE(static_cast<int>(max_length), size); 131 CHECK_GE(static_cast<int>(max_length), size);
131 memcpy(destination, stream, size); 132 memcpy(destination, stream, size);
132 133
133 hr = buffer->Unlock(); 134 hr = buffer->Unlock();
134 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); 135 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", nullptr);
135 136
136 hr = buffer->SetCurrentLength(size); 137 hr = buffer->SetCurrentLength(size);
137 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); 138 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", nullptr);
138 139
139 return sample.Detach(); 140 return sample.Detach();
140 } 141 }
141 142
142 static IMFSample* CreateSampleFromInputBuffer( 143 static IMFSample* CreateSampleFromInputBuffer(
143 const media::BitstreamBuffer& bitstream_buffer, 144 const media::BitstreamBuffer& bitstream_buffer,
144 DWORD stream_size, 145 DWORD stream_size,
145 DWORD alignment) { 146 DWORD alignment) {
146 base::SharedMemory shm(bitstream_buffer.handle(), true); 147 base::SharedMemory shm(bitstream_buffer.handle(), true);
147 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), 148 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()),
148 "Failed in base::SharedMemory::Map", NULL); 149 "Failed in base::SharedMemory::Map", nullptr);
149 150
150 return CreateInputSample(reinterpret_cast<const uint8*>(shm.memory()), 151 return CreateInputSample(reinterpret_cast<const uint8*>(shm.memory()),
151 bitstream_buffer.size(), 152 bitstream_buffer.size(),
152 stream_size, 153 stream_size,
153 alignment); 154 alignment);
154 } 155 }
155 156
156 // Maintains information about a DXVA picture buffer, i.e. whether it is 157 // Maintains information about a DXVA picture buffer, i.e. whether it is
157 // available for rendering, the texture information, etc. 158 // available for rendering, the texture information, etc.
158 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer { 159 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, 223 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
223 EGL_NONE 224 EGL_NONE
224 }; 225 };
225 226
226 picture_buffer->decoding_surface_ = eglCreatePbufferSurface( 227 picture_buffer->decoding_surface_ = eglCreatePbufferSurface(
227 egl_display, 228 egl_display,
228 egl_config, 229 egl_config,
229 attrib_list); 230 attrib_list);
230 RETURN_ON_FAILURE(picture_buffer->decoding_surface_, 231 RETURN_ON_FAILURE(picture_buffer->decoding_surface_,
231 "Failed to create surface", 232 "Failed to create surface",
232 linked_ptr<DXVAPictureBuffer>(NULL)); 233 linked_ptr<DXVAPictureBuffer>(nullptr));
233 234
234 HANDLE share_handle = NULL; 235 HANDLE share_handle = nullptr;
235 EGLBoolean ret = eglQuerySurfacePointerANGLE( 236 EGLBoolean ret = eglQuerySurfacePointerANGLE(
236 egl_display, 237 egl_display,
237 picture_buffer->decoding_surface_, 238 picture_buffer->decoding_surface_,
238 EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, 239 EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
239 &share_handle); 240 &share_handle);
240 241
241 RETURN_ON_FAILURE(share_handle && ret == EGL_TRUE, 242 RETURN_ON_FAILURE(share_handle && ret == EGL_TRUE,
242 "Failed to query ANGLE surface pointer", 243 "Failed to query ANGLE surface pointer",
243 linked_ptr<DXVAPictureBuffer>(NULL)); 244 linked_ptr<DXVAPictureBuffer>(nullptr));
244 245
245 HRESULT hr = decoder.device_->CreateTexture( 246 HRESULT hr = decoder.device_->CreateTexture(
246 buffer.size().width(), 247 buffer.size().width(),
247 buffer.size().height(), 248 buffer.size().height(),
248 1, 249 1,
249 D3DUSAGE_RENDERTARGET, 250 D3DUSAGE_RENDERTARGET,
250 use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8, 251 use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
251 D3DPOOL_DEFAULT, 252 D3DPOOL_DEFAULT,
252 picture_buffer->decoding_texture_.Receive(), 253 picture_buffer->decoding_texture_.Receive(),
253 &share_handle); 254 &share_handle);
254 255
255 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", 256 RETURN_ON_HR_FAILURE(hr, "Failed to create texture",
256 linked_ptr<DXVAPictureBuffer>(NULL)); 257 linked_ptr<DXVAPictureBuffer>(nullptr));
257 picture_buffer->use_rgb_ = !!use_rgb; 258 picture_buffer->use_rgb_ = !!use_rgb;
258 return picture_buffer; 259 return picture_buffer;
259 } 260 }
260 261
261 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer( 262 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer(
262 const media::PictureBuffer& buffer) 263 const media::PictureBuffer& buffer)
263 : available_(true), 264 : available_(true),
264 picture_buffer_(buffer), 265 picture_buffer_(buffer),
265 decoding_surface_(NULL), 266 decoding_surface_(nullptr),
266 use_rgb_(true) { 267 use_rgb_(true) {
267 } 268 }
268 269
269 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() { 270 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() {
270 if (decoding_surface_) { 271 if (decoding_surface_) {
271 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 272 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
272 273
273 eglReleaseTexImage( 274 eglReleaseTexImage(
274 egl_display, 275 egl_display,
275 decoding_surface_, 276 decoding_surface_,
276 EGL_BACK_BUFFER); 277 EGL_BACK_BUFFER);
277 278
278 eglDestroySurface( 279 eglDestroySurface(
279 egl_display, 280 egl_display,
280 decoding_surface_); 281 decoding_surface_);
281 decoding_surface_ = NULL; 282 decoding_surface_ = nullptr;
282 } 283 }
283 } 284 }
284 285
285 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() { 286 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
286 DCHECK(decoding_surface_); 287 DCHECK(decoding_surface_);
287 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 288 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
288 eglReleaseTexImage( 289 eglReleaseTexImage(
289 egl_display, 290 egl_display,
290 decoding_surface_, 291 decoding_surface_,
291 EGL_BACK_BUFFER); 292 EGL_BACK_BUFFER);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 324
324 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); 325 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id());
325 326
326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
327 328
328 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface; 329 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface;
329 hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive()); 330 hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive());
330 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); 331 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false);
331 332
332 hr = decoder.device_->StretchRect( 333 hr = decoder.device_->StretchRect(
333 dest_surface, NULL, d3d_surface, NULL, D3DTEXF_NONE); 334 dest_surface, nullptr, d3d_surface, nullptr, D3DTEXF_NONE);
334 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", 335 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed",
335 false); 336 false);
336 337
337 // Ideally, this should be done immediately before the draw call that uses 338 // Ideally, this should be done immediately before the draw call that uses
338 // the texture. Flush it once here though. 339 // the texture. Flush it once here though.
339 hr = decoder.query_->Issue(D3DISSUE_END); 340 hr = decoder.query_->Issue(D3DISSUE_END);
340 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); 341 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false);
341 342
342 // The DXVA decoder has its own device which it uses for decoding. ANGLE 343 // 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. 344 // has its own device which we don't have access to.
344 // The above code attempts to copy the decoded picture into a surface 345 // The above code attempts to copy the decoded picture into a surface
345 // which is owned by ANGLE. As there are multiple devices involved in 346 // which is owned by ANGLE. As there are multiple devices involved in
346 // this, the StretchRect call above is not synchronous. 347 // this, the StretchRect call above is not synchronous.
347 // We attempt to flush the batched operations to ensure that the picture is 348 // We attempt to flush the batched operations to ensure that the picture is
348 // copied to the surface owned by ANGLE. 349 // copied to the surface owned by ANGLE.
349 // We need to do this in a loop and call flush multiple times. 350 // We need to do this in a loop and call flush multiple times.
350 // We have seen the GetData call for flushing the command buffer fail to 351 // We have seen the GetData call for flushing the command buffer fail to
351 // return success occassionally on multi core machines, leading to an 352 // return success occassionally on multi core machines, leading to an
352 // infinite loop. 353 // infinite loop.
353 // Workaround is to have an upper limit of 10 on the number of iterations to 354 // Workaround is to have an upper limit of 10 on the number of iterations to
354 // wait for the Flush to finish. 355 // wait for the Flush to finish.
355 int iterations = 0; 356 int iterations = 0;
356 while ((decoder.query_->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE) && 357 while ((decoder.query_->GetData(nullptr, 0, D3DGETDATA_FLUSH) == S_FALSE) &&
357 ++iterations < kMaxIterationsForD3DFlush) { 358 ++iterations < kMaxIterationsForD3DFlush) {
358 Sleep(1); // Poor-man's Yield(). 359 Sleep(1); // Poor-man's Yield().
359 } 360 }
360 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 361 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
361 eglBindTexImage( 362 eglBindTexImage(
362 egl_display, 363 egl_display,
363 decoding_surface_, 364 decoding_surface_,
364 EGL_BACK_BUFFER); 365 EGL_BACK_BUFFER);
365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
366 glBindTexture(GL_TEXTURE_2D, current_texture); 367 glBindTexture(GL_TEXTURE_2D, current_texture);
(...skipping 28 matching lines...) Expand all
395 present_params.PresentationInterval = 0; 396 present_params.PresentationInterval = 0;
396 397
397 hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT, 398 hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT,
398 D3DDEVTYPE_HAL, 399 D3DDEVTYPE_HAL,
399 ::GetShellWindow(), 400 ::GetShellWindow(),
400 D3DCREATE_FPU_PRESERVE | 401 D3DCREATE_FPU_PRESERVE |
401 D3DCREATE_SOFTWARE_VERTEXPROCESSING | 402 D3DCREATE_SOFTWARE_VERTEXPROCESSING |
402 D3DCREATE_DISABLE_PSGP_THREADING | 403 D3DCREATE_DISABLE_PSGP_THREADING |
403 D3DCREATE_MULTITHREADED, 404 D3DCREATE_MULTITHREADED,
404 &present_params, 405 &present_params,
405 NULL, 406 nullptr,
406 device_.Receive()); 407 device_.Receive());
407 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false); 408 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false);
408 409
409 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_, 410 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_,
410 device_manager_.Receive()); 411 device_manager_.Receive());
411 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false); 412 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false);
412 413
413 hr = device_manager_->ResetDevice(device_, dev_manager_reset_token_); 414 hr = device_manager_->ResetDevice(device_, dev_manager_reset_token_);
414 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 415 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
415 416
416 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); 417 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive());
417 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); 418 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false);
418 // Ensure query_ API works (to avoid an infinite loop later in 419 // Ensure query_ API works (to avoid an infinite loop later in
419 // CopyOutputSampleDataToPictureBuffer). 420 // CopyOutputSampleDataToPictureBuffer).
420 hr = query_->Issue(D3DISSUE_END); 421 hr = query_->Issue(D3DISSUE_END);
421 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); 422 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false);
422 return true; 423 return true;
423 } 424 }
424 425
425 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( 426 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
426 const base::Callback<bool(void)>& make_context_current) 427 const base::Callback<bool(void)>& make_context_current)
427 : client_(NULL), 428 : client_(nullptr),
428 dev_manager_reset_token_(0), 429 dev_manager_reset_token_(0),
429 egl_config_(NULL), 430 egl_config_(nullptr),
430 state_(kUninitialized), 431 state_(kUninitialized),
431 pictures_requested_(false), 432 pictures_requested_(false),
432 inputs_before_decode_(0), 433 inputs_before_decode_(0),
433 make_context_current_(make_context_current), 434 make_context_current_(make_context_current),
434 weak_this_factory_(this) { 435 weak_this_factory_(this) {
435 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 436 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
436 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 437 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
437 } 438 }
438 439
439 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 440 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
440 client_ = NULL; 441 client_ = nullptr;
441 } 442 }
442 443
443 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 444 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
444 Client* client) { 445 Client* client) {
445 DCHECK(CalledOnValidThread()); 446 DCHECK(CalledOnValidThread());
446 447
447 client_ = client; 448 client_ = client;
448 449
449 // Not all versions of Windows 7 and later include Media Foundation DLLs. 450 // Not all versions of Windows 7 and later include Media Foundation DLLs.
450 // Instead of crashing while delay loading the DLL when calling MFStartup() 451 // Instead of crashing while delay loading the DLL when calling MFStartup()
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 GetProcAddress(decoder_dll, "DllGetClassObject")); 673 GetProcAddress(decoder_dll, "DllGetClassObject"));
673 RETURN_ON_FAILURE( 674 RETURN_ON_FAILURE(
674 get_class_object, "Failed to get DllGetClassObject pointer", false); 675 get_class_object, "Failed to get DllGetClassObject pointer", false);
675 676
676 base::win::ScopedComPtr<IClassFactory> factory; 677 base::win::ScopedComPtr<IClassFactory> factory;
677 HRESULT hr = get_class_object(__uuidof(CMSH264DecoderMFT), 678 HRESULT hr = get_class_object(__uuidof(CMSH264DecoderMFT),
678 __uuidof(IClassFactory), 679 __uuidof(IClassFactory),
679 reinterpret_cast<void**>(factory.Receive())); 680 reinterpret_cast<void**>(factory.Receive()));
680 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false); 681 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false);
681 682
682 hr = factory->CreateInstance(NULL, 683 hr = factory->CreateInstance(nullptr,
683 __uuidof(IMFTransform), 684 __uuidof(IMFTransform),
684 reinterpret_cast<void**>(decoder_.Receive())); 685 reinterpret_cast<void**>(decoder_.Receive()));
685 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); 686 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false);
686 687
687 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), 688 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(),
688 "Failed to check decoder DXVA support", false); 689 "Failed to check decoder DXVA support", false);
689 690
690 hr = decoder_->ProcessMessage( 691 hr = decoder_->ProcessMessage(
691 MFT_MESSAGE_SET_D3D_MANAGER, 692 MFT_MESSAGE_SET_D3D_MANAGER,
692 reinterpret_cast<ULONG_PTR>(device_manager_.get())); 693 reinterpret_cast<ULONG_PTR>(device_manager_.get()));
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE,); 829 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE,);
829 830
830 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; 831 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0};
831 DWORD status = 0; 832 DWORD status = 0;
832 833
833 HRESULT hr = decoder_->ProcessOutput(0, // No flags 834 HRESULT hr = decoder_->ProcessOutput(0, // No flags
834 1, // # of out streams to pull from 835 1, // # of out streams to pull from
835 &output_data_buffer, 836 &output_data_buffer,
836 &status); 837 &status);
837 IMFCollection* events = output_data_buffer.pEvents; 838 IMFCollection* events = output_data_buffer.pEvents;
838 if (events != NULL) { 839 if (events != nullptr) {
839 VLOG(1) << "Got events from ProcessOuput, but discarding"; 840 VLOG(1) << "Got events from ProcessOuput, but discarding";
840 events->Release(); 841 events->Release();
841 } 842 }
842 if (FAILED(hr)) { 843 if (FAILED(hr)) {
843 // A stream change needs further ProcessInput calls to get back decoder 844 // A stream change needs further ProcessInput calls to get back decoder
844 // output which is why we need to set the state to stopped. 845 // output which is why we need to set the state to stopped.
845 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { 846 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
846 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12)) { 847 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12)) {
847 // Decoder didn't let us set NV12 output format. Not sure as to why 848 // Decoder didn't let us set NV12 output format. Not sure as to why
848 // this can happen. Give up in disgust. 849 // this can happen. Give up in disgust.
(...skipping 19 matching lines...) Expand all
868 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", 869 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode",
869 inputs_before_decode_); 870 inputs_before_decode_);
870 871
871 inputs_before_decode_ = 0; 872 inputs_before_decode_ = 0;
872 873
873 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_data_buffer.pSample), 874 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_data_buffer.pSample),
874 "Failed to process output sample.", PLATFORM_FAILURE,); 875 "Failed to process output sample.", PLATFORM_FAILURE,);
875 } 876 }
876 877
877 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) { 878 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) {
878 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); 879 RETURN_ON_FAILURE(sample, "Decode succeeded with nullptr output sample",
880 false);
879 881
880 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 882 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
881 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); 883 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive());
882 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); 884 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
883 885
884 base::win::ScopedComPtr<IDirect3DSurface9> surface; 886 base::win::ScopedComPtr<IDirect3DSurface9> surface;
885 hr = MFGetService(output_buffer, MR_BUFFER_SERVICE, 887 hr = MFGetService(output_buffer, MR_BUFFER_SERVICE,
886 IID_PPV_ARGS(surface.Receive())); 888 IID_PPV_ARGS(surface.Receive()));
887 RETURN_ON_HR_FAILURE(hr, "Failed to get D3D surface from output sample", 889 RETURN_ON_HR_FAILURE(hr, "Failed to get D3D surface from output sample",
888 false); 890 false);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 weak_this_factory_.GetWeakPtr())); 992 weak_this_factory_.GetWeakPtr()));
991 } 993 }
992 } 994 }
993 995
994 void DXVAVideoDecodeAccelerator::StopOnError( 996 void DXVAVideoDecodeAccelerator::StopOnError(
995 media::VideoDecodeAccelerator::Error error) { 997 media::VideoDecodeAccelerator::Error error) {
996 DCHECK(CalledOnValidThread()); 998 DCHECK(CalledOnValidThread());
997 999
998 if (client_) 1000 if (client_)
999 client_->NotifyError(error); 1001 client_->NotifyError(error);
1000 client_ = NULL; 1002 client_ = nullptr;
1001 1003
1002 if (state_ != kUninitialized) { 1004 if (state_ != kUninitialized) {
1003 Invalidate(); 1005 Invalidate();
1004 } 1006 }
1005 } 1007 }
1006 1008
1007 void DXVAVideoDecodeAccelerator::Invalidate() { 1009 void DXVAVideoDecodeAccelerator::Invalidate() {
1008 if (state_ == kUninitialized) 1010 if (state_ == kUninitialized)
1009 return; 1011 return;
1010 weak_this_factory_.InvalidateWeakPtrs(); 1012 weak_this_factory_.InvalidateWeakPtrs();
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 int32 picture_buffer_id) { 1221 int32 picture_buffer_id) {
1220 OutputBuffers::iterator it = stale_output_picture_buffers_.find( 1222 OutputBuffers::iterator it = stale_output_picture_buffers_.find(
1221 picture_buffer_id); 1223 picture_buffer_id);
1222 DCHECK(it != stale_output_picture_buffers_.end()); 1224 DCHECK(it != stale_output_picture_buffers_.end());
1223 DVLOG(1) << "Dismissing picture id: " << it->second->id(); 1225 DVLOG(1) << "Dismissing picture id: " << it->second->id();
1224 client_->DismissPictureBuffer(it->second->id()); 1226 client_->DismissPictureBuffer(it->second->id());
1225 stale_output_picture_buffers_.erase(it); 1227 stale_output_picture_buffers_.erase(it);
1226 } 1228 }
1227 1229
1228 } // namespace content 1230 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_encode_accelerator.cc ('k') | content/common/gpu/media/exynos_v4l2_video_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698