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

Side by Side Diff: media/gpu/dxva_picture_buffer_win.cc

Issue 2859723002: Copy NV12 picture buffers on demand on the main thread. (Closed)
Patch Set: change comment Created 3 years, 6 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
« no previous file with comments | « media/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "media/gpu/dxva_picture_buffer_win.h" 5 #include "media/gpu/dxva_picture_buffer_win.h"
6 6
7 #include "media/gpu/dxva_video_decode_accelerator_win.h" 7 #include "media/gpu/dxva_video_decode_accelerator_win.h"
8 #include "third_party/angle/include/EGL/egl.h" 8 #include "third_party/angle/include/EGL/egl.h"
9 #include "third_party/angle/include/EGL/eglext.h" 9 #include "third_party/angle/include/EGL/eglext.h"
10 #include "ui/gl/gl_bindings.h" 10 #include "ui/gl/gl_bindings.h"
(...skipping 14 matching lines...) Expand all
25 25
26 // These GLImage subclasses are just used to hold references to the underlying 26 // These GLImage subclasses are just used to hold references to the underlying
27 // image content so it can be destroyed when the textures are. 27 // image content so it can be destroyed when the textures are.
28 class DummyGLImage : public gl::GLImage { 28 class DummyGLImage : public gl::GLImage {
29 public: 29 public:
30 DummyGLImage(const gfx::Size& size) : size_(size) {} 30 DummyGLImage(const gfx::Size& size) : size_(size) {}
31 31
32 // gl::GLImage implementation. 32 // gl::GLImage implementation.
33 gfx::Size GetSize() override { return size_; } 33 gfx::Size GetSize() override { return size_; }
34 unsigned GetInternalFormat() override { return GL_BGRA_EXT; } 34 unsigned GetInternalFormat() override { return GL_BGRA_EXT; }
35 bool BindTexImage(unsigned target) override { return false; } 35 // PbufferPictureBuffer::CopySurfaceComplete does the actual binding, so
36 // this doesn't do anything and always succeeds.
37 bool BindTexImage(unsigned target) override { return true; }
36 void ReleaseTexImage(unsigned target) override {} 38 void ReleaseTexImage(unsigned target) override {}
37 bool CopyTexImage(unsigned target) override { return false; } 39 bool CopyTexImage(unsigned target) override { return false; }
38 bool CopyTexSubImage(unsigned target, 40 bool CopyTexSubImage(unsigned target,
39 const gfx::Point& offset, 41 const gfx::Point& offset,
40 const gfx::Rect& rect) override { 42 const gfx::Rect& rect) override {
41 return false; 43 return false;
42 } 44 }
43 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 45 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
44 int z_order, 46 int z_order,
45 gfx::OverlayTransform transform, 47 gfx::OverlayTransform transform,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // The keyed mutex should always be released before the other thread 97 // The keyed mutex should always be released before the other thread
96 // attempts to acquire it, so AcquireSync should always return immediately. 98 // attempts to acquire it, so AcquireSync should always return immediately.
97 kAcquireSyncWaitMs = 0, 99 kAcquireSyncWaitMs = 0,
98 }; 100 };
99 101
100 // static 102 // static
101 linked_ptr<DXVAPictureBuffer> DXVAPictureBuffer::Create( 103 linked_ptr<DXVAPictureBuffer> DXVAPictureBuffer::Create(
102 const DXVAVideoDecodeAccelerator& decoder, 104 const DXVAVideoDecodeAccelerator& decoder,
103 const PictureBuffer& buffer, 105 const PictureBuffer& buffer,
104 EGLConfig egl_config) { 106 EGLConfig egl_config) {
105 if (decoder.share_nv12_textures_) { 107 switch (decoder.GetPictureBufferMechanism()) {
106 linked_ptr<EGLStreamPictureBuffer> picture_buffer( 108 case DXVAVideoDecodeAccelerator::PictureBufferMechanism::BIND: {
107 new EGLStreamPictureBuffer(buffer)); 109 linked_ptr<EGLStreamPictureBuffer> picture_buffer(
108 if (!picture_buffer->Initialize()) 110 new EGLStreamPictureBuffer(buffer));
109 return linked_ptr<DXVAPictureBuffer>(nullptr); 111 if (!picture_buffer->Initialize())
112 return linked_ptr<DXVAPictureBuffer>(nullptr);
110 113
111 return picture_buffer; 114 return picture_buffer;
115 }
116 case DXVAVideoDecodeAccelerator::PictureBufferMechanism::
117 DELAYED_COPY_TO_NV12: {
118 linked_ptr<EGLStreamDelayedCopyPictureBuffer> picture_buffer(
119 new EGLStreamDelayedCopyPictureBuffer(buffer));
120 if (!picture_buffer->Initialize(decoder))
121 return linked_ptr<DXVAPictureBuffer>(nullptr);
122
123 return picture_buffer;
124 }
125 case DXVAVideoDecodeAccelerator::PictureBufferMechanism::COPY_TO_NV12: {
126 linked_ptr<EGLStreamCopyPictureBuffer> picture_buffer(
127 new EGLStreamCopyPictureBuffer(buffer));
128 if (!picture_buffer->Initialize(decoder))
129 return linked_ptr<DXVAPictureBuffer>(nullptr);
130
131 return picture_buffer;
132 }
133 case DXVAVideoDecodeAccelerator::PictureBufferMechanism::COPY_TO_RGB: {
134 linked_ptr<PbufferPictureBuffer> picture_buffer(
135 new PbufferPictureBuffer(buffer));
136
137 if (!picture_buffer->Initialize(decoder, egl_config))
138 return linked_ptr<DXVAPictureBuffer>(nullptr);
139
140 return picture_buffer;
141 }
112 } 142 }
113 if (decoder.copy_nv12_textures_) { 143 NOTREACHED();
114 linked_ptr<EGLStreamCopyPictureBuffer> picture_buffer( 144 return linked_ptr<DXVAPictureBuffer>(nullptr);
115 new EGLStreamCopyPictureBuffer(buffer));
116 if (!picture_buffer->Initialize(decoder))
117 return linked_ptr<DXVAPictureBuffer>(nullptr);
118
119 return picture_buffer;
120 }
121 linked_ptr<PbufferPictureBuffer> picture_buffer(
122 new PbufferPictureBuffer(buffer));
123
124 if (!picture_buffer->Initialize(decoder, egl_config))
125 return linked_ptr<DXVAPictureBuffer>(nullptr);
126
127 return picture_buffer;
128 } 145 }
129 146
130 DXVAPictureBuffer::~DXVAPictureBuffer() {} 147 DXVAPictureBuffer::~DXVAPictureBuffer() {}
131 148
132 void DXVAPictureBuffer::ResetReuseFence() { 149 void DXVAPictureBuffer::ResetReuseFence() {
133 NOTREACHED(); 150 NOTREACHED();
134 } 151 }
135 152
136 bool DXVAPictureBuffer::CopyOutputSampleDataToPictureBuffer( 153 bool DXVAPictureBuffer::CopyOutputSampleDataToPictureBuffer(
137 DXVAVideoDecodeAccelerator* decoder, 154 DXVAVideoDecodeAccelerator* decoder,
(...skipping 16 matching lines...) Expand all
154 bool DXVAPictureBuffer::CopySurfaceComplete(IDirect3DSurface9* src_surface, 171 bool DXVAPictureBuffer::CopySurfaceComplete(IDirect3DSurface9* src_surface,
155 IDirect3DSurface9* dest_surface) { 172 IDirect3DSurface9* dest_surface) {
156 NOTREACHED(); 173 NOTREACHED();
157 return false; 174 return false;
158 } 175 }
159 176
160 DXVAPictureBuffer::DXVAPictureBuffer(const PictureBuffer& buffer) 177 DXVAPictureBuffer::DXVAPictureBuffer(const PictureBuffer& buffer)
161 : picture_buffer_(buffer) {} 178 : picture_buffer_(buffer) {}
162 179
163 bool DXVAPictureBuffer::BindSampleToTexture( 180 bool DXVAPictureBuffer::BindSampleToTexture(
181 DXVAVideoDecodeAccelerator* decoder,
164 base::win::ScopedComPtr<IMFSample> sample) { 182 base::win::ScopedComPtr<IMFSample> sample) {
165 NOTREACHED(); 183 NOTREACHED();
166 return false; 184 return false;
167 } 185 }
168 186
169 bool PbufferPictureBuffer::Initialize(const DXVAVideoDecodeAccelerator& decoder, 187 bool PbufferPictureBuffer::Initialize(const DXVAVideoDecodeAccelerator& decoder,
170 EGLConfig egl_config) { 188 EGLConfig egl_config) {
171 RETURN_ON_FAILURE(!picture_buffer_.service_texture_ids().empty(), 189 RETURN_ON_FAILURE(!picture_buffer_.service_texture_ids().empty(),
172 "No service texture ids provided", false); 190 "No service texture ids provided", false);
173 191
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 386
369 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
370 glBindTexture(GL_TEXTURE_2D, current_texture); 388 glBindTexture(GL_TEXTURE_2D, current_texture);
371 return true; 389 return true;
372 } 390 }
373 391
374 bool PbufferPictureBuffer::AllowOverlay() const { 392 bool PbufferPictureBuffer::AllowOverlay() const {
375 return false; 393 return false;
376 } 394 }
377 395
396 bool PbufferPictureBuffer::CanBindSamples() const {
397 return false;
398 }
399
378 PbufferPictureBuffer::PbufferPictureBuffer(const PictureBuffer& buffer) 400 PbufferPictureBuffer::PbufferPictureBuffer(const PictureBuffer& buffer)
379 : DXVAPictureBuffer(buffer), 401 : DXVAPictureBuffer(buffer),
380 decoding_surface_(NULL), 402 decoding_surface_(NULL),
381 texture_share_handle_(nullptr), 403 texture_share_handle_(nullptr),
382 keyed_mutex_value_(0), 404 keyed_mutex_value_(0),
383 use_rgb_(true) {} 405 use_rgb_(true) {}
384 406
385 PbufferPictureBuffer::~PbufferPictureBuffer() { 407 PbufferPictureBuffer::~PbufferPictureBuffer() {
386 // decoding_surface_ will be deleted by gl_image_. 408 // decoding_surface_ will be deleted by gl_image_.
387 } 409 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 489 }
468 if (current_d3d_sample_) { 490 if (current_d3d_sample_) {
469 dx11_decoding_texture_.Reset(); 491 dx11_decoding_texture_.Reset();
470 current_d3d_sample_.Reset(); 492 current_d3d_sample_.Reset();
471 } 493 }
472 state_ = UNUSED; 494 state_ = UNUSED;
473 return true; 495 return true;
474 } 496 }
475 497
476 bool EGLStreamPictureBuffer::BindSampleToTexture( 498 bool EGLStreamPictureBuffer::BindSampleToTexture(
499 DXVAVideoDecodeAccelerator* decoder,
477 base::win::ScopedComPtr<IMFSample> sample) { 500 base::win::ScopedComPtr<IMFSample> sample) {
478 DCHECK_EQ(BOUND, state_); 501 DCHECK_EQ(BOUND, state_);
479 state_ = IN_CLIENT; 502 state_ = IN_CLIENT;
480 503
481 current_d3d_sample_ = sample; 504 current_d3d_sample_ = sample;
482 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); 505 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
483 506
484 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 507 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
485 HRESULT hr = 508 HRESULT hr =
486 current_d3d_sample_->GetBufferByIndex(0, output_buffer.GetAddressOf()); 509 current_d3d_sample_->GetBufferByIndex(0, output_buffer.GetAddressOf());
(...skipping 24 matching lines...) Expand all
511 DCHECK(gl_image_dxgi); 534 DCHECK(gl_image_dxgi);
512 535
513 gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource); 536 gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource);
514 return true; 537 return true;
515 } 538 }
516 539
517 bool EGLStreamPictureBuffer::AllowOverlay() const { 540 bool EGLStreamPictureBuffer::AllowOverlay() const {
518 return true; 541 return true;
519 } 542 }
520 543
544 bool EGLStreamPictureBuffer::CanBindSamples() const {
545 return true;
546 }
547
548 EGLStreamDelayedCopyPictureBuffer::EGLStreamDelayedCopyPictureBuffer(
549 const PictureBuffer& buffer)
550 : DXVAPictureBuffer(buffer), stream_(nullptr) {}
551
552 EGLStreamDelayedCopyPictureBuffer::~EGLStreamDelayedCopyPictureBuffer() {
553 // stream_ will be deleted by gl_image_.
554 }
555
556 bool EGLStreamDelayedCopyPictureBuffer::Initialize(
557 const DXVAVideoDecodeAccelerator& decoder) {
558 RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2,
559 "Not enough texture ids provided", false);
560
561 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
562 const EGLint stream_attributes[] = {
563 EGL_CONSUMER_LATENCY_USEC_KHR,
564 0,
565 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR,
566 0,
567 EGL_NONE,
568 };
569 stream_ = eglCreateStreamKHR(egl_display, stream_attributes);
570 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false);
571 gl::ScopedActiveTexture texture0(GL_TEXTURE0);
572 gl::ScopedTextureBinder texture0_binder(
573 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]);
574 gl::ScopedActiveTexture texture1(GL_TEXTURE1);
575 gl::ScopedTextureBinder texture1_binder(
576 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]);
577
578 EGLAttrib consumer_attributes[] = {
579 EGL_COLOR_BUFFER_TYPE,
580 EGL_YUV_BUFFER_EXT,
581 EGL_YUV_NUMBER_OF_PLANES_EXT,
582 2,
583 EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
584 0,
585 EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
586 1,
587 EGL_NONE,
588 };
589 EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
590 egl_display, stream_, consumer_attributes);
591 RETURN_ON_FAILURE(result, "Could not set stream consumer", false);
592
593 EGLAttrib producer_attributes[] = {
594 EGL_NONE,
595 };
596
597 result = eglCreateStreamProducerD3DTextureNV12ANGLE(egl_display, stream_,
598 producer_attributes);
599 RETURN_ON_FAILURE(result, "Could not create stream producer", false);
600 scoped_refptr<gl::CopyingGLImageDXGI> copying_image_ =
601 make_scoped_refptr(new gl::CopyingGLImageDXGI(
602 base::win::ScopedComPtr<ID3D11Device>(decoder.D3D11Device()), size(),
603 stream_));
604 gl_image_ = copying_image_;
605 return copying_image_->Initialize();
606 }
607
608 bool EGLStreamDelayedCopyPictureBuffer::ReusePictureBuffer() {
609 DCHECK_NE(UNUSED, state_);
610
611 static_cast<gl::CopyingGLImageDXGI*>(gl_image_.get())->UnbindFromTexture();
612 if (current_d3d_sample_) {
613 dx11_decoding_texture_.Reset();
614 current_d3d_sample_.Reset();
615 }
616 state_ = UNUSED;
617 return true;
618 }
619
620 bool EGLStreamDelayedCopyPictureBuffer::BindSampleToTexture(
621 DXVAVideoDecodeAccelerator* decoder,
622 base::win::ScopedComPtr<IMFSample> sample) {
623 DCHECK_EQ(BOUND, state_);
624 state_ = IN_CLIENT;
625
626 current_d3d_sample_ = sample;
627
628 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
629 HRESULT hr =
630 current_d3d_sample_->GetBufferByIndex(0, output_buffer.GetAddressOf());
631 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
632
633 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
634 hr = output_buffer.CopyTo(dxgi_buffer.GetAddressOf());
635 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample",
636 false);
637 hr = dxgi_buffer->GetResource(
638 IID_PPV_ARGS(dx11_decoding_texture_.GetAddressOf()));
639 RETURN_ON_HR_FAILURE(hr, "Failed to get texture from output sample", false);
640 UINT subresource;
641 dxgi_buffer->GetSubresourceIndex(&subresource);
642 if (!decoder->InitializeID3D11VideoProcessor(size().width(), size().height(),
643 color_space_))
644 return false;
645
646 DCHECK(decoder->d3d11_processor_);
647 DCHECK(decoder->enumerator_);
648
649 gl::GLImageDXGI* gl_image_dxgi =
650 gl::GLImageDXGI::FromGLImage(gl_image_.get());
651 DCHECK(gl_image_dxgi);
652
653 gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource);
654 return static_cast<gl::CopyingGLImageDXGI*>(gl_image_dxgi)
655 ->InitializeVideoProcessor(decoder->d3d11_processor_,
656 decoder->enumerator_);
657 }
658
659 bool EGLStreamDelayedCopyPictureBuffer::AllowOverlay() const {
660 return true;
661 }
662
663 bool EGLStreamDelayedCopyPictureBuffer::CanBindSamples() const {
664 return true;
665 }
666
521 EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer( 667 EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer(
522 const PictureBuffer& buffer) 668 const PictureBuffer& buffer)
523 : DXVAPictureBuffer(buffer), stream_(nullptr) {} 669 : DXVAPictureBuffer(buffer), stream_(nullptr) {}
524 670
525 EGLStreamCopyPictureBuffer::~EGLStreamCopyPictureBuffer() { 671 EGLStreamCopyPictureBuffer::~EGLStreamCopyPictureBuffer() {
526 // stream_ will be deleted by gl_image_. 672 // stream_ will be deleted by gl_image_.
527 } 673 }
528 674
529 bool EGLStreamCopyPictureBuffer::Initialize( 675 bool EGLStreamCopyPictureBuffer::Initialize(
530 const DXVAVideoDecodeAccelerator& decoder) { 676 const DXVAVideoDecodeAccelerator& decoder) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_); 824 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_);
679 RETURN_ON_FAILURE(result, "Could not release stream", false); 825 RETURN_ON_FAILURE(result, "Could not release stream", false);
680 } 826 }
681 return true; 827 return true;
682 } 828 }
683 829
684 bool EGLStreamCopyPictureBuffer::AllowOverlay() const { 830 bool EGLStreamCopyPictureBuffer::AllowOverlay() const {
685 return true; 831 return true;
686 } 832 }
687 833
834 bool EGLStreamCopyPictureBuffer::CanBindSamples() const {
835 return false;
836 }
837
688 } // namespace media 838 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698