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 // The bulk of this file is support code; sorry about that. Here's an overview | 5 // The bulk of this file is support code; sorry about that. Here's an overview |
6 // to hopefully help readers of this code: | 6 // to hopefully help readers of this code: |
7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or | 7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or |
8 // Win/EGL. | 8 // Win/EGL. |
9 // - ClientState is an enum for the state of the decode client used by the test. | 9 // - ClientState is an enum for the state of the decode client used by the test. |
10 // - ClientStateNotification is a barrier abstraction that allows the test code | 10 // - ClientStateNotification is a barrier abstraction that allows the test code |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 #endif | 68 #endif |
69 #if defined(ARCH_CPU_X86_FAMILY) | 69 #if defined(ARCH_CPU_X86_FAMILY) |
70 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" | 70 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" |
71 #include "content/common/gpu/media/vaapi_wrapper.h" | 71 #include "content/common/gpu/media/vaapi_wrapper.h" |
72 #endif // defined(ARCH_CPU_X86_FAMILY) | 72 #endif // defined(ARCH_CPU_X86_FAMILY) |
73 #else | 73 #else |
74 #error The VideoAccelerator tests are not supported on this platform. | 74 #error The VideoAccelerator tests are not supported on this platform. |
75 #endif // OS_WIN | 75 #endif // OS_WIN |
76 | 76 |
77 #if defined(USE_OZONE) | 77 #if defined(USE_OZONE) |
| 78 #include "ui/ozone/public/native_pixmap.h" |
78 #include "ui/ozone/public/ozone_gpu_test_helper.h" | 79 #include "ui/ozone/public/ozone_gpu_test_helper.h" |
79 #include "ui/ozone/public/ozone_platform.h" | 80 #include "ui/ozone/public/ozone_platform.h" |
| 81 #include "ui/ozone/public/surface_factory_ozone.h" |
80 #endif // defined(USE_OZONE) | 82 #endif // defined(USE_OZONE) |
81 | 83 |
82 using media::VideoDecodeAccelerator; | 84 using media::VideoDecodeAccelerator; |
83 | 85 |
84 namespace content { | 86 namespace content { |
85 namespace { | 87 namespace { |
86 | 88 |
87 using base::MakeTuple; | 89 using base::MakeTuple; |
88 | 90 |
89 // Values optionally filled in from flags; see main() below. | 91 // Values optionally filled in from flags; see main() below. |
(...skipping 29 matching lines...) Expand all Loading... |
119 int g_rendering_warm_up = 0; | 121 int g_rendering_warm_up = 0; |
120 | 122 |
121 // The value is set by the switch "--num_play_throughs". The video will play | 123 // The value is set by the switch "--num_play_throughs". The video will play |
122 // the specified number of times. In different test cases, we have different | 124 // the specified number of times. In different test cases, we have different |
123 // values for |num_play_throughs|. This setting will override the value. A | 125 // values for |num_play_throughs|. This setting will override the value. A |
124 // special value "0" means no override. | 126 // special value "0" means no override. |
125 int g_num_play_throughs = 0; | 127 int g_num_play_throughs = 0; |
126 // Fake decode | 128 // Fake decode |
127 int g_fake_decoder = 0; | 129 int g_fake_decoder = 0; |
128 | 130 |
| 131 // Test buffer import into VDA, providing buffers allocated by us, instead of |
| 132 // requesting the VDA itself to allocate buffers. |
| 133 bool g_test_import = false; |
| 134 |
129 // Environment to store rendering thread. | 135 // Environment to store rendering thread. |
130 class VideoDecodeAcceleratorTestEnvironment; | 136 class VideoDecodeAcceleratorTestEnvironment; |
131 VideoDecodeAcceleratorTestEnvironment* g_env; | 137 VideoDecodeAcceleratorTestEnvironment* g_env; |
132 | 138 |
133 // Magic constants for differentiating the reasons for NotifyResetDone being | 139 // Magic constants for differentiating the reasons for NotifyResetDone being |
134 // called. | 140 // called. |
135 enum ResetPoint { | 141 enum ResetPoint { |
136 // Reset() just after calling Decode() with a fragment containing config info. | 142 // Reset() just after calling Decode() with a fragment containing config info. |
137 RESET_AFTER_FIRST_CONFIG_INFO = -4, | 143 RESET_AFTER_FIRST_CONFIG_INFO = -4, |
138 START_OF_STREAM_RESET = -3, | 144 START_OF_STREAM_RESET = -3, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 #if defined(USE_OZONE) | 272 #if defined(USE_OZONE) |
267 scoped_ptr<ui::OzoneGpuTestHelper> gpu_helper_; | 273 scoped_ptr<ui::OzoneGpuTestHelper> gpu_helper_; |
268 #endif | 274 #endif |
269 | 275 |
270 DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorTestEnvironment); | 276 DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorTestEnvironment); |
271 }; | 277 }; |
272 | 278 |
273 // A helper class used to manage the lifetime of a Texture. | 279 // A helper class used to manage the lifetime of a Texture. |
274 class TextureRef : public base::RefCounted<TextureRef> { | 280 class TextureRef : public base::RefCounted<TextureRef> { |
275 public: | 281 public: |
276 TextureRef(uint32_t texture_id, const base::Closure& no_longer_needed_cb) | 282 TextureRef(uint32_t texture_id, |
277 : texture_id_(texture_id), no_longer_needed_cb_(no_longer_needed_cb) {} | 283 const scoped_refptr<ui::NativePixmap>& pixmap, |
| 284 const base::Closure& no_longer_needed_cb) |
| 285 : texture_id_(texture_id), |
| 286 pixmap_(pixmap), |
| 287 no_longer_needed_cb_(no_longer_needed_cb) {} |
278 | 288 |
279 int32_t texture_id() const { return texture_id_; } | 289 int32_t texture_id() const { return texture_id_; } |
| 290 scoped_refptr<ui::NativePixmap> pixmap() { return pixmap_; } |
280 | 291 |
281 private: | 292 private: |
282 friend class base::RefCounted<TextureRef>; | 293 friend class base::RefCounted<TextureRef>; |
283 ~TextureRef(); | 294 ~TextureRef(); |
284 | 295 |
285 uint32_t texture_id_; | 296 uint32_t texture_id_; |
| 297 scoped_refptr<ui::NativePixmap> pixmap_; |
286 base::Closure no_longer_needed_cb_; | 298 base::Closure no_longer_needed_cb_; |
287 }; | 299 }; |
288 | 300 |
289 TextureRef::~TextureRef() { | 301 TextureRef::~TextureRef() { |
290 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 302 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
291 } | 303 } |
292 | 304 |
293 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by | 305 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by |
294 // the TESTs below. | 306 // the TESTs below. |
295 class GLRenderingVDAClient | 307 class GLRenderingVDAClient |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 } else { | 535 } else { |
524 if (!vda_factory_) { | 536 if (!vda_factory_) { |
525 vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create( | 537 vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create( |
526 base::Bind(&RenderingHelper::GetGLContext, | 538 base::Bind(&RenderingHelper::GetGLContext, |
527 base::Unretained(rendering_helper_)), | 539 base::Unretained(rendering_helper_)), |
528 base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage)); | 540 base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage)); |
529 LOG_ASSERT(vda_factory_); | 541 LOG_ASSERT(vda_factory_); |
530 } | 542 } |
531 | 543 |
532 VideoDecodeAccelerator::Config config(profile_); | 544 VideoDecodeAccelerator::Config config(profile_); |
| 545 if (g_test_import) { |
| 546 config.output_mode = |
| 547 media::VideoDecodeAccelerator::Config::OutputMode::IMPORT; |
| 548 } |
533 gpu::GpuPreferences gpu_preferences; | 549 gpu::GpuPreferences gpu_preferences; |
534 #if defined(OS_WIN) | 550 #if defined(OS_WIN) |
535 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 551 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
536 gpu_preferences.enable_accelerated_vpx_decode = | 552 gpu_preferences.enable_accelerated_vpx_decode = |
537 cmd_line->HasSwitch(switches::kEnableAcceleratedVpxDecode); | 553 cmd_line->HasSwitch(switches::kEnableAcceleratedVpxDecode); |
538 #endif | 554 #endif |
539 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences); | 555 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences); |
540 } | 556 } |
541 | 557 |
542 LOG_ASSERT(decoder_) << "Failed creating a VDA"; | 558 LOG_ASSERT(decoder_) << "Failed creating a VDA"; |
543 | 559 |
544 decoder_->TryToSetupDecodeOnSeparateThread( | 560 decoder_->TryToSetupDecodeOnSeparateThread( |
545 weak_this_, base::ThreadTaskRunnerHandle::Get()); | 561 weak_this_, base::ThreadTaskRunnerHandle::Get()); |
546 | 562 |
547 SetState(CS_DECODER_SET); | 563 SetState(CS_DECODER_SET); |
548 FinishInitialization(); | 564 FinishInitialization(); |
549 } | 565 } |
550 | 566 |
| 567 namespace { |
| 568 gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( |
| 569 media::VideoPixelFormat pixel_format) { |
| 570 switch (pixel_format) { |
| 571 case media::VideoPixelFormat::PIXEL_FORMAT_ARGB: |
| 572 return gfx::BufferFormat::BGRA_8888; |
| 573 case media::VideoPixelFormat::PIXEL_FORMAT_XRGB: |
| 574 return gfx::BufferFormat::BGRX_8888; |
| 575 case media::VideoPixelFormat::PIXEL_FORMAT_NV12: |
| 576 return gfx::BufferFormat::YUV_420_BIPLANAR; |
| 577 default: |
| 578 LOG_ASSERT(false) << "Unknown VideoPixelFormat"; |
| 579 return gfx::BufferFormat::BGRX_8888; |
| 580 } |
| 581 } |
| 582 } |
| 583 |
551 void GLRenderingVDAClient::ProvidePictureBuffers( | 584 void GLRenderingVDAClient::ProvidePictureBuffers( |
552 uint32_t requested_num_of_buffers, | 585 uint32_t requested_num_of_buffers, |
553 const gfx::Size& dimensions, | 586 const gfx::Size& dimensions, |
554 uint32_t texture_target) { | 587 uint32_t texture_target) { |
555 if (decoder_deleted()) | 588 if (decoder_deleted()) |
556 return; | 589 return; |
557 std::vector<media::PictureBuffer> buffers; | 590 std::vector<media::PictureBuffer> buffers; |
558 | 591 |
559 requested_num_of_buffers += kExtraPictureBuffers; | 592 requested_num_of_buffers += kExtraPictureBuffers; |
560 | 593 |
561 texture_target_ = texture_target; | 594 texture_target_ = texture_target; |
562 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { | 595 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { |
563 uint32_t texture_id; | 596 uint32_t texture_id; |
564 base::WaitableEvent done(false, false); | 597 base::WaitableEvent done(false, false); |
565 rendering_helper_->CreateTexture( | 598 rendering_helper_->CreateTexture( |
566 texture_target_, &texture_id, dimensions, &done); | 599 texture_target_, &texture_id, dimensions, &done); |
567 done.Wait(); | 600 done.Wait(); |
568 | 601 |
| 602 scoped_refptr<ui::NativePixmap> pixmap; |
| 603 if (g_test_import) { |
| 604 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); |
| 605 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); |
| 606 gfx::BufferFormat buffer_format = |
| 607 VideoPixelFormatToGfxBufferFormat(decoder_->GetOutputFormat()); |
| 608 pixmap = |
| 609 factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, dimensions, |
| 610 buffer_format, gfx::BufferUsage::SCANOUT); |
| 611 LOG_ASSERT(pixmap); |
| 612 } |
| 613 |
569 int32_t picture_buffer_id = next_picture_buffer_id_++; | 614 int32_t picture_buffer_id = next_picture_buffer_id_++; |
570 LOG_ASSERT(active_textures_ | 615 LOG_ASSERT( |
571 .insert(std::make_pair( | 616 active_textures_ |
572 picture_buffer_id, | 617 .insert(std::make_pair( |
573 new TextureRef(texture_id, | 618 picture_buffer_id, |
574 base::Bind(&RenderingHelper::DeleteTexture, | 619 new TextureRef(texture_id, pixmap, |
575 base::Unretained(rendering_helper_), | 620 base::Bind(&RenderingHelper::DeleteTexture, |
576 texture_id)))) | 621 base::Unretained(rendering_helper_), |
577 .second); | 622 texture_id)))) |
| 623 .second); |
578 | 624 |
579 buffers.push_back( | 625 buffers.push_back( |
580 media::PictureBuffer(picture_buffer_id, dimensions, texture_id)); | 626 media::PictureBuffer(picture_buffer_id, dimensions, texture_id)); |
581 } | 627 } |
582 decoder_->AssignPictureBuffers(buffers); | 628 decoder_->AssignPictureBuffers(buffers); |
| 629 |
| 630 if (g_test_import) { |
| 631 for (const auto& buffer : buffers) { |
| 632 TextureRefMap::iterator texture_it = active_textures_.find(buffer.id()); |
| 633 ASSERT_NE(active_textures_.end(), texture_it); |
| 634 |
| 635 scoped_refptr<ui::NativePixmap> pixmap = texture_it->second->pixmap(); |
| 636 int duped_fd = HANDLE_EINTR(dup(pixmap->GetDmaBufFd())); |
| 637 ASSERT_NE(duped_fd, -1); |
| 638 gfx::GpuMemoryBufferHandle handle; |
| 639 handle.type = gfx::OZONE_NATIVE_PIXMAP; |
| 640 handle.native_pixmap_handle.fd = base::FileDescriptor(duped_fd, true); |
| 641 std::vector<gfx::GpuMemoryBufferHandle> handles; |
| 642 handles.push_back(handle); |
| 643 decoder_->ImportBufferForPicture(buffer.id(), handles); |
| 644 } |
| 645 } |
583 } | 646 } |
584 | 647 |
585 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) { | 648 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) { |
586 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id)); | 649 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id)); |
587 } | 650 } |
588 | 651 |
589 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 652 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
590 // We shouldn't be getting pictures delivered after Reset has completed. | 653 // We shouldn't be getting pictures delivered after Reset has completed. |
591 LOG_ASSERT(state_ < CS_RESET); | 654 LOG_ASSERT(state_ < CS_RESET); |
592 | 655 |
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 continue; | 1614 continue; |
1552 } | 1615 } |
1553 if (it->first == "fake_decoder") { | 1616 if (it->first == "fake_decoder") { |
1554 content::g_fake_decoder = 1; | 1617 content::g_fake_decoder = 1; |
1555 continue; | 1618 continue; |
1556 } | 1619 } |
1557 if (it->first == "v" || it->first == "vmodule") | 1620 if (it->first == "v" || it->first == "vmodule") |
1558 continue; | 1621 continue; |
1559 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") | 1622 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") |
1560 continue; | 1623 continue; |
| 1624 if (it->first == "test_import") { |
| 1625 content::g_test_import = true; |
| 1626 continue; |
| 1627 } |
1561 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1628 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1562 } | 1629 } |
1563 | 1630 |
1564 base::ShadowingAtExitManager at_exit_manager; | 1631 base::ShadowingAtExitManager at_exit_manager; |
1565 #if defined(OS_WIN) || defined(USE_OZONE) | 1632 #if defined(OS_WIN) || defined(USE_OZONE) |
1566 // For windows the decoding thread initializes the media foundation decoder | 1633 // For windows the decoding thread initializes the media foundation decoder |
1567 // which uses COM. We need the thread to be a UI thread. | 1634 // which uses COM. We need the thread to be a UI thread. |
1568 // On Ozone, the backend initializes the event system using a UI | 1635 // On Ozone, the backend initializes the event system using a UI |
1569 // thread. | 1636 // thread. |
1570 base::MessageLoopForUI main_loop; | 1637 base::MessageLoopForUI main_loop; |
1571 #else | 1638 #else |
1572 base::MessageLoop main_loop; | 1639 base::MessageLoop main_loop; |
1573 #endif // OS_WIN || USE_OZONE | 1640 #endif // OS_WIN || USE_OZONE |
1574 | 1641 |
1575 #if defined(USE_OZONE) | 1642 #if defined(USE_OZONE) |
1576 ui::OzonePlatform::InitializeForUI(); | 1643 ui::OzonePlatform::InitializeForUI(); |
1577 #endif | 1644 #endif |
1578 | 1645 |
1579 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 1646 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
1580 content::VaapiWrapper::PreSandboxInitialization(); | 1647 content::VaapiWrapper::PreSandboxInitialization(); |
1581 #endif | 1648 #endif |
1582 | 1649 |
1583 content::g_env = | 1650 content::g_env = |
1584 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>( | 1651 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>( |
1585 testing::AddGlobalTestEnvironment( | 1652 testing::AddGlobalTestEnvironment( |
1586 new content::VideoDecodeAcceleratorTestEnvironment())); | 1653 new content::VideoDecodeAcceleratorTestEnvironment())); |
1587 | 1654 |
1588 return RUN_ALL_TESTS(); | 1655 return RUN_ALL_TESTS(); |
1589 } | 1656 } |
OLD | NEW |