OLD | NEW |
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 ID3D11Texture2D* dx11_texture, | 67 ID3D11Texture2D* dx11_texture, |
68 int input_buffer_id) { | 68 int input_buffer_id) { |
69 NOTREACHED(); | 69 NOTREACHED(); |
70 return false; | 70 return false; |
71 } | 71 } |
72 | 72 |
73 bool DXVAPictureBuffer::waiting_to_reuse() const { | 73 bool DXVAPictureBuffer::waiting_to_reuse() const { |
74 return false; | 74 return false; |
75 } | 75 } |
76 | 76 |
77 gfx::GLFence* DXVAPictureBuffer::reuse_fence() { | 77 gl::GLFence* DXVAPictureBuffer::reuse_fence() { |
78 return nullptr; | 78 return nullptr; |
79 } | 79 } |
80 | 80 |
81 bool DXVAPictureBuffer::CopySurfaceComplete(IDirect3DSurface9* src_surface, | 81 bool DXVAPictureBuffer::CopySurfaceComplete(IDirect3DSurface9* src_surface, |
82 IDirect3DSurface9* dest_surface) { | 82 IDirect3DSurface9* dest_surface) { |
83 NOTREACHED(); | 83 NOTREACHED(); |
84 return false; | 84 return false; |
85 } | 85 } |
86 | 86 |
87 DXVAPictureBuffer::DXVAPictureBuffer(const media::PictureBuffer& buffer) | 87 DXVAPictureBuffer::DXVAPictureBuffer(const media::PictureBuffer& buffer) |
88 : available_(true), picture_buffer_(buffer) {} | 88 : available_(true), picture_buffer_(buffer) {} |
89 | 89 |
90 bool DXVAPictureBuffer::BindSampleToTexture( | 90 bool DXVAPictureBuffer::BindSampleToTexture( |
91 base::win::ScopedComPtr<IMFSample> sample) { | 91 base::win::ScopedComPtr<IMFSample> sample) { |
92 NOTREACHED(); | 92 NOTREACHED(); |
93 return false; | 93 return false; |
94 } | 94 } |
95 | 95 |
96 bool PbufferPictureBuffer::Initialize(const DXVAVideoDecodeAccelerator& decoder, | 96 bool PbufferPictureBuffer::Initialize(const DXVAVideoDecodeAccelerator& decoder, |
97 EGLConfig egl_config) { | 97 EGLConfig egl_config) { |
98 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 98 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
99 EGLint use_rgb = 1; | 99 EGLint use_rgb = 1; |
100 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, | 100 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, |
101 &use_rgb); | 101 &use_rgb); |
102 | 102 |
103 if (!InitializeTexture(decoder, !!use_rgb)) | 103 if (!InitializeTexture(decoder, !!use_rgb)) |
104 return false; | 104 return false; |
105 | 105 |
106 EGLint attrib_list[] = {EGL_WIDTH, | 106 EGLint attrib_list[] = {EGL_WIDTH, |
107 size().width(), | 107 size().width(), |
108 EGL_HEIGHT, | 108 EGL_HEIGHT, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 D3DPOOL_DEFAULT, decoding_texture_.Receive(), &texture_share_handle_); | 174 D3DPOOL_DEFAULT, decoding_texture_.Receive(), &texture_share_handle_); |
175 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false); | 175 RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false); |
176 RETURN_ON_FAILURE(texture_share_handle_, "Failed to query shared handle", | 176 RETURN_ON_FAILURE(texture_share_handle_, "Failed to query shared handle", |
177 false); | 177 false); |
178 } | 178 } |
179 return true; | 179 return true; |
180 } | 180 } |
181 | 181 |
182 void PbufferPictureBuffer::ResetReuseFence() { | 182 void PbufferPictureBuffer::ResetReuseFence() { |
183 if (!reuse_fence_ || !reuse_fence_->ResetSupported()) | 183 if (!reuse_fence_ || !reuse_fence_->ResetSupported()) |
184 reuse_fence_.reset(gfx::GLFence::Create()); | 184 reuse_fence_.reset(gl::GLFence::Create()); |
185 else | 185 else |
186 reuse_fence_->ResetState(); | 186 reuse_fence_->ResetState(); |
187 waiting_to_reuse_ = true; | 187 waiting_to_reuse_ = true; |
188 } | 188 } |
189 | 189 |
190 bool PbufferPictureBuffer::CopyOutputSampleDataToPictureBuffer( | 190 bool PbufferPictureBuffer::CopyOutputSampleDataToPictureBuffer( |
191 DXVAVideoDecodeAccelerator* decoder, | 191 DXVAVideoDecodeAccelerator* decoder, |
192 IDirect3DSurface9* dest_surface, | 192 IDirect3DSurface9* dest_surface, |
193 ID3D11Texture2D* dx11_texture, | 193 ID3D11Texture2D* dx11_texture, |
194 int input_buffer_id) { | 194 int input_buffer_id) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 237 |
238 decoder->CopySurface(decoder_surface_.get(), target_surface_.get(), id(), | 238 decoder->CopySurface(decoder_surface_.get(), target_surface_.get(), id(), |
239 input_buffer_id); | 239 input_buffer_id); |
240 return true; | 240 return true; |
241 } | 241 } |
242 | 242 |
243 bool PbufferPictureBuffer::waiting_to_reuse() const { | 243 bool PbufferPictureBuffer::waiting_to_reuse() const { |
244 return waiting_to_reuse_; | 244 return waiting_to_reuse_; |
245 } | 245 } |
246 | 246 |
247 gfx::GLFence* PbufferPictureBuffer::reuse_fence() { | 247 gl::GLFence* PbufferPictureBuffer::reuse_fence() { |
248 return reuse_fence_.get(); | 248 return reuse_fence_.get(); |
249 } | 249 } |
250 | 250 |
251 bool PbufferPictureBuffer::CopySurfaceComplete( | 251 bool PbufferPictureBuffer::CopySurfaceComplete( |
252 IDirect3DSurface9* src_surface, | 252 IDirect3DSurface9* src_surface, |
253 IDirect3DSurface9* dest_surface) { | 253 IDirect3DSurface9* dest_surface) { |
254 DCHECK(!available()); | 254 DCHECK(!available()); |
255 | 255 |
256 GLint current_texture = 0; | 256 GLint current_texture = 0; |
257 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); | 257 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
(...skipping 11 matching lines...) Expand all Loading... |
269 DCHECK(decoder_dx11_texture_.get()); | 269 DCHECK(decoder_dx11_texture_.get()); |
270 decoder_dx11_texture_.Release(); | 270 decoder_dx11_texture_.Release(); |
271 } | 271 } |
272 if (egl_keyed_mutex_) { | 272 if (egl_keyed_mutex_) { |
273 keyed_mutex_value_++; | 273 keyed_mutex_value_++; |
274 HRESULT result = | 274 HRESULT result = |
275 egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs); | 275 egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs); |
276 RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false); | 276 RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false); |
277 } | 277 } |
278 | 278 |
279 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 279 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
280 eglBindTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); | 280 eglBindTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); |
281 | 281 |
282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
283 glBindTexture(GL_TEXTURE_2D, current_texture); | 283 glBindTexture(GL_TEXTURE_2D, current_texture); |
284 return true; | 284 return true; |
285 } | 285 } |
286 | 286 |
287 PbufferPictureBuffer::PbufferPictureBuffer(const media::PictureBuffer& buffer) | 287 PbufferPictureBuffer::PbufferPictureBuffer(const media::PictureBuffer& buffer) |
288 : DXVAPictureBuffer(buffer), | 288 : DXVAPictureBuffer(buffer), |
289 waiting_to_reuse_(false), | 289 waiting_to_reuse_(false), |
290 decoding_surface_(NULL), | 290 decoding_surface_(NULL), |
291 texture_share_handle_(nullptr), | 291 texture_share_handle_(nullptr), |
292 keyed_mutex_value_(0), | 292 keyed_mutex_value_(0), |
293 use_rgb_(true) {} | 293 use_rgb_(true) {} |
294 | 294 |
295 PbufferPictureBuffer::~PbufferPictureBuffer() { | 295 PbufferPictureBuffer::~PbufferPictureBuffer() { |
296 if (decoding_surface_) { | 296 if (decoding_surface_) { |
297 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 297 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
298 | 298 |
299 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); | 299 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); |
300 | 300 |
301 eglDestroySurface(egl_display, decoding_surface_); | 301 eglDestroySurface(egl_display, decoding_surface_); |
302 decoding_surface_ = NULL; | 302 decoding_surface_ = NULL; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 bool PbufferPictureBuffer::ReusePictureBuffer() { | 306 bool PbufferPictureBuffer::ReusePictureBuffer() { |
307 DCHECK(decoding_surface_); | 307 DCHECK(decoding_surface_); |
308 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 308 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
309 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); | 309 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); |
310 | 310 |
311 decoder_surface_.Release(); | 311 decoder_surface_.Release(); |
312 target_surface_.Release(); | 312 target_surface_.Release(); |
313 decoder_dx11_texture_.Release(); | 313 decoder_dx11_texture_.Release(); |
314 waiting_to_reuse_ = false; | 314 waiting_to_reuse_ = false; |
315 set_available(true); | 315 set_available(true); |
316 if (egl_keyed_mutex_) { | 316 if (egl_keyed_mutex_) { |
317 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_); | 317 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_); |
318 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false); | 318 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false); |
319 } | 319 } |
320 return true; | 320 return true; |
321 } | 321 } |
322 | 322 |
323 EGLStreamPictureBuffer::EGLStreamPictureBuffer( | 323 EGLStreamPictureBuffer::EGLStreamPictureBuffer( |
324 const media::PictureBuffer& buffer) | 324 const media::PictureBuffer& buffer) |
325 : DXVAPictureBuffer(buffer), stream_(nullptr) {} | 325 : DXVAPictureBuffer(buffer), stream_(nullptr) {} |
326 | 326 |
327 EGLStreamPictureBuffer::~EGLStreamPictureBuffer() { | 327 EGLStreamPictureBuffer::~EGLStreamPictureBuffer() { |
328 if (stream_) { | 328 if (stream_) { |
329 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 329 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
330 eglDestroyStreamKHR(egl_display, stream_); | 330 eglDestroyStreamKHR(egl_display, stream_); |
331 stream_ = nullptr; | 331 stream_ = nullptr; |
332 } | 332 } |
333 } | 333 } |
334 | 334 |
335 bool EGLStreamPictureBuffer::Initialize() { | 335 bool EGLStreamPictureBuffer::Initialize() { |
336 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 336 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
337 const EGLint stream_attributes[] = { | 337 const EGLint stream_attributes[] = { |
338 EGL_CONSUMER_LATENCY_USEC_KHR, | 338 EGL_CONSUMER_LATENCY_USEC_KHR, |
339 0, | 339 0, |
340 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, | 340 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, |
341 0, | 341 0, |
342 EGL_NONE, | 342 EGL_NONE, |
343 }; | 343 }; |
344 stream_ = eglCreateStreamKHR(egl_display, stream_attributes); | 344 stream_ = eglCreateStreamKHR(egl_display, stream_attributes); |
345 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false); | 345 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false); |
346 gfx::ScopedActiveTexture texture0(GL_TEXTURE0); | 346 gl::ScopedActiveTexture texture0(GL_TEXTURE0); |
347 gfx::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES, | 347 gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES, |
348 picture_buffer_.texture_ids()[0]); | 348 picture_buffer_.texture_ids()[0]); |
349 gfx::ScopedActiveTexture texture1(GL_TEXTURE1); | 349 gl::ScopedActiveTexture texture1(GL_TEXTURE1); |
350 gfx::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES, | 350 gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES, |
351 picture_buffer_.texture_ids()[1]); | 351 picture_buffer_.texture_ids()[1]); |
352 | 352 |
353 EGLAttrib consumer_attributes[] = { | 353 EGLAttrib consumer_attributes[] = { |
354 EGL_COLOR_BUFFER_TYPE, | 354 EGL_COLOR_BUFFER_TYPE, |
355 EGL_YUV_BUFFER_EXT, | 355 EGL_YUV_BUFFER_EXT, |
356 EGL_YUV_NUMBER_OF_PLANES_EXT, | 356 EGL_YUV_NUMBER_OF_PLANES_EXT, |
357 2, | 357 2, |
358 EGL_YUV_PLANE0_TEXTURE_UNIT_NV, | 358 EGL_YUV_PLANE0_TEXTURE_UNIT_NV, |
359 0, | 359 0, |
360 EGL_YUV_PLANE1_TEXTURE_UNIT_NV, | 360 EGL_YUV_PLANE1_TEXTURE_UNIT_NV, |
361 1, | 361 1, |
362 EGL_NONE, | 362 EGL_NONE, |
363 }; | 363 }; |
364 EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV( | 364 EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV( |
365 egl_display, stream_, consumer_attributes); | 365 egl_display, stream_, consumer_attributes); |
366 RETURN_ON_FAILURE(result, "Could not set stream consumer", false); | 366 RETURN_ON_FAILURE(result, "Could not set stream consumer", false); |
367 | 367 |
368 EGLAttrib producer_attributes[] = { | 368 EGLAttrib producer_attributes[] = { |
369 EGL_NONE, | 369 EGL_NONE, |
370 }; | 370 }; |
371 | 371 |
372 result = eglCreateStreamProducerD3DTextureNV12ANGLE(egl_display, stream_, | 372 result = eglCreateStreamProducerD3DTextureNV12ANGLE(egl_display, stream_, |
373 producer_attributes); | 373 producer_attributes); |
374 RETURN_ON_FAILURE(result, "Could not create stream producer", false); | 374 RETURN_ON_FAILURE(result, "Could not create stream producer", false); |
375 return true; | 375 return true; |
376 } | 376 } |
377 | 377 |
378 bool EGLStreamPictureBuffer::ReusePictureBuffer() { | 378 bool EGLStreamPictureBuffer::ReusePictureBuffer() { |
379 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 379 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
380 | 380 |
381 if (stream_) { | 381 if (stream_) { |
382 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_); | 382 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_); |
383 RETURN_ON_FAILURE(result, "Could not release stream", false); | 383 RETURN_ON_FAILURE(result, "Could not release stream", false); |
384 } | 384 } |
385 if (current_d3d_sample_) { | 385 if (current_d3d_sample_) { |
386 dx11_decoding_texture_.Release(); | 386 dx11_decoding_texture_.Release(); |
387 current_d3d_sample_.Release(); | 387 current_d3d_sample_.Release(); |
388 } | 388 } |
389 set_available(true); | 389 set_available(true); |
390 return true; | 390 return true; |
391 } | 391 } |
392 | 392 |
393 bool EGLStreamPictureBuffer::BindSampleToTexture( | 393 bool EGLStreamPictureBuffer::BindSampleToTexture( |
394 base::win::ScopedComPtr<IMFSample> sample) { | 394 base::win::ScopedComPtr<IMFSample> sample) { |
395 DCHECK(!available()); | 395 DCHECK(!available()); |
396 | 396 |
397 current_d3d_sample_ = sample; | 397 current_d3d_sample_ = sample; |
398 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 398 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
399 | 399 |
400 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 400 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
401 HRESULT hr = | 401 HRESULT hr = |
402 current_d3d_sample_->GetBufferByIndex(0, output_buffer.Receive()); | 402 current_d3d_sample_->GetBufferByIndex(0, output_buffer.Receive()); |
403 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); | 403 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); |
404 | 404 |
405 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer; | 405 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer; |
406 hr = dxgi_buffer.QueryFrom(output_buffer.get()); | 406 hr = dxgi_buffer.QueryFrom(output_buffer.get()); |
407 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", | 407 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", |
408 false); | 408 false); |
409 hr = dxgi_buffer->GetResource(IID_PPV_ARGS(dx11_decoding_texture_.Receive())); | 409 hr = dxgi_buffer->GetResource(IID_PPV_ARGS(dx11_decoding_texture_.Receive())); |
410 RETURN_ON_HR_FAILURE(hr, "Failed to get texture from output sample", false); | 410 RETURN_ON_HR_FAILURE(hr, "Failed to get texture from output sample", false); |
411 UINT subresource; | 411 UINT subresource; |
412 dxgi_buffer->GetSubresourceIndex(&subresource); | 412 dxgi_buffer->GetSubresourceIndex(&subresource); |
413 | 413 |
414 EGLAttrib frame_attributes[] = { | 414 EGLAttrib frame_attributes[] = { |
415 EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, subresource, EGL_NONE, | 415 EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, subresource, EGL_NONE, |
416 }; | 416 }; |
417 | 417 |
418 EGLBoolean result = eglStreamPostD3DTextureNV12ANGLE( | 418 EGLBoolean result = eglStreamPostD3DTextureNV12ANGLE( |
419 egl_display, stream_, static_cast<void*>(dx11_decoding_texture_.get()), | 419 egl_display, stream_, static_cast<void*>(dx11_decoding_texture_.get()), |
420 frame_attributes); | 420 frame_attributes); |
421 RETURN_ON_FAILURE(result, "Could not post texture", false); | 421 RETURN_ON_FAILURE(result, "Could not post texture", false); |
422 result = eglStreamConsumerAcquireKHR(egl_display, stream_); | 422 result = eglStreamConsumerAcquireKHR(egl_display, stream_); |
423 RETURN_ON_FAILURE(result, "Could not post acquire stream", false); | 423 RETURN_ON_FAILURE(result, "Could not post acquire stream", false); |
424 return true; | 424 return true; |
425 } | 425 } |
426 | 426 |
427 } // namespace media | 427 } // namespace media |
OLD | NEW |