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

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

Issue 1822983002: Support external buffer import in VDA interface and add a V4L2SVDA impl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 #endif 67 #endif
68 #if defined(ARCH_CPU_X86_FAMILY) 68 #if defined(ARCH_CPU_X86_FAMILY)
69 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" 69 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
70 #include "content/common/gpu/media/vaapi_wrapper.h" 70 #include "content/common/gpu/media/vaapi_wrapper.h"
71 #endif // defined(ARCH_CPU_X86_FAMILY) 71 #endif // defined(ARCH_CPU_X86_FAMILY)
72 #else 72 #else
73 #error The VideoAccelerator tests are not supported on this platform. 73 #error The VideoAccelerator tests are not supported on this platform.
74 #endif // OS_WIN 74 #endif // OS_WIN
75 75
76 #if defined(USE_OZONE) 76 #if defined(USE_OZONE)
77 #include "ui/ozone/public/native_pixmap.h"
77 #include "ui/ozone/public/ozone_gpu_test_helper.h" 78 #include "ui/ozone/public/ozone_gpu_test_helper.h"
78 #include "ui/ozone/public/ozone_platform.h" 79 #include "ui/ozone/public/ozone_platform.h"
80 #include "ui/ozone/public/surface_factory_ozone.h"
79 #endif // defined(USE_OZONE) 81 #endif // defined(USE_OZONE)
80 82
81 using media::VideoDecodeAccelerator; 83 using media::VideoDecodeAccelerator;
82 84
83 namespace content { 85 namespace content {
84 namespace { 86 namespace {
85 87
86 using base::MakeTuple; 88 using base::MakeTuple;
87 89
88 // Values optionally filled in from flags; see main() below. 90 // Values optionally filled in from flags; see main() below.
(...skipping 29 matching lines...) Expand all
118 int g_rendering_warm_up = 0; 120 int g_rendering_warm_up = 0;
119 121
120 // The value is set by the switch "--num_play_throughs". The video will play 122 // The value is set by the switch "--num_play_throughs". The video will play
121 // the specified number of times. In different test cases, we have different 123 // the specified number of times. In different test cases, we have different
122 // values for |num_play_throughs|. This setting will override the value. A 124 // values for |num_play_throughs|. This setting will override the value. A
123 // special value "0" means no override. 125 // special value "0" means no override.
124 int g_num_play_throughs = 0; 126 int g_num_play_throughs = 0;
125 // Fake decode 127 // Fake decode
126 int g_fake_decoder = 0; 128 int g_fake_decoder = 0;
127 129
130 // Test buffer import into VDA, providing buffers allocated by us, instead of
131 // requesting the VDA itself to allocate buffers.
132 bool g_test_import = false;
133
128 // Environment to store rendering thread. 134 // Environment to store rendering thread.
129 class VideoDecodeAcceleratorTestEnvironment; 135 class VideoDecodeAcceleratorTestEnvironment;
130 VideoDecodeAcceleratorTestEnvironment* g_env; 136 VideoDecodeAcceleratorTestEnvironment* g_env;
131 137
132 // Magic constants for differentiating the reasons for NotifyResetDone being 138 // Magic constants for differentiating the reasons for NotifyResetDone being
133 // called. 139 // called.
134 enum ResetPoint { 140 enum ResetPoint {
135 // Reset() just after calling Decode() with a fragment containing config info. 141 // Reset() just after calling Decode() with a fragment containing config info.
136 RESET_AFTER_FIRST_CONFIG_INFO = -4, 142 RESET_AFTER_FIRST_CONFIG_INFO = -4,
137 START_OF_STREAM_RESET = -3, 143 START_OF_STREAM_RESET = -3,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 #if defined(USE_OZONE) 271 #if defined(USE_OZONE)
266 scoped_ptr<ui::OzoneGpuTestHelper> gpu_helper_; 272 scoped_ptr<ui::OzoneGpuTestHelper> gpu_helper_;
267 #endif 273 #endif
268 274
269 DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorTestEnvironment); 275 DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorTestEnvironment);
270 }; 276 };
271 277
272 // A helper class used to manage the lifetime of a Texture. 278 // A helper class used to manage the lifetime of a Texture.
273 class TextureRef : public base::RefCounted<TextureRef> { 279 class TextureRef : public base::RefCounted<TextureRef> {
274 public: 280 public:
275 TextureRef(uint32_t texture_id, const base::Closure& no_longer_needed_cb) 281 TextureRef(uint32_t texture_id,
276 : texture_id_(texture_id), no_longer_needed_cb_(no_longer_needed_cb) {} 282 const scoped_refptr<ui::NativePixmap>& pixmap,
283 const base::Closure& no_longer_needed_cb)
284 : texture_id_(texture_id),
285 pixmap_(pixmap),
286 no_longer_needed_cb_(no_longer_needed_cb) {}
277 287
278 int32_t texture_id() const { return texture_id_; } 288 int32_t texture_id() const { return texture_id_; }
289 scoped_refptr<ui::NativePixmap> pixmap() { return pixmap_; }
279 290
280 private: 291 private:
281 friend class base::RefCounted<TextureRef>; 292 friend class base::RefCounted<TextureRef>;
282 ~TextureRef(); 293 ~TextureRef();
283 294
284 uint32_t texture_id_; 295 uint32_t texture_id_;
296 scoped_refptr<ui::NativePixmap> pixmap_;
285 base::Closure no_longer_needed_cb_; 297 base::Closure no_longer_needed_cb_;
286 }; 298 };
287 299
288 TextureRef::~TextureRef() { 300 TextureRef::~TextureRef() {
289 base::ResetAndReturn(&no_longer_needed_cb_).Run(); 301 base::ResetAndReturn(&no_longer_needed_cb_).Run();
290 } 302 }
291 303
292 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by 304 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by
293 // the TESTs below. 305 // the TESTs below.
294 class GLRenderingVDAClient 306 class GLRenderingVDAClient
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences); 550 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences);
535 } 551 }
536 552
537 LOG_ASSERT(decoder_) << "Failed creating a VDA"; 553 LOG_ASSERT(decoder_) << "Failed creating a VDA";
538 554
539 decoder_->TryToSetupDecodeOnSeparateThread( 555 decoder_->TryToSetupDecodeOnSeparateThread(
540 weak_this_, base::ThreadTaskRunnerHandle::Get()); 556 weak_this_, base::ThreadTaskRunnerHandle::Get());
541 557
542 SetState(CS_DECODER_SET); 558 SetState(CS_DECODER_SET);
543 FinishInitialization(); 559 FinishInitialization();
544 } 560 }
545 561
562 namespace {
563 gfx::BufferFormat VideoPixelFormatToGfxBufferFormat(
564 media::VideoPixelFormat pixel_format) {
565 switch (pixel_format) {
566 case media::VideoPixelFormat::PIXEL_FORMAT_ARGB:
567 return gfx::BufferFormat::BGRA_8888;
568 case media::VideoPixelFormat::PIXEL_FORMAT_XRGB:
569 return gfx::BufferFormat::BGRX_8888;
570 case media::VideoPixelFormat::PIXEL_FORMAT_NV12:
571 return gfx::BufferFormat::YUV_420_BIPLANAR;
572 default:
573 LOG_ASSERT(false) << "Unknown VideoPixelFormat";
574 return gfx::BufferFormat::BGRX_8888;
575 }
576 }
577 }
578
546 void GLRenderingVDAClient::ProvidePictureBuffers( 579 void GLRenderingVDAClient::ProvidePictureBuffers(
547 uint32_t requested_num_of_buffers, 580 uint32_t requested_num_of_buffers,
548 const gfx::Size& dimensions, 581 const gfx::Size& dimensions,
549 uint32_t texture_target) { 582 uint32_t texture_target) {
550 if (decoder_deleted()) 583 if (decoder_deleted())
551 return; 584 return;
552 std::vector<media::PictureBuffer> buffers; 585 std::vector<media::PictureBuffer> buffers;
553 586
554 requested_num_of_buffers += kExtraPictureBuffers; 587 requested_num_of_buffers += kExtraPictureBuffers;
555 588
556 texture_target_ = texture_target; 589 texture_target_ = texture_target;
557 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { 590 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) {
558 uint32_t texture_id; 591 uint32_t texture_id;
559 base::WaitableEvent done(false, false); 592 base::WaitableEvent done(false, false);
560 rendering_helper_->CreateTexture( 593 rendering_helper_->CreateTexture(
561 texture_target_, &texture_id, dimensions, &done); 594 texture_target_, &texture_id, dimensions, &done);
562 done.Wait(); 595 done.Wait();
563 596
597 scoped_refptr<ui::NativePixmap> pixmap;
598 if (g_test_import) {
599 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
600 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
601 gfx::BufferFormat buffer_format =
602 VideoPixelFormatToGfxBufferFormat(decoder_->GetOutputFormat());
603 pixmap =
604 factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, dimensions,
605 buffer_format, gfx::BufferUsage::SCANOUT);
606 LOG_ASSERT(pixmap);
607 }
608
564 int32_t picture_buffer_id = next_picture_buffer_id_++; 609 int32_t picture_buffer_id = next_picture_buffer_id_++;
565 LOG_ASSERT(active_textures_ 610 LOG_ASSERT(
566 .insert(std::make_pair( 611 active_textures_
567 picture_buffer_id, 612 .insert(std::make_pair(
568 new TextureRef(texture_id, 613 picture_buffer_id,
569 base::Bind(&RenderingHelper::DeleteTexture, 614 new TextureRef(texture_id, pixmap,
570 base::Unretained(rendering_helper_), 615 base::Bind(&RenderingHelper::DeleteTexture,
571 texture_id)))) 616 base::Unretained(rendering_helper_),
572 .second); 617 texture_id))))
618 .second);
573 619
574 buffers.push_back( 620 buffers.push_back(
575 media::PictureBuffer(picture_buffer_id, dimensions, texture_id)); 621 media::PictureBuffer(picture_buffer_id, dimensions, texture_id));
576 } 622 }
577 decoder_->AssignPictureBuffers(buffers); 623 decoder_->AssignPictureBuffers(buffers);
624
625 if (g_test_import) {
626 for (const auto& buffer : buffers) {
627 TextureRefMap::iterator texture_it = active_textures_.find(buffer.id());
628 ASSERT_NE(active_textures_.end(), texture_it);
629
630 scoped_refptr<ui::NativePixmap> pixmap = texture_it->second->pixmap();
631 int duped_fd = HANDLE_EINTR(dup(pixmap->GetDmaBufFd()));
632 ASSERT_NE(duped_fd, -1);
633 gfx::GpuMemoryBufferHandle handle;
634 handle.type = gfx::OZONE_NATIVE_PIXMAP;
635 handle.native_pixmap_handle.fd = base::FileDescriptor(duped_fd, true);
636 std::vector<gfx::GpuMemoryBufferHandle> handles;
637 handles.push_back(handle);
638 decoder_->ImportBufferForPicture(buffer.id(), handles);
639 }
640 }
578 } 641 }
579 642
580 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) { 643 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) {
581 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id)); 644 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id));
582 } 645 }
583 646
584 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { 647 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
585 // We shouldn't be getting pictures delivered after Reset has completed. 648 // We shouldn't be getting pictures delivered after Reset has completed.
586 LOG_ASSERT(state_ < CS_RESET); 649 LOG_ASSERT(state_ < CS_RESET);
587 650
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 continue; 1609 continue;
1547 } 1610 }
1548 if (it->first == "fake_decoder") { 1611 if (it->first == "fake_decoder") {
1549 content::g_fake_decoder = 1; 1612 content::g_fake_decoder = 1;
1550 continue; 1613 continue;
1551 } 1614 }
1552 if (it->first == "v" || it->first == "vmodule") 1615 if (it->first == "v" || it->first == "vmodule")
1553 continue; 1616 continue;
1554 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") 1617 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless")
1555 continue; 1618 continue;
1619 if (it->first == "test_import") {
1620 content::g_test_import = true;
1621 continue;
1622 }
1556 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; 1623 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
1557 } 1624 }
1558 1625
1559 base::ShadowingAtExitManager at_exit_manager; 1626 base::ShadowingAtExitManager at_exit_manager;
1560 #if defined(OS_WIN) || defined(USE_OZONE) 1627 #if defined(OS_WIN) || defined(USE_OZONE)
1561 // For windows the decoding thread initializes the media foundation decoder 1628 // For windows the decoding thread initializes the media foundation decoder
1562 // which uses COM. We need the thread to be a UI thread. 1629 // which uses COM. We need the thread to be a UI thread.
1563 // On Ozone, the backend initializes the event system using a UI 1630 // On Ozone, the backend initializes the event system using a UI
1564 // thread. 1631 // thread.
1565 base::MessageLoopForUI main_loop; 1632 base::MessageLoopForUI main_loop;
1566 #else 1633 #else
1567 base::MessageLoop main_loop; 1634 base::MessageLoop main_loop;
1568 #endif // OS_WIN || USE_OZONE 1635 #endif // OS_WIN || USE_OZONE
1569 1636
1570 #if defined(USE_OZONE) 1637 #if defined(USE_OZONE)
1571 ui::OzonePlatform::InitializeForUI(); 1638 ui::OzonePlatform::InitializeForUI();
1572 #endif 1639 #endif
1573 1640
1574 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) 1641 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
1575 content::VaapiWrapper::PreSandboxInitialization(); 1642 content::VaapiWrapper::PreSandboxInitialization();
1576 #endif 1643 #endif
1577 1644
1578 content::g_env = 1645 content::g_env =
1579 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>( 1646 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>(
1580 testing::AddGlobalTestEnvironment( 1647 testing::AddGlobalTestEnvironment(
1581 new content::VideoDecodeAcceleratorTestEnvironment())); 1648 new content::VideoDecodeAcceleratorTestEnvironment()));
1582 1649
1583 return RUN_ALL_TESTS(); 1650 return RUN_ALL_TESTS();
1584 } 1651 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698