platform_video_frame_utils_unittest.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/chromeos/platform_video_frame_utils.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/containers/contains.h"
  10. #include "base/files/file.h"
  11. #include "base/files/file_path.h"
  12. #include "base/files/scoped_file.h"
  13. #include "base/logging.h"
  14. #include "base/numerics/safe_conversions.h"
  15. #include "base/time/time.h"
  16. #include "media/base/color_plane_layout.h"
  17. #include "media/base/format_utils.h"
  18. #include "media/base/video_frame.h"
  19. #include "media/base/video_frame_layout.h"
  20. #include "media/base/video_types.h"
  21. #include "media/video/fake_gpu_memory_buffer.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. #include "third_party/abseil-cpp/absl/types/optional.h"
  24. #include "ui/gfx/buffer_types.h"
  25. #include "ui/gfx/geometry/rect.h"
  26. #include "ui/gfx/geometry/size.h"
  27. #include "ui/gfx/linux/native_pixmap_dmabuf.h"
  28. #include "ui/gfx/native_pixmap_handle.h"
  29. namespace media {
  30. namespace {
  31. // Creates mock FDs and wrap them into a VideoFrame.
  32. scoped_refptr<VideoFrame> CreateMockDmaBufVideoFrame(
  33. VideoPixelFormat pixel_format,
  34. const gfx::Size& coded_size,
  35. const gfx::Rect& visible_rect,
  36. const gfx::Size& natural_size) {
  37. const absl::optional<VideoFrameLayout> layout =
  38. VideoFrameLayout::Create(pixel_format, coded_size);
  39. if (!layout) {
  40. LOG(ERROR) << "Failed to create video frame layout";
  41. return nullptr;
  42. }
  43. std::vector<base::ScopedFD> dmabuf_fds;
  44. for (size_t i = 0; i < layout->num_planes(); i++) {
  45. base::File file(base::FilePath("/dev/null"),
  46. base::File::FLAG_OPEN | base::File::FLAG_READ);
  47. if (!file.IsValid()) {
  48. LOG(ERROR) << "Failed to open a file";
  49. return nullptr;
  50. }
  51. dmabuf_fds.emplace_back(file.TakePlatformFile());
  52. if (!dmabuf_fds.back().is_valid()) {
  53. LOG(ERROR) << "The FD taken from file is not valid";
  54. return nullptr;
  55. }
  56. }
  57. return VideoFrame::WrapExternalDmabufs(*layout, visible_rect, natural_size,
  58. std::move(dmabuf_fds),
  59. base::TimeDelta());
  60. }
  61. } // namespace
  62. TEST(PlatformVideoFrameUtilsTest, CreateNativePixmapDmaBuf) {
  63. constexpr VideoPixelFormat kPixelFormat = PIXEL_FORMAT_NV12;
  64. constexpr gfx::Size kCodedSize(320, 240);
  65. const absl::optional<gfx::BufferFormat> gfx_format =
  66. VideoPixelFormatToGfxBufferFormat(kPixelFormat);
  67. ASSERT_TRUE(gfx_format) << "Invalid pixel format: " << kPixelFormat;
  68. scoped_refptr<VideoFrame> video_frame = CreateMockDmaBufVideoFrame(
  69. kPixelFormat, kCodedSize, gfx::Rect(kCodedSize), kCodedSize);
  70. ASSERT_TRUE(video_frame);
  71. // Create a native pixmap and verify its metadata.
  72. scoped_refptr<gfx::NativePixmapDmaBuf> native_pixmap =
  73. CreateNativePixmapDmaBuf(video_frame.get());
  74. ASSERT_TRUE(native_pixmap);
  75. EXPECT_EQ(native_pixmap->GetBufferFormat(), *gfx_format);
  76. EXPECT_EQ(native_pixmap->GetBufferFormatModifier(),
  77. video_frame->layout().modifier());
  78. // Verify the DMA Buf layouts are the same.
  79. const size_t num_planes = video_frame->layout().num_planes();
  80. ASSERT_EQ(native_pixmap->ExportHandle().planes.size(), num_planes);
  81. for (size_t i = 0; i < num_planes; i++) {
  82. const ColorPlaneLayout& plane = video_frame->layout().planes()[i];
  83. // The original and duplicated FDs should be different.
  84. EXPECT_NE(native_pixmap->GetDmaBufFd(i), video_frame->DmabufFds()[i].get());
  85. EXPECT_EQ(native_pixmap->GetDmaBufPitch(i),
  86. base::checked_cast<uint32_t>(plane.stride));
  87. EXPECT_EQ(native_pixmap->GetDmaBufOffset(i), plane.offset);
  88. EXPECT_EQ(native_pixmap->GetDmaBufPlaneSize(i), plane.size);
  89. }
  90. }
  91. // TODO(b/230370976): remove this #if/#endif guard. To do so, we need to be able
  92. // to mock/fake the allocator used by CreatePlatformVideoFrame() and
  93. // CreateGpuMemoryBufferVideoFrame() so that those functions return a
  94. // non-nullptr frame on platforms where allocating NV12 buffers is not
  95. // supported.
  96. #if BUILDFLAG(IS_CHROMEOS_ASH)
  97. TEST(PlatformVideoFrameUtilsTest, CreateVideoFrame) {
  98. constexpr VideoPixelFormat kPixelFormat = PIXEL_FORMAT_NV12;
  99. constexpr gfx::Size kCodedSize(320, 240);
  100. constexpr gfx::Rect kVisibleRect(kCodedSize);
  101. constexpr gfx::Size kNaturalSize(kCodedSize);
  102. constexpr auto kTimeStamp = base::Milliseconds(1234);
  103. constexpr gfx::BufferUsage kBufferUsage =
  104. gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE;
  105. const VideoFrame::StorageType storage_types[] = {
  106. VideoFrame::STORAGE_DMABUFS,
  107. VideoFrame::STORAGE_GPU_MEMORY_BUFFER,
  108. };
  109. for (const auto& storage_type : storage_types) {
  110. scoped_refptr<VideoFrame> frame;
  111. switch (storage_type) {
  112. case VideoFrame::STORAGE_DMABUFS:
  113. frame =
  114. CreatePlatformVideoFrame(kPixelFormat, kCodedSize, kVisibleRect,
  115. kNaturalSize, kTimeStamp, kBufferUsage);
  116. break;
  117. case VideoFrame::STORAGE_GPU_MEMORY_BUFFER:
  118. frame = CreateGpuMemoryBufferVideoFrame(kPixelFormat, kCodedSize,
  119. kVisibleRect, kNaturalSize,
  120. kTimeStamp, kBufferUsage);
  121. break;
  122. default:
  123. NOTREACHED();
  124. break;
  125. };
  126. ASSERT_TRUE(frame);
  127. EXPECT_EQ(frame->format(), kPixelFormat);
  128. EXPECT_EQ(frame->coded_size(), kCodedSize);
  129. EXPECT_EQ(frame->visible_rect(), kVisibleRect);
  130. EXPECT_EQ(frame->natural_size(), kNaturalSize);
  131. EXPECT_EQ(frame->timestamp(), kTimeStamp);
  132. EXPECT_EQ(frame->storage_type(), storage_type);
  133. switch (storage_type) {
  134. case VideoFrame::STORAGE_DMABUFS:
  135. EXPECT_FALSE(frame->DmabufFds().empty());
  136. break;
  137. case VideoFrame::STORAGE_GPU_MEMORY_BUFFER:
  138. EXPECT_TRUE(frame->GetGpuMemoryBuffer());
  139. break;
  140. default:
  141. NOTREACHED();
  142. break;
  143. };
  144. }
  145. }
  146. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  147. } // namespace media