| 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 // Maximum number of iterations we allow before aborting the attempt to flush | 159 // Maximum number of iterations we allow before aborting the attempt to flush |
| 160 // the batched queries to the driver and allow torn/corrupt frames to be | 160 // the batched queries to the driver and allow torn/corrupt frames to be |
| 161 // rendered. | 161 // rendered. |
| 162 kFlushDecoderSurfaceTimeoutMs = 1, | 162 kFlushDecoderSurfaceTimeoutMs = 1, |
| 163 // Maximum iterations where we try to flush the d3d device. | 163 // Maximum iterations where we try to flush the d3d device. |
| 164 kMaxIterationsForD3DFlush = 4, | 164 kMaxIterationsForD3DFlush = 4, |
| 165 // We only request 5 picture buffers from the client which are used to hold | 165 // We only request 5 picture buffers from the client which are used to hold |
| 166 // the decoded samples. These buffers are then reused when the client tells | 166 // the decoded samples. These buffers are then reused when the client tells |
| 167 // us that it is done with the buffer. | 167 // us that it is done with the buffer. |
| 168 kNumPictureBuffers = 5, | 168 kNumPictureBuffers = 5, |
| 169 // The keyed mutex should always be released before the other thread |
| 170 // attempts to acquire it, so AcquireSync should always return immediately. |
| 171 kAcquireSyncWaitMs = 0, |
| 169 }; | 172 }; |
| 170 | 173 |
| 171 static IMFSample* CreateEmptySample() { | 174 static IMFSample* CreateEmptySample() { |
| 172 base::win::ScopedComPtr<IMFSample> sample; | 175 base::win::ScopedComPtr<IMFSample> sample; |
| 173 HRESULT hr = MFCreateSample(sample.Receive()); | 176 HRESULT hr = MFCreateSample(sample.Receive()); |
| 174 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); | 177 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); |
| 175 return sample.Detach(); | 178 return sample.Detach(); |
| 176 } | 179 } |
| 177 | 180 |
| 178 // 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| |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 // Maintains information about a DXVA picture buffer, i.e. whether it is | 345 // Maintains information about a DXVA picture buffer, i.e. whether it is |
| 343 // available for rendering, the texture information, etc. | 346 // available for rendering, the texture information, etc. |
| 344 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer { | 347 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer { |
| 345 public: | 348 public: |
| 346 static linked_ptr<DXVAPictureBuffer> Create( | 349 static linked_ptr<DXVAPictureBuffer> Create( |
| 347 const DXVAVideoDecodeAccelerator& decoder, | 350 const DXVAVideoDecodeAccelerator& decoder, |
| 348 const media::PictureBuffer& buffer, | 351 const media::PictureBuffer& buffer, |
| 349 EGLConfig egl_config); | 352 EGLConfig egl_config); |
| 350 ~DXVAPictureBuffer(); | 353 ~DXVAPictureBuffer(); |
| 351 | 354 |
| 352 void ReusePictureBuffer(); | 355 bool InitializeTexture(const DXVAVideoDecodeAccelerator& decoder, |
| 356 bool use_rgb); |
| 357 |
| 358 bool ReusePictureBuffer(); |
| 353 // Copies the output sample data to the picture buffer provided by the | 359 // Copies the output sample data to the picture buffer provided by the |
| 354 // client. | 360 // client. |
| 355 // The dest_surface parameter contains the decoded bits. | 361 // The dest_surface parameter contains the decoded bits. |
| 356 bool CopyOutputSampleDataToPictureBuffer( | 362 bool CopyOutputSampleDataToPictureBuffer( |
| 357 DXVAVideoDecodeAccelerator* decoder, | 363 DXVAVideoDecodeAccelerator* decoder, |
| 358 IDirect3DSurface9* dest_surface, | 364 IDirect3DSurface9* dest_surface, |
| 359 ID3D11Texture2D* dx11_texture, | 365 ID3D11Texture2D* dx11_texture, |
| 360 int input_buffer_id); | 366 int input_buffer_id); |
| 361 | 367 |
| 362 bool available() const { | 368 bool available() const { |
| 363 return available_; | 369 return available_; |
| 364 } | 370 } |
| 365 | 371 |
| 366 void set_available(bool available) { | 372 void set_available(bool available) { |
| 367 available_ = available; | 373 available_ = available; |
| 368 } | 374 } |
| 369 | 375 |
| 370 int id() const { | 376 int id() const { |
| 371 return picture_buffer_.id(); | 377 return picture_buffer_.id(); |
| 372 } | 378 } |
| 373 | 379 |
| 374 gfx::Size size() const { | 380 gfx::Size size() const { |
| 375 return picture_buffer_.size(); | 381 return picture_buffer_.size(); |
| 376 } | 382 } |
| 377 | 383 |
| 378 // Called when the source surface |src_surface| is copied to the destination | 384 // Called when the source surface |src_surface| is copied to the destination |
| 379 // |dest_surface| | 385 // |dest_surface| |
| 380 void CopySurfaceComplete(IDirect3DSurface9* src_surface, | 386 bool CopySurfaceComplete(IDirect3DSurface9* src_surface, |
| 381 IDirect3DSurface9* dest_surface); | 387 IDirect3DSurface9* dest_surface); |
| 382 | 388 |
| 383 private: | 389 private: |
| 384 explicit DXVAPictureBuffer(const media::PictureBuffer& buffer); | 390 explicit DXVAPictureBuffer(const media::PictureBuffer& buffer); |
| 385 | 391 |
| 386 bool available_; | 392 bool available_; |
| 387 media::PictureBuffer picture_buffer_; | 393 media::PictureBuffer picture_buffer_; |
| 388 EGLSurface decoding_surface_; | 394 EGLSurface decoding_surface_; |
| 395 |
| 396 HANDLE texture_share_handle_; |
| 389 base::win::ScopedComPtr<IDirect3DTexture9> decoding_texture_; | 397 base::win::ScopedComPtr<IDirect3DTexture9> decoding_texture_; |
| 390 base::win::ScopedComPtr<ID3D11Texture2D> dx11_decoding_texture_; | 398 base::win::ScopedComPtr<ID3D11Texture2D> dx11_decoding_texture_; |
| 391 | 399 |
| 400 base::win::ScopedComPtr<IDXGIKeyedMutex> egl_keyed_mutex_; |
| 401 base::win::ScopedComPtr<IDXGIKeyedMutex> dx11_keyed_mutex_; |
| 402 |
| 403 // This is the last value that was used to release the keyed mutex. |
| 404 uint64_t keyed_mutex_value_; |
| 405 |
| 392 // The following |IDirect3DSurface9| interface pointers are used to hold | 406 // The following |IDirect3DSurface9| interface pointers are used to hold |
| 393 // references on the surfaces during the course of a StretchRect operation | 407 // references on the surfaces during the course of a StretchRect operation |
| 394 // to copy the source surface to the target. The references are released | 408 // to copy the source surface to the target. The references are released |
| 395 // when the StretchRect operation i.e. the copy completes. | 409 // when the StretchRect operation i.e. the copy completes. |
| 396 base::win::ScopedComPtr<IDirect3DSurface9> decoder_surface_; | 410 base::win::ScopedComPtr<IDirect3DSurface9> decoder_surface_; |
| 397 base::win::ScopedComPtr<IDirect3DSurface9> target_surface_; | 411 base::win::ScopedComPtr<IDirect3DSurface9> target_surface_; |
| 398 | 412 |
| 399 // This ID3D11Texture2D interface pointer is used to hold a reference to the | 413 // This ID3D11Texture2D interface pointer is used to hold a reference to the |
| 400 // decoder texture during the course of a copy operation. This reference is | 414 // decoder texture during the course of a copy operation. This reference is |
| 401 // released when the copy completes. | 415 // released when the copy completes. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 415 const media::PictureBuffer& buffer, | 429 const media::PictureBuffer& buffer, |
| 416 EGLConfig egl_config) { | 430 EGLConfig egl_config) { |
| 417 linked_ptr<DXVAPictureBuffer> picture_buffer(new DXVAPictureBuffer(buffer)); | 431 linked_ptr<DXVAPictureBuffer> picture_buffer(new DXVAPictureBuffer(buffer)); |
| 418 | 432 |
| 419 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 433 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
| 420 | 434 |
| 421 EGLint use_rgb = 1; | 435 EGLint use_rgb = 1; |
| 422 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, | 436 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, |
| 423 &use_rgb); | 437 &use_rgb); |
| 424 | 438 |
| 439 if (!picture_buffer->InitializeTexture(decoder, !!use_rgb)) |
| 440 return linked_ptr<DXVAPictureBuffer>(nullptr); |
| 441 |
| 425 EGLint attrib_list[] = { | 442 EGLint attrib_list[] = { |
| 426 EGL_WIDTH, buffer.size().width(), | 443 EGL_WIDTH, buffer.size().width(), |
| 427 EGL_HEIGHT, buffer.size().height(), | 444 EGL_HEIGHT, buffer.size().height(), |
| 428 EGL_TEXTURE_FORMAT, use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA, | 445 EGL_TEXTURE_FORMAT, use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA, |
| 429 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, | 446 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, |
| 430 EGL_NONE | 447 EGL_NONE |
| 431 }; | 448 }; |
| 432 | 449 |
| 433 picture_buffer->decoding_surface_ = eglCreatePbufferSurface( | 450 picture_buffer->decoding_surface_ = eglCreatePbufferFromClientBuffer( |
| 434 egl_display, | 451 egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, |
| 435 egl_config, | 452 picture_buffer->texture_share_handle_, egl_config, attrib_list); |
| 436 attrib_list); | |
| 437 RETURN_ON_FAILURE(picture_buffer->decoding_surface_, | 453 RETURN_ON_FAILURE(picture_buffer->decoding_surface_, |
| 438 "Failed to create surface", | 454 "Failed to create surface", |
| 439 linked_ptr<DXVAPictureBuffer>(NULL)); | 455 linked_ptr<DXVAPictureBuffer>(NULL)); |
| 440 | 456 if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) { |
| 441 HANDLE share_handle = NULL; | 457 void* keyed_mutex = nullptr; |
| 442 EGLBoolean ret = eglQuerySurfacePointerANGLE( | 458 EGLBoolean ret = eglQuerySurfacePointerANGLE( |
| 443 egl_display, | 459 egl_display, picture_buffer->decoding_surface_, |
| 444 picture_buffer->decoding_surface_, | 460 EGL_DXGI_KEYED_MUTEX_ANGLE, &keyed_mutex); |
| 445 EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, | 461 RETURN_ON_FAILURE(keyed_mutex && ret == EGL_TRUE, |
| 446 &share_handle); | 462 "Failed to query ANGLE keyed mutex", |
| 447 | 463 linked_ptr<DXVAPictureBuffer>(nullptr)); |
| 448 RETURN_ON_FAILURE(share_handle && ret == EGL_TRUE, | 464 picture_buffer->egl_keyed_mutex_ = base::win::ScopedComPtr<IDXGIKeyedMutex>( |
| 449 "Failed to query ANGLE surface pointer", | 465 static_cast<IDXGIKeyedMutex*>(keyed_mutex)); |
| 450 linked_ptr<DXVAPictureBuffer>(NULL)); | |
| 451 | |
| 452 HRESULT hr = E_FAIL; | |
| 453 if (decoder.d3d11_device_) { | |
| 454 base::win::ScopedComPtr<ID3D11Resource> resource; | |
| 455 hr = decoder.d3d11_device_->OpenSharedResource( | |
| 456 share_handle, | |
| 457 __uuidof(ID3D11Resource), | |
| 458 reinterpret_cast<void**>(resource.Receive())); | |
| 459 RETURN_ON_HR_FAILURE(hr, "Failed to open shared resource", | |
| 460 linked_ptr<DXVAPictureBuffer>(NULL)); | |
| 461 hr = picture_buffer->dx11_decoding_texture_.QueryFrom(resource.get()); | |
| 462 } else { | |
| 463 hr = decoder.d3d9_device_ex_->CreateTexture( | |
| 464 buffer.size().width(), | |
| 465 buffer.size().height(), | |
| 466 1, | |
| 467 D3DUSAGE_RENDERTARGET, | |
| 468 use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8, | |
| 469 D3DPOOL_DEFAULT, | |
| 470 picture_buffer->decoding_texture_.Receive(), | |
| 471 &share_handle); | |
| 472 } | 466 } |
| 473 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", | |
| 474 linked_ptr<DXVAPictureBuffer>(NULL)); | |
| 475 picture_buffer->use_rgb_ = !!use_rgb; | 467 picture_buffer->use_rgb_ = !!use_rgb; |
| 476 return picture_buffer; | 468 return picture_buffer; |
| 477 } | 469 } |
| 478 | 470 |
| 471 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::InitializeTexture( |
| 472 const DXVAVideoDecodeAccelerator& decoder, |
| 473 bool use_rgb) { |
| 474 DCHECK(!texture_share_handle_); |
| 475 if (decoder.d3d11_device_) { |
| 476 D3D11_TEXTURE2D_DESC desc; |
| 477 desc.Width = picture_buffer_.size().width(); |
| 478 desc.Height = picture_buffer_.size().height(); |
| 479 desc.MipLevels = 1; |
| 480 desc.ArraySize = 1; |
| 481 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; |
| 482 desc.SampleDesc.Count = 1; |
| 483 desc.SampleDesc.Quality = 0; |
| 484 desc.Usage = D3D11_USAGE_DEFAULT; |
| 485 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; |
| 486 desc.CPUAccessFlags = 0; |
| 487 desc.MiscFlags = decoder.use_keyed_mutex_ |
| 488 ? D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX |
| 489 : D3D11_RESOURCE_MISC_SHARED; |
| 490 |
| 491 HRESULT hr = decoder.d3d11_device_->CreateTexture2D( |
| 492 &desc, nullptr, dx11_decoding_texture_.Receive()); |
| 493 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false); |
| 494 if (decoder.use_keyed_mutex_) { |
| 495 hr = dx11_keyed_mutex_.QueryFrom(dx11_decoding_texture_.get()); |
| 496 RETURN_ON_HR_FAILURE(hr, "Failed to get keyed mutex", false); |
| 497 } |
| 498 |
| 499 base::win::ScopedComPtr<IDXGIResource> resource; |
| 500 hr = resource.QueryFrom(dx11_decoding_texture_.get()); |
| 501 DCHECK(SUCCEEDED(hr)); |
| 502 hr = resource->GetSharedHandle(&texture_share_handle_); |
| 503 RETURN_ON_FAILURE(SUCCEEDED(hr) && texture_share_handle_, |
| 504 "Failed to query shared handle", false); |
| 505 |
| 506 } else { |
| 507 HRESULT hr = E_FAIL; |
| 508 hr = decoder.d3d9_device_ex_->CreateTexture( |
| 509 picture_buffer_.size().width(), picture_buffer_.size().height(), 1, |
| 510 D3DUSAGE_RENDERTARGET, use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8, |
| 511 D3DPOOL_DEFAULT, decoding_texture_.Receive(), &texture_share_handle_); |
| 512 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false); |
| 513 RETURN_ON_FAILURE(texture_share_handle_, "Failed to query shared handle", |
| 514 false); |
| 515 } |
| 516 return true; |
| 517 } |
| 518 |
| 479 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer( | 519 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer( |
| 480 const media::PictureBuffer& buffer) | 520 const media::PictureBuffer& buffer) |
| 481 : available_(true), | 521 : available_(true), |
| 482 picture_buffer_(buffer), | 522 picture_buffer_(buffer), |
| 483 decoding_surface_(NULL), | 523 decoding_surface_(NULL), |
| 484 use_rgb_(true) { | 524 texture_share_handle_(nullptr), |
| 485 } | 525 keyed_mutex_value_(0), |
| 526 use_rgb_(true) {} |
| 486 | 527 |
| 487 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() { | 528 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() { |
| 488 if (decoding_surface_) { | 529 if (decoding_surface_) { |
| 489 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 530 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
| 490 | 531 |
| 491 eglReleaseTexImage( | 532 eglReleaseTexImage( |
| 492 egl_display, | 533 egl_display, |
| 493 decoding_surface_, | 534 decoding_surface_, |
| 494 EGL_BACK_BUFFER); | 535 EGL_BACK_BUFFER); |
| 495 | 536 |
| 496 eglDestroySurface( | 537 eglDestroySurface( |
| 497 egl_display, | 538 egl_display, |
| 498 decoding_surface_); | 539 decoding_surface_); |
| 499 decoding_surface_ = NULL; | 540 decoding_surface_ = NULL; |
| 500 } | 541 } |
| 501 } | 542 } |
| 502 | 543 |
| 503 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() { | 544 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() { |
| 504 DCHECK(decoding_surface_); | 545 DCHECK(decoding_surface_); |
| 505 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 546 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
| 506 eglReleaseTexImage( | 547 eglReleaseTexImage( |
| 507 egl_display, | 548 egl_display, |
| 508 decoding_surface_, | 549 decoding_surface_, |
| 509 EGL_BACK_BUFFER); | 550 EGL_BACK_BUFFER); |
| 510 decoder_surface_.Release(); | 551 decoder_surface_.Release(); |
| 511 target_surface_.Release(); | 552 target_surface_.Release(); |
| 512 decoder_dx11_texture_.Release(); | 553 decoder_dx11_texture_.Release(); |
| 513 set_available(true); | 554 set_available(true); |
| 555 if (egl_keyed_mutex_) { |
| 556 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_); |
| 557 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false); |
| 558 } |
| 559 return true; |
| 514 } | 560 } |
| 515 | 561 |
| 516 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer:: | 562 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer:: |
| 517 CopyOutputSampleDataToPictureBuffer( | 563 CopyOutputSampleDataToPictureBuffer( |
| 518 DXVAVideoDecodeAccelerator* decoder, | 564 DXVAVideoDecodeAccelerator* decoder, |
| 519 IDirect3DSurface9* dest_surface, | 565 IDirect3DSurface9* dest_surface, |
| 520 ID3D11Texture2D* dx11_texture, | 566 ID3D11Texture2D* dx11_texture, |
| 521 int input_buffer_id) { | 567 int input_buffer_id) { |
| 522 DCHECK(dest_surface || dx11_texture); | 568 DCHECK(dest_surface || dx11_texture); |
| 523 if (dx11_texture) { | 569 if (dx11_texture) { |
| 524 // Grab a reference on the decoder texture. This reference will be released | 570 // Grab a reference on the decoder texture. This reference will be released |
| 525 // when we receive a notification that the copy was completed or when the | 571 // when we receive a notification that the copy was completed or when the |
| 526 // DXVAPictureBuffer instance is destroyed. | 572 // DXVAPictureBuffer instance is destroyed. |
| 527 decoder_dx11_texture_ = dx11_texture; | 573 decoder_dx11_texture_ = dx11_texture; |
| 528 decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(), NULL, | 574 decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(), |
| 529 id(), input_buffer_id); | 575 dx11_keyed_mutex_, keyed_mutex_value_, NULL, id(), |
| 576 input_buffer_id); |
| 530 return true; | 577 return true; |
| 531 } | 578 } |
| 532 D3DSURFACE_DESC surface_desc; | 579 D3DSURFACE_DESC surface_desc; |
| 533 HRESULT hr = dest_surface->GetDesc(&surface_desc); | 580 HRESULT hr = dest_surface->GetDesc(&surface_desc); |
| 534 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); | 581 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); |
| 535 | 582 |
| 536 D3DSURFACE_DESC texture_desc; | 583 D3DSURFACE_DESC texture_desc; |
| 537 decoding_texture_->GetLevelDesc(0, &texture_desc); | 584 decoding_texture_->GetLevelDesc(0, &texture_desc); |
| 538 | 585 |
| 539 if (texture_desc.Width != surface_desc.Width || | 586 if (texture_desc.Width != surface_desc.Width || |
| (...skipping 19 matching lines...) Expand all Loading... |
| 559 hr = decoding_texture_->GetSurfaceLevel(0, target_surface_.Receive()); | 606 hr = decoding_texture_->GetSurfaceLevel(0, target_surface_.Receive()); |
| 560 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); | 607 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); |
| 561 | 608 |
| 562 decoder_surface_ = dest_surface; | 609 decoder_surface_ = dest_surface; |
| 563 | 610 |
| 564 decoder->CopySurface(decoder_surface_.get(), target_surface_.get(), id(), | 611 decoder->CopySurface(decoder_surface_.get(), target_surface_.get(), id(), |
| 565 input_buffer_id); | 612 input_buffer_id); |
| 566 return true; | 613 return true; |
| 567 } | 614 } |
| 568 | 615 |
| 569 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete( | 616 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete( |
| 570 IDirect3DSurface9* src_surface, | 617 IDirect3DSurface9* src_surface, |
| 571 IDirect3DSurface9* dest_surface) { | 618 IDirect3DSurface9* dest_surface) { |
| 572 DCHECK(!available()); | 619 DCHECK(!available()); |
| 573 | 620 |
| 574 GLint current_texture = 0; | 621 GLint current_texture = 0; |
| 575 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); | 622 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
| 576 | 623 |
| 577 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); | 624 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); |
| 578 | 625 |
| 579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 626 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 580 | 627 |
| 581 if (src_surface && dest_surface) { | 628 if (src_surface && dest_surface) { |
| 582 DCHECK_EQ(src_surface, decoder_surface_.get()); | 629 DCHECK_EQ(src_surface, decoder_surface_.get()); |
| 583 DCHECK_EQ(dest_surface, target_surface_.get()); | 630 DCHECK_EQ(dest_surface, target_surface_.get()); |
| 584 decoder_surface_.Release(); | 631 decoder_surface_.Release(); |
| 585 target_surface_.Release(); | 632 target_surface_.Release(); |
| 586 } else { | 633 } else { |
| 587 DCHECK(decoder_dx11_texture_.get()); | 634 DCHECK(decoder_dx11_texture_.get()); |
| 588 decoder_dx11_texture_.Release(); | 635 decoder_dx11_texture_.Release(); |
| 589 } | 636 } |
| 637 if (egl_keyed_mutex_) { |
| 638 keyed_mutex_value_++; |
| 639 HRESULT result = |
| 640 egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs); |
| 641 RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false); |
| 642 } |
| 590 | 643 |
| 591 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 644 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
| 592 eglBindTexImage( | 645 eglBindTexImage( |
| 593 egl_display, | 646 egl_display, |
| 594 decoding_surface_, | 647 decoding_surface_, |
| 595 EGL_BACK_BUFFER); | 648 EGL_BACK_BUFFER); |
| 596 | 649 |
| 597 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 650 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 598 glBindTexture(GL_TEXTURE_2D, current_texture); | 651 glBindTexture(GL_TEXTURE_2D, current_texture); |
| 652 return true; |
| 599 } | 653 } |
| 600 | 654 |
| 601 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( | 655 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( |
| 602 int32_t buffer_id, | 656 int32_t buffer_id, |
| 603 IMFSample* sample) | 657 IMFSample* sample) |
| 604 : input_buffer_id(buffer_id), picture_buffer_id(-1) { | 658 : input_buffer_id(buffer_id), picture_buffer_id(-1) { |
| 605 output_sample.Attach(sample); | 659 output_sample.Attach(sample); |
| 606 } | 660 } |
| 607 | 661 |
| 608 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} | 662 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} |
| 609 | 663 |
| 610 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( | 664 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
| 611 const base::Callback<bool(void)>& make_context_current, | 665 const base::Callback<bool(void)>& make_context_current, |
| 612 gfx::GLContext* gl_context) | 666 gfx::GLContext* gl_context) |
| 613 : client_(NULL), | 667 : client_(NULL), |
| 614 dev_manager_reset_token_(0), | 668 dev_manager_reset_token_(0), |
| 615 dx11_dev_manager_reset_token_(0), | 669 dx11_dev_manager_reset_token_(0), |
| 616 egl_config_(NULL), | 670 egl_config_(NULL), |
| 617 state_(kUninitialized), | 671 state_(kUninitialized), |
| 618 pictures_requested_(false), | 672 pictures_requested_(false), |
| 619 inputs_before_decode_(0), | 673 inputs_before_decode_(0), |
| 620 sent_drain_message_(false), | 674 sent_drain_message_(false), |
| 621 make_context_current_(make_context_current), | 675 make_context_current_(make_context_current), |
| 622 codec_(media::kUnknownVideoCodec), | 676 codec_(media::kUnknownVideoCodec), |
| 623 decoder_thread_("DXVAVideoDecoderThread"), | 677 decoder_thread_("DXVAVideoDecoderThread"), |
| 624 pending_flush_(false), | 678 pending_flush_(false), |
| 625 use_dx11_(false), | 679 use_dx11_(false), |
| 680 use_keyed_mutex_(false), |
| 626 dx11_video_format_converter_media_type_needs_init_(true), | 681 dx11_video_format_converter_media_type_needs_init_(true), |
| 627 gl_context_(gl_context), | 682 gl_context_(gl_context), |
| 628 using_angle_device_(false), | 683 using_angle_device_(false), |
| 629 weak_this_factory_(this) { | 684 weak_this_factory_(this) { |
| 630 weak_ptr_ = weak_this_factory_.GetWeakPtr(); | 685 weak_ptr_ = weak_this_factory_.GetWeakPtr(); |
| 631 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); | 686 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); |
| 632 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); | 687 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); |
| 633 } | 688 } |
| 634 | 689 |
| 635 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { | 690 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 it = stale_output_picture_buffers_.find(picture_buffer_id); | 1014 it = stale_output_picture_buffers_.find(picture_buffer_id); |
| 960 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), | 1015 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), |
| 961 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); | 1016 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); |
| 962 main_thread_task_runner_->PostTask( | 1017 main_thread_task_runner_->PostTask( |
| 963 FROM_HERE, | 1018 FROM_HERE, |
| 964 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, | 1019 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, |
| 965 weak_this_factory_.GetWeakPtr(), picture_buffer_id)); | 1020 weak_this_factory_.GetWeakPtr(), picture_buffer_id)); |
| 966 return; | 1021 return; |
| 967 } | 1022 } |
| 968 | 1023 |
| 969 it->second->ReusePictureBuffer(); | 1024 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), |
| 1025 "Failed to reuse picture buffer", |
| 1026 PLATFORM_FAILURE, ); |
| 1027 |
| 970 ProcessPendingSamples(); | 1028 ProcessPendingSamples(); |
| 971 if (pending_flush_) { | 1029 if (pending_flush_) { |
| 972 decoder_thread_task_runner_->PostTask( | 1030 decoder_thread_task_runner_->PostTask( |
| 973 FROM_HERE, | 1031 FROM_HERE, |
| 974 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, | 1032 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, |
| 975 base::Unretained(this))); | 1033 base::Unretained(this))); |
| 976 } | 1034 } |
| 977 } | 1035 } |
| 978 | 1036 |
| 979 void DXVAVideoDecodeAccelerator::Flush() { | 1037 void DXVAVideoDecodeAccelerator::Flush() { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 // this. This should always be true for Windows 8+. | 1294 // this. This should always be true for Windows 8+. |
| 1237 // 3. ANGLE is using DX11. | 1295 // 3. ANGLE is using DX11. |
| 1238 DCHECK(gl_context_); | 1296 DCHECK(gl_context_); |
| 1239 if (create_dxgi_device_manager_ && | 1297 if (create_dxgi_device_manager_ && |
| 1240 (gl_context_->GetGLRenderer().find("Direct3D11") != | 1298 (gl_context_->GetGLRenderer().find("Direct3D11") != |
| 1241 std::string::npos)) { | 1299 std::string::npos)) { |
| 1242 UINT32 dx11_aware = 0; | 1300 UINT32 dx11_aware = 0; |
| 1243 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); | 1301 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); |
| 1244 use_dx11_ = !!dx11_aware; | 1302 use_dx11_ = !!dx11_aware; |
| 1245 } | 1303 } |
| 1304 |
| 1305 use_keyed_mutex_ = |
| 1306 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); |
| 1307 |
| 1246 return true; | 1308 return true; |
| 1247 } | 1309 } |
| 1248 | 1310 |
| 1249 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { | 1311 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { |
| 1250 RETURN_ON_FAILURE(SetDecoderInputMediaType(), | 1312 RETURN_ON_FAILURE(SetDecoderInputMediaType(), |
| 1251 "Failed to set decoder input media type", false); | 1313 "Failed to set decoder input media type", false); |
| 1252 return SetDecoderOutputMediaType(MFVideoFormat_NV12); | 1314 return SetDecoderOutputMediaType(MFVideoFormat_NV12); |
| 1253 } | 1315 } |
| 1254 | 1316 |
| 1255 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { | 1317 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 // was a Reset operation which dropped the output frame. | 1995 // was a Reset operation which dropped the output frame. |
| 1934 DXVAPictureBuffer* picture_buffer = it->second.get(); | 1996 DXVAPictureBuffer* picture_buffer = it->second.get(); |
| 1935 if (picture_buffer->available()) | 1997 if (picture_buffer->available()) |
| 1936 return; | 1998 return; |
| 1937 | 1999 |
| 1938 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), | 2000 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), |
| 1939 "Failed to make context current", PLATFORM_FAILURE,); | 2001 "Failed to make context current", PLATFORM_FAILURE,); |
| 1940 | 2002 |
| 1941 DCHECK(!output_picture_buffers_.empty()); | 2003 DCHECK(!output_picture_buffers_.empty()); |
| 1942 | 2004 |
| 1943 picture_buffer->CopySurfaceComplete(src_surface, | 2005 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); |
| 1944 dest_surface); | 2006 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", |
| 2007 PLATFORM_FAILURE, ); |
| 1945 | 2008 |
| 1946 NotifyPictureReady(picture_buffer->id(), input_buffer_id); | 2009 NotifyPictureReady(picture_buffer->id(), input_buffer_id); |
| 1947 | 2010 |
| 1948 { | 2011 { |
| 1949 base::AutoLock lock(decoder_lock_); | 2012 base::AutoLock lock(decoder_lock_); |
| 1950 if (!pending_output_samples_.empty()) | 2013 if (!pending_output_samples_.empty()) |
| 1951 pending_output_samples_.pop_front(); | 2014 pending_output_samples_.pop_front(); |
| 1952 } | 2015 } |
| 1953 | 2016 |
| 1954 if (pending_flush_) { | 2017 if (pending_flush_) { |
| 1955 decoder_thread_task_runner_->PostTask( | 2018 decoder_thread_task_runner_->PostTask( |
| 1956 FROM_HERE, | 2019 FROM_HERE, |
| 1957 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, | 2020 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, |
| 1958 base::Unretained(this))); | 2021 base::Unretained(this))); |
| 1959 return; | 2022 return; |
| 1960 } | 2023 } |
| 1961 decoder_thread_task_runner_->PostTask( | 2024 decoder_thread_task_runner_->PostTask( |
| 1962 FROM_HERE, | 2025 FROM_HERE, |
| 1963 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2026 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 1964 base::Unretained(this))); | 2027 base::Unretained(this))); |
| 1965 } | 2028 } |
| 1966 | 2029 |
| 1967 void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture, | 2030 void DXVAVideoDecodeAccelerator::CopyTexture( |
| 1968 ID3D11Texture2D* dest_texture, | 2031 ID3D11Texture2D* src_texture, |
| 1969 IMFSample* video_frame, | 2032 ID3D11Texture2D* dest_texture, |
| 1970 int picture_buffer_id, | 2033 base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex, |
| 1971 int input_buffer_id) { | 2034 uint64_t keyed_mutex_value, |
| 2035 IMFSample* video_frame, |
| 2036 int picture_buffer_id, |
| 2037 int input_buffer_id) { |
| 1972 HRESULT hr = E_FAIL; | 2038 HRESULT hr = E_FAIL; |
| 1973 | 2039 |
| 1974 DCHECK(use_dx11_); | 2040 DCHECK(use_dx11_); |
| 1975 | 2041 |
| 1976 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) { | 2042 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) { |
| 1977 // The media foundation H.264 decoder outputs YUV12 textures which we | 2043 // The media foundation H.264 decoder outputs YUV12 textures which we |
| 1978 // cannot copy into ANGLE as they expect ARGB textures. In D3D land | 2044 // cannot copy into ANGLE as they expect ARGB textures. In D3D land |
| 1979 // the StretchRect API in the IDirect3DDevice9Ex interface did the color | 2045 // the StretchRect API in the IDirect3DDevice9Ex interface did the color |
| 1980 // space conversion for us. Sadly in DX11 land the API does not provide | 2046 // space conversion for us. Sadly in DX11 land the API does not provide |
| 1981 // a straightforward way to do this. | 2047 // a straightforward way to do this. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1998 | 2064 |
| 1999 // The input to the video processor is the output sample. | 2065 // The input to the video processor is the output sample. |
| 2000 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; | 2066 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; |
| 2001 { | 2067 { |
| 2002 base::AutoLock lock(decoder_lock_); | 2068 base::AutoLock lock(decoder_lock_); |
| 2003 PendingSampleInfo& sample_info = pending_output_samples_.front(); | 2069 PendingSampleInfo& sample_info = pending_output_samples_.front(); |
| 2004 input_sample_for_conversion = sample_info.output_sample; | 2070 input_sample_for_conversion = sample_info.output_sample; |
| 2005 } | 2071 } |
| 2006 | 2072 |
| 2007 decoder_thread_task_runner_->PostTask( | 2073 decoder_thread_task_runner_->PostTask( |
| 2008 FROM_HERE, | 2074 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopyTexture, |
| 2009 base::Bind(&DXVAVideoDecodeAccelerator::CopyTexture, | 2075 base::Unretained(this), src_texture, dest_texture, |
| 2010 base::Unretained(this), | 2076 dest_keyed_mutex, keyed_mutex_value, |
| 2011 src_texture, | 2077 input_sample_for_conversion.Detach(), |
| 2012 dest_texture, | 2078 picture_buffer_id, input_buffer_id)); |
| 2013 input_sample_for_conversion.Detach(), | |
| 2014 picture_buffer_id, | |
| 2015 input_buffer_id)); | |
| 2016 return; | 2079 return; |
| 2017 } | 2080 } |
| 2018 | 2081 |
| 2019 DCHECK(video_frame); | 2082 DCHECK(video_frame); |
| 2020 | 2083 |
| 2021 base::win::ScopedComPtr<IMFSample> input_sample; | 2084 base::win::ScopedComPtr<IMFSample> input_sample; |
| 2022 input_sample.Attach(video_frame); | 2085 input_sample.Attach(video_frame); |
| 2023 | 2086 |
| 2024 DCHECK(video_format_converter_mft_.get()); | 2087 DCHECK(video_format_converter_mft_.get()); |
| 2025 | 2088 |
| 2089 if (dest_keyed_mutex) { |
| 2090 HRESULT hr = |
| 2091 dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs); |
| 2092 RETURN_AND_NOTIFY_ON_FAILURE( |
| 2093 hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.", |
| 2094 PLATFORM_FAILURE, ); |
| 2095 } |
| 2026 // The video processor MFT requires output samples to be allocated by the | 2096 // The video processor MFT requires output samples to be allocated by the |
| 2027 // caller. We create a sample with a buffer backed with the ID3D11Texture2D | 2097 // caller. We create a sample with a buffer backed with the ID3D11Texture2D |
| 2028 // interface exposed by ANGLE. This works nicely as this ensures that the | 2098 // interface exposed by ANGLE. This works nicely as this ensures that the |
| 2029 // video processor coverts the color space of the output frame and copies | 2099 // video processor coverts the color space of the output frame and copies |
| 2030 // the result into the ANGLE texture. | 2100 // the result into the ANGLE texture. |
| 2031 base::win::ScopedComPtr<IMFSample> output_sample; | 2101 base::win::ScopedComPtr<IMFSample> output_sample; |
| 2032 hr = MFCreateSample(output_sample.Receive()); | 2102 hr = MFCreateSample(output_sample.Receive()); |
| 2033 if (FAILED(hr)) { | 2103 if (FAILED(hr)) { |
| 2034 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, | 2104 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, |
| 2035 "Failed to create output sample.", PLATFORM_FAILURE,); | 2105 "Failed to create output sample.", PLATFORM_FAILURE,); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2070 if (FAILED(hr)) { | 2140 if (FAILED(hr)) { |
| 2071 base::debug::Alias(&hr); | 2141 base::debug::Alias(&hr); |
| 2072 // TODO(ananta) | 2142 // TODO(ananta) |
| 2073 // Remove this CHECK when the change to use DX11 for H/W decoding | 2143 // Remove this CHECK when the change to use DX11 for H/W decoding |
| 2074 // stablizes. | 2144 // stablizes. |
| 2075 CHECK(false); | 2145 CHECK(false); |
| 2076 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, | 2146 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, |
| 2077 "Failed to convert output sample format.", PLATFORM_FAILURE,); | 2147 "Failed to convert output sample format.", PLATFORM_FAILURE,); |
| 2078 } | 2148 } |
| 2079 | 2149 |
| 2080 d3d11_device_context_->Flush(); | 2150 if (dest_keyed_mutex) { |
| 2081 d3d11_device_context_->End(d3d11_query_.get()); | 2151 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); |
| 2152 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", |
| 2153 PLATFORM_FAILURE, ); |
| 2082 | 2154 |
| 2083 decoder_thread_task_runner_->PostDelayedTask( | 2155 main_thread_task_runner_->PostTask( |
| 2084 FROM_HERE, | 2156 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, |
| 2085 base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, | 2157 weak_this_factory_.GetWeakPtr(), nullptr, nullptr, |
| 2086 base::Unretained(this), 0, | 2158 picture_buffer_id, input_buffer_id)); |
| 2087 reinterpret_cast<IDirect3DSurface9*>(NULL), | 2159 } else { |
| 2088 reinterpret_cast<IDirect3DSurface9*>(NULL), | 2160 d3d11_device_context_->Flush(); |
| 2089 picture_buffer_id, input_buffer_id), | 2161 d3d11_device_context_->End(d3d11_query_.get()); |
| 2090 base::TimeDelta::FromMilliseconds( | 2162 |
| 2091 kFlushDecoderSurfaceTimeoutMs)); | 2163 decoder_thread_task_runner_->PostDelayedTask( |
| 2164 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, |
| 2165 base::Unretained(this), 0, |
| 2166 reinterpret_cast<IDirect3DSurface9*>(NULL), |
| 2167 reinterpret_cast<IDirect3DSurface9*>(NULL), |
| 2168 picture_buffer_id, input_buffer_id), |
| 2169 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); |
| 2170 } |
| 2092 } | 2171 } |
| 2093 | 2172 |
| 2094 void DXVAVideoDecodeAccelerator::FlushDecoder( | 2173 void DXVAVideoDecodeAccelerator::FlushDecoder( |
| 2095 int iterations, | 2174 int iterations, |
| 2096 IDirect3DSurface9* src_surface, | 2175 IDirect3DSurface9* src_surface, |
| 2097 IDirect3DSurface9* dest_surface, | 2176 IDirect3DSurface9* dest_surface, |
| 2098 int picture_buffer_id, | 2177 int picture_buffer_id, |
| 2099 int input_buffer_id) { | 2178 int input_buffer_id) { |
| 2100 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 2179 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
| 2101 | 2180 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2298 } | 2377 } |
| 2299 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); | 2378 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); |
| 2300 return true; | 2379 return true; |
| 2301 } | 2380 } |
| 2302 media_type.Release(); | 2381 media_type.Release(); |
| 2303 } | 2382 } |
| 2304 return false; | 2383 return false; |
| 2305 } | 2384 } |
| 2306 | 2385 |
| 2307 } // namespace content | 2386 } // namespace content |
| OLD | NEW |