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

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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 268
263 private: 269 private:
264 base::Thread rendering_thread_; 270 base::Thread rendering_thread_;
265 #if defined(USE_OZONE) 271 #if defined(USE_OZONE)
266 std::unique_ptr<ui::OzoneGpuTestHelper> gpu_helper_; 272 std::unique_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. Can be backed by
279 // either a buffer allocated by the VDA, or by a preallocated pixmap.
273 class TextureRef : public base::RefCounted<TextureRef> { 280 class TextureRef : public base::RefCounted<TextureRef> {
274 public: 281 public:
275 TextureRef(uint32_t texture_id, const base::Closure& no_longer_needed_cb) 282 static scoped_refptr<TextureRef> Create(
276 : texture_id_(texture_id), no_longer_needed_cb_(no_longer_needed_cb) {} 283 uint32_t texture_id,
284 const base::Closure& no_longer_needed_cb);
285
286 static scoped_refptr<TextureRef> CreatePreallocated(
287 uint32_t texture_id,
288 const base::Closure& no_longer_needed_cb,
289 media::VideoPixelFormat pixel_format,
290 const gfx::Size& size);
291
292 std::vector<gfx::GpuMemoryBufferHandle> ExportGpuMemoryBufferHandles() const;
277 293
278 int32_t texture_id() const { return texture_id_; } 294 int32_t texture_id() const { return texture_id_; }
279 295
280 private: 296 private:
281 friend class base::RefCounted<TextureRef>; 297 friend class base::RefCounted<TextureRef>;
298
299 TextureRef(uint32_t texture_id, const base::Closure& no_longer_needed_cb)
300 : texture_id_(texture_id), no_longer_needed_cb_(no_longer_needed_cb) {}
301
282 ~TextureRef(); 302 ~TextureRef();
283 303
284 uint32_t texture_id_; 304 uint32_t texture_id_;
285 base::Closure no_longer_needed_cb_; 305 base::Closure no_longer_needed_cb_;
306 #if defined(USE_OZONE)
307 scoped_refptr<ui::NativePixmap> pixmap_;
308 #endif
286 }; 309 };
287 310
288 TextureRef::~TextureRef() { 311 TextureRef::~TextureRef() {
289 base::ResetAndReturn(&no_longer_needed_cb_).Run(); 312 base::ResetAndReturn(&no_longer_needed_cb_).Run();
290 } 313 }
291 314
315 // static
316 scoped_refptr<TextureRef> TextureRef::Create(
317 uint32_t texture_id,
318 const base::Closure& no_longer_needed_cb) {
319 return make_scoped_refptr(new TextureRef(texture_id, no_longer_needed_cb));
320 }
321
322 #if defined(USE_OZONE)
323 gfx::BufferFormat VideoPixelFormatToGfxBufferFormat(
324 media::VideoPixelFormat pixel_format) {
325 switch (pixel_format) {
326 case media::VideoPixelFormat::PIXEL_FORMAT_ARGB:
327 return gfx::BufferFormat::BGRA_8888;
328 case media::VideoPixelFormat::PIXEL_FORMAT_XRGB:
329 return gfx::BufferFormat::BGRX_8888;
330 case media::VideoPixelFormat::PIXEL_FORMAT_NV12:
331 return gfx::BufferFormat::YUV_420_BIPLANAR;
332 default:
333 LOG_ASSERT(false) << "Unknown VideoPixelFormat";
334 return gfx::BufferFormat::BGRX_8888;
335 }
336 }
337 #endif
338
339 // static
340 scoped_refptr<TextureRef> TextureRef::CreatePreallocated(
341 uint32_t texture_id,
342 const base::Closure& no_longer_needed_cb,
343 media::VideoPixelFormat pixel_format,
344 const gfx::Size& size) {
345 scoped_refptr<TextureRef> texture_ref;
346 #if defined(USE_OZONE)
347 texture_ref = TextureRef::Create(texture_id, no_longer_needed_cb);
348 LOG_ASSERT(texture_ref);
349
350 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
351 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
352 gfx::BufferFormat buffer_format =
353 VideoPixelFormatToGfxBufferFormat(pixel_format);
354 texture_ref->pixmap_ =
355 factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size,
356 buffer_format, gfx::BufferUsage::SCANOUT);
357 LOG_ASSERT(texture_ref->pixmap_);
358 #endif
359
360 return texture_ref;
361 }
362
363 std::vector<gfx::GpuMemoryBufferHandle>
364 TextureRef::ExportGpuMemoryBufferHandles() const {
365 std::vector<gfx::GpuMemoryBufferHandle> handles;
366 #if defined(USE_OZONE)
367 CHECK(pixmap_);
368 int duped_fd = HANDLE_EINTR(dup(pixmap_->GetDmaBufFd()));
369 LOG_ASSERT(duped_fd != -1) << "Failed duplicating dmabuf fd";
370 gfx::GpuMemoryBufferHandle handle;
371 handle.type = gfx::OZONE_NATIVE_PIXMAP;
372 handle.native_pixmap_handle.fd = base::FileDescriptor(duped_fd, true);
373 handles.push_back(handle);
374 #endif
375 return handles;
376 }
377
292 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by 378 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by
293 // the TESTs below. 379 // the TESTs below.
294 class GLRenderingVDAClient 380 class GLRenderingVDAClient
295 : public VideoDecodeAccelerator::Client, 381 : public VideoDecodeAccelerator::Client,
296 public base::SupportsWeakPtr<GLRenderingVDAClient> { 382 public base::SupportsWeakPtr<GLRenderingVDAClient> {
297 public: 383 public:
298 // |window_id| the window_id of the client, which is used to identify the 384 // |window_id| the window_id of the client, which is used to identify the
299 // rendering area in the |rendering_helper|. 385 // rendering area in the |rendering_helper|.
300 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive 386 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive
301 // |*this|. 387 // |*this|.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 } else { 610 } else {
525 if (!vda_factory_) { 611 if (!vda_factory_) {
526 vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create( 612 vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create(
527 base::Bind(&RenderingHelper::GetGLContext, 613 base::Bind(&RenderingHelper::GetGLContext,
528 base::Unretained(rendering_helper_)), 614 base::Unretained(rendering_helper_)),
529 base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage)); 615 base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage));
530 LOG_ASSERT(vda_factory_); 616 LOG_ASSERT(vda_factory_);
531 } 617 }
532 618
533 VideoDecodeAccelerator::Config config(profile_); 619 VideoDecodeAccelerator::Config config(profile_);
620 if (g_test_import) {
621 config.output_mode =
622 media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;
623 }
534 gpu::GpuPreferences gpu_preferences; 624 gpu::GpuPreferences gpu_preferences;
535 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences); 625 decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences);
536 } 626 }
537 627
538 LOG_ASSERT(decoder_) << "Failed creating a VDA"; 628 LOG_ASSERT(decoder_) << "Failed creating a VDA";
539 629
540 decoder_->TryToSetupDecodeOnSeparateThread( 630 decoder_->TryToSetupDecodeOnSeparateThread(
541 weak_this_, base::ThreadTaskRunnerHandle::Get()); 631 weak_this_, base::ThreadTaskRunnerHandle::Get());
542 632
543 SetState(CS_DECODER_SET); 633 SetState(CS_DECODER_SET);
(...skipping 13 matching lines...) Expand all
557 requested_num_of_buffers += kExtraPictureBuffers; 647 requested_num_of_buffers += kExtraPictureBuffers;
558 648
559 texture_target_ = texture_target; 649 texture_target_ = texture_target;
560 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { 650 for (uint32_t i = 0; i < requested_num_of_buffers; ++i) {
561 uint32_t texture_id; 651 uint32_t texture_id;
562 base::WaitableEvent done(false, false); 652 base::WaitableEvent done(false, false);
563 rendering_helper_->CreateTexture( 653 rendering_helper_->CreateTexture(
564 texture_target_, &texture_id, dimensions, &done); 654 texture_target_, &texture_id, dimensions, &done);
565 done.Wait(); 655 done.Wait();
566 656
657 scoped_refptr<TextureRef> texture_ref;
658 base::Closure delete_texture_cb =
659 base::Bind(&RenderingHelper::DeleteTexture,
660 base::Unretained(rendering_helper_), texture_id);
661
662 if (g_test_import) {
663 media::VideoPixelFormat pixel_format = decoder_->GetOutputFormat();
664 if (pixel_format == media::PIXEL_FORMAT_UNKNOWN)
665 pixel_format = media::PIXEL_FORMAT_ARGB;
666 texture_ref = TextureRef::CreatePreallocated(
667 texture_id, delete_texture_cb, pixel_format, dimensions);
668 } else {
669 texture_ref = TextureRef::Create(texture_id, delete_texture_cb);
670 }
671
672 LOG_ASSERT(texture_ref);
673
567 int32_t picture_buffer_id = next_picture_buffer_id_++; 674 int32_t picture_buffer_id = next_picture_buffer_id_++;
568 LOG_ASSERT(active_textures_ 675 LOG_ASSERT(
569 .insert(std::make_pair( 676 active_textures_.insert(std::make_pair(picture_buffer_id, texture_ref))
570 picture_buffer_id, 677 .second);
571 new TextureRef(texture_id,
572 base::Bind(&RenderingHelper::DeleteTexture,
573 base::Unretained(rendering_helper_),
574 texture_id))))
575 .second);
576 678
577 media::PictureBuffer::TextureIds ids; 679 media::PictureBuffer::TextureIds ids;
578 ids.push_back(texture_id); 680 ids.push_back(texture_id);
579 buffers.push_back(media::PictureBuffer(picture_buffer_id, dimensions, ids)); 681 buffers.push_back(media::PictureBuffer(picture_buffer_id, dimensions, ids));
580 } 682 }
581 decoder_->AssignPictureBuffers(buffers); 683 decoder_->AssignPictureBuffers(buffers);
684
685 if (g_test_import) {
686 for (const auto& buffer : buffers) {
687 TextureRefMap::iterator texture_it = active_textures_.find(buffer.id());
688 ASSERT_NE(active_textures_.end(), texture_it);
689
690 std::vector<gfx::GpuMemoryBufferHandle> handles =
691 texture_it->second->ExportGpuMemoryBufferHandles();
692 LOG_ASSERT(!handles.empty()) << "Failed producing GMB handles";
693
694 decoder_->ImportBufferForPicture(buffer.id(), handles);
695 }
696 }
582 } 697 }
583 698
584 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) { 699 void GLRenderingVDAClient::DismissPictureBuffer(int32_t picture_buffer_id) {
585 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id)); 700 LOG_ASSERT(1U == active_textures_.erase(picture_buffer_id));
586 } 701 }
587 702
588 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { 703 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
589 // We shouldn't be getting pictures delivered after Reset has completed. 704 // We shouldn't be getting pictures delivered after Reset has completed.
590 LOG_ASSERT(state_ < CS_RESET); 705 LOG_ASSERT(state_ < CS_RESET);
591 706
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 continue; 1665 continue;
1551 } 1666 }
1552 if (it->first == "fake_decoder") { 1667 if (it->first == "fake_decoder") {
1553 content::g_fake_decoder = 1; 1668 content::g_fake_decoder = 1;
1554 continue; 1669 continue;
1555 } 1670 }
1556 if (it->first == "v" || it->first == "vmodule") 1671 if (it->first == "v" || it->first == "vmodule")
1557 continue; 1672 continue;
1558 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") 1673 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless")
1559 continue; 1674 continue;
1675 if (it->first == "test_import") {
1676 content::g_test_import = true;
1677 continue;
1678 }
1560 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; 1679 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
1561 } 1680 }
1562 1681
1563 base::ShadowingAtExitManager at_exit_manager; 1682 base::ShadowingAtExitManager at_exit_manager;
1564 #if defined(OS_WIN) || defined(USE_OZONE) 1683 #if defined(OS_WIN) || defined(USE_OZONE)
1565 // For windows the decoding thread initializes the media foundation decoder 1684 // For windows the decoding thread initializes the media foundation decoder
1566 // which uses COM. We need the thread to be a UI thread. 1685 // which uses COM. We need the thread to be a UI thread.
1567 // On Ozone, the backend initializes the event system using a UI 1686 // On Ozone, the backend initializes the event system using a UI
1568 // thread. 1687 // thread.
1569 base::MessageLoopForUI main_loop; 1688 base::MessageLoopForUI main_loop;
1570 #else 1689 #else
1571 base::MessageLoop main_loop; 1690 base::MessageLoop main_loop;
1572 #endif // OS_WIN || USE_OZONE 1691 #endif // OS_WIN || USE_OZONE
1573 1692
1574 #if defined(USE_OZONE) 1693 #if defined(USE_OZONE)
1575 ui::OzonePlatform::InitializeForUI(); 1694 ui::OzonePlatform::InitializeForUI();
1576 #endif 1695 #endif
1577 1696
1578 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) 1697 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
1579 content::VaapiWrapper::PreSandboxInitialization(); 1698 content::VaapiWrapper::PreSandboxInitialization();
1580 #endif 1699 #endif
1581 1700
1582 content::g_env = 1701 content::g_env =
1583 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>( 1702 reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>(
1584 testing::AddGlobalTestEnvironment( 1703 testing::AddGlobalTestEnvironment(
1585 new content::VideoDecodeAcceleratorTestEnvironment())); 1704 new content::VideoDecodeAcceleratorTestEnvironment()));
1586 1705
1587 return RUN_ALL_TESTS(); 1706 return RUN_ALL_TESTS();
1588 } 1707 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698