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

Unified Diff: media/video/gpu_memory_buffer_video_frame_pool_unittest.cc

Issue 1874733002: media: split GpuMemoryBufferVideoFramePool into GpuMemoryBufferVideoFrameCopier/Pool Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add GpuMemoryBufferVideoFramePoolTest 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/video/gpu_memory_buffer_video_frame_pool.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
index 8374ba699fde41b04e89e0cee5514c14541f3e77..c78f10ceedf601290cd2447e68cc5e1ce47f8219 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -72,14 +72,12 @@ class GpuMemoryBufferVideoFramePoolTest : public ::testing::Test {
void SetUp() override {
gles2_.reset(new TestGLES2Interface);
media_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner);
- copy_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner);
media_task_runner_handle_.reset(
new base::ThreadTaskRunnerHandle(media_task_runner_));
mock_gpu_factories_.reset(
new MockGpuVideoAcceleratorFactories(gles2_.get()));
gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool(
- media_task_runner_, copy_task_runner_.get(),
- mock_gpu_factories_.get()));
+ media_task_runner_, mock_gpu_factories_.get()));
}
void TearDown() override {
@@ -90,223 +88,249 @@ class GpuMemoryBufferVideoFramePoolTest : public ::testing::Test {
void RunUntilIdle() {
media_task_runner_->RunUntilIdle();
- copy_task_runner_->RunUntilIdle();
media_task_runner_->RunUntilIdle();
}
- static scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame(
- int dimension) {
+ std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format) {
const int kDimension = 10;
- static uint8_t y_data[kDimension * kDimension] = {0};
- static uint8_t u_data[kDimension * kDimension / 2] = {0};
- static uint8_t v_data[kDimension * kDimension / 2] = {0};
-
- DCHECK_LE(dimension, kDimension);
- gfx::Size size(dimension, dimension);
-
- scoped_refptr<VideoFrame> video_frame =
- media::VideoFrame::WrapExternalYuvData(
- media::PIXEL_FORMAT_YV12, // format
- size, // coded_size
- gfx::Rect(size), // visible_rect
- size, // natural_size
- size.width(), // y_stride
- size.width() / 2, // u_stride
- size.width() / 2, // v_stride
- y_data, // y_data
- u_data, // u_data
- v_data, // v_data
- base::TimeDelta()); // timestamp
- EXPECT_TRUE(video_frame);
- return video_frame;
+ return CreateFrame(format, kDimension);
+ }
+
+ std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format,
+ int width) {
+ gfx::Size coded_size(width, width);
+ gfx::Rect visible_rect(coded_size);
+ gfx::Size natural_size(coded_size);
+
+ return gpu_memory_buffer_pool_->CreateFrame(
+ format, coded_size, visible_rect, natural_size, kNoTimestamp());
+ }
+
+ void CheckPoolSize(size_t size) const {
+ EXPECT_EQ(size, gpu_memory_buffer_pool_->GetPoolSizeForTesting());
}
protected:
scoped_ptr<MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
scoped_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_;
scoped_refptr<base::TestSimpleTaskRunner> media_task_runner_;
- scoped_refptr<base::TestSimpleTaskRunner> copy_task_runner_;
// GpuMemoryBufferVideoFramePool uses BindToCurrentLoop(), which requires
// ThreadTaskRunnerHandle initialization.
scoped_ptr<base::ThreadTaskRunnerHandle> media_task_runner_handle_;
scoped_ptr<TestGLES2Interface> gles2_;
};
-void MaybeCreateHardwareFrameCallback(
- scoped_refptr<VideoFrame>* video_frame_output,
- const scoped_refptr<VideoFrame>& video_frame) {
- *video_frame_output = video_frame;
+TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameInitializedAndZeroed_I420) {
+ VideoPixelFormat format = PIXEL_FORMAT_I420;
+ std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format);
+
+ for (size_t i = 0; i < VideoFrame::NumPlanes(format); ++i)
+ EXPECT_EQ(0, frame_future->data(i)[0]);
+
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
+
+ EXPECT_EQ(format, frame->format());
+ EXPECT_EQ(3u, gles2_->gen_textures);
}
-TEST_F(GpuMemoryBufferVideoFramePoolTest, VideoFrameOutputFormatUnknown) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_UNKNOWN);
- scoped_refptr<VideoFrame> frame;
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameInitializedAndZeroed_YV12) {
+ VideoPixelFormat format = PIXEL_FORMAT_YV12;
+ std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format);
+
+ for (size_t i = 0; i < VideoFrame::NumPlanes(format); ++i)
+ EXPECT_EQ(0, frame_future->data(i)[0]);
+
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
+
+ // I420 VideoFrame covers both PIXEL_FORMAT_I420 and PIXEL_FORMAT_YV12;
+ EXPECT_EQ(PIXEL_FORMAT_I420, frame->format());
+ EXPECT_EQ(3u, gles2_->gen_textures);
+}
+
+TEST_F(GpuMemoryBufferVideoFramePoolTest, SimpleFrameReuse) {
+ VideoPixelFormat format = PIXEL_FORMAT_I420;
+ std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format);
+
+ const uint8_t* old_y_data = frame_future->data(VideoFrame::kYPlane);
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
+
+ // Clear frame reference to return the frame to the pool.
+ frame = nullptr;
+ frame_future = nullptr;
+
RunUntilIdle();
- EXPECT_EQ(software_frame.get(), frame.get());
+ // Verify that the next frame from the pool uses the same memory.
+ std::unique_ptr<VideoFrameFuture> new_frame_future = CreateFrame(format);
+ EXPECT_EQ(old_y_data, new_frame_future->data(VideoFrame::kYPlane));
}
-TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrame) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+TEST_F(GpuMemoryBufferVideoFramePoolTest, SimpleFormatChange) {
+ std::unique_ptr<VideoFrameFuture> frame_future1 =
+ CreateFrame(PIXEL_FORMAT_YV12);
+ std::unique_ptr<VideoFrameFuture> frame_future2 =
+ CreateFrame(PIXEL_FORMAT_YV12);
+
+ scoped_refptr<VideoFrame> frame1 = frame_future1->Release();
+ scoped_refptr<VideoFrame> frame2 = frame_future2->Release();
+ // Clear frame references to return the frames to the pool.
+ frame1 = nullptr;
+ frame2 = nullptr;
+ frame_future1 = nullptr;
+ frame_future2 = nullptr;
+
+ // Verify that both frames are in the pool.
+ CheckPoolSize(2u);
RunUntilIdle();
+ CheckPoolSize(2u);
- EXPECT_NE(software_frame.get(), frame.get());
- EXPECT_EQ(3u, gles2_->gen_textures);
+ // Verify that requesting a frame with a different format causes the pool
+ // to get drained.
+ std::unique_ptr<VideoFrameFuture> new_frame_future =
+ CreateFrame(PIXEL_FORMAT_I420);
+ CheckPoolSize(1u);
}
-TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameValidAfterPoolDestruction) {
+ std::unique_ptr<VideoFrameFuture> frame_future =
+ CreateFrame(PIXEL_FORMAT_YV12);
+
+ // Destroy the pool.
+ gpu_memory_buffer_pool_.reset();
+
RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame.get());
- gpu::Mailbox mailbox = frame->mailbox_holder(0).mailbox;
- const gpu::SyncToken sync_token = frame->mailbox_holder(0).sync_token;
+ // Write to the Y plane. The memory tools should detect a
+ // use-after-free if the storage was actually removed by pool destruction.
+ memset(frame_future->data(VideoFrame::kYPlane), 0xff,
+ frame_future->stride(VideoFrame::kYPlane));
+}
+
+TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) {
+ std::unique_ptr<VideoFrameFuture> frame_future1 =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> frame1 = frame_future1->Release();
+ gpu::Mailbox mailbox = frame1->mailbox_holder(0).mailbox;
+ const gpu::SyncToken sync_token = frame1->mailbox_holder(0).sync_token;
EXPECT_EQ(3u, gles2_->gen_textures);
- scoped_refptr<VideoFrame> frame2;
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2));
- RunUntilIdle();
+ std::unique_ptr<VideoFrameFuture> frame_future2 =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> frame2 = frame_future2->Release();
- EXPECT_NE(software_frame.get(), frame2.get());
+ EXPECT_NE(frame1.get(), frame2.get());
EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox);
EXPECT_EQ(6u, gles2_->gen_textures);
- frame = nullptr;
+ frame1 = nullptr;
frame2 = nullptr;
+ frame_future1 = nullptr;
+ frame_future2 = nullptr;
RunUntilIdle();
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
- RunUntilIdle();
+ std::unique_ptr<VideoFrameFuture> new_frame_future =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> new_frame = new_frame_future->Release();
- EXPECT_NE(software_frame.get(), frame.get());
EXPECT_EQ(6u, gles2_->gen_textures);
- EXPECT_EQ(frame->mailbox_holder(0).mailbox, mailbox);
- EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token);
+ EXPECT_EQ(new_frame->mailbox_holder(0).mailbox, mailbox);
+ EXPECT_NE(new_frame->mailbox_holder(0).sync_token, sync_token);
}
TEST_F(GpuMemoryBufferVideoFramePoolTest, DoNotReuseInUse) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
- scoped_refptr<VideoFrame> frame2;
-
- // Allocate a frame.
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
- RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame.get());
- gpu::Mailbox mailbox = frame->mailbox_holder(0).mailbox;
- const gpu::SyncToken sync_token = frame->mailbox_holder(0).sync_token;
+ std::unique_ptr<VideoFrameFuture> frame_future1 =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> frame1 = frame_future1->Release();
+ gpu::Mailbox mailbox = frame1->mailbox_holder(0).mailbox;
+ const gpu::SyncToken sync_token = frame1->mailbox_holder(0).sync_token;
EXPECT_EQ(3u, gles2_->gen_textures);
- // Allocate a second frame.
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2));
- RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame2.get());
+ std::unique_ptr<VideoFrameFuture> frame_future2 =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> frame2 = frame_future2->Release();
+
+ EXPECT_NE(frame1.get(), frame2.get());
EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox);
EXPECT_EQ(6u, gles2_->gen_textures);
- // Allow the frames to be recycled.
- frame = nullptr;
+ frame1 = nullptr;
frame2 = nullptr;
+ frame_future1 = nullptr;
+ frame_future2 = nullptr;
RunUntilIdle();
// Set all buffers to be in use, so the next hardware frame will require
// a new allocation.
mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(true);
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+ std::unique_ptr<VideoFrameFuture> new_frame_future =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> new_frame = new_frame_future->Release();
RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame.get());
EXPECT_EQ(9u, gles2_->gen_textures);
- EXPECT_NE(frame->mailbox_holder(0).mailbox, mailbox);
- EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token);
+ EXPECT_NE(new_frame->mailbox_holder(0).mailbox, mailbox);
+ EXPECT_NE(new_frame->mailbox_holder(0).sync_token, sync_token);
// Set the buffers no longer in use, so no new allocations will be made.
mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(false);
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2));
+ std::unique_ptr<VideoFrameFuture> new_frame_future2 =
+ CreateFrame(PIXEL_FORMAT_I420);
+ scoped_refptr<VideoFrame> new_frame2 = new_frame_future2->Release();
RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame2.get());
EXPECT_EQ(9u, gles2_->gen_textures);
- EXPECT_NE(frame->mailbox_holder(0).mailbox, mailbox);
- EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token);
+ EXPECT_EQ(new_frame2->mailbox_holder(0).mailbox, mailbox);
+ EXPECT_NE(new_frame2->mailbox_holder(0).sync_token, sync_token);
}
TEST_F(GpuMemoryBufferVideoFramePoolTest, DropResourceWhenSizeIsDifferent) {
- scoped_refptr<VideoFrame> frame;
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- CreateTestYUVVideoFrame(10),
- base::Bind(MaybeCreateHardwareFrameCallback, &frame));
- RunUntilIdle();
-
+ VideoPixelFormat format = PIXEL_FORMAT_I420;
+ std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format);
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
EXPECT_EQ(3u, gles2_->gen_textures);
+ // Clear frame reference to return the frame to the pool.
frame = nullptr;
+ frame_future = nullptr;
+
RunUntilIdle();
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- CreateTestYUVVideoFrame(4),
- base::Bind(MaybeCreateHardwareFrameCallback, &frame));
- RunUntilIdle();
+
+ std::unique_ptr<VideoFrameFuture> new_frame_future = CreateFrame(format, 32);
+ scoped_refptr<VideoFrame> new_frame = new_frame_future->Release();
EXPECT_EQ(6u, gles2_->gen_textures);
}
TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareUYUVFrame) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
- mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_UYVY);
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+ std::unique_ptr<VideoFrameFuture> frame_future =
+ CreateFrame(PIXEL_FORMAT_UYVY);
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
- RunUntilIdle();
-
- EXPECT_NE(software_frame.get(), frame.get());
EXPECT_EQ(1u, gles2_->gen_textures);
EXPECT_TRUE(frame->metadata()->IsTrue(
media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED));
}
TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareNV12Frame) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
- mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_NV12);
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+ std::unique_ptr<VideoFrameFuture> frame_future =
+ CreateFrame(PIXEL_FORMAT_NV12);
+ scoped_refptr<VideoFrame> frame = frame_future->Release();
RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame.get());
EXPECT_EQ(1u, gles2_->gen_textures);
EXPECT_TRUE(frame->metadata()->IsTrue(
media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED));
}
-// AllocateGpuMemoryBuffer can return null (e.g: when the GPU process is down).
-// This test checks that in that case we don't crash and still create the
-// textures.
+// CreateFrame can return null (e.g: when the GPU process is down).
TEST_F(GpuMemoryBufferVideoFramePoolTest, AllocateGpuMemoryBufferFail) {
- scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
- scoped_refptr<VideoFrame> frame;
mock_gpu_factories_->SetFailToAllocateGpuMemoryBufferForTesting(true);
- gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
- software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame));
+ std::unique_ptr<VideoFrameFuture> frame_future =
+ CreateFrame(PIXEL_FORMAT_I420);
+ EXPECT_EQ(nullptr, frame_future.get());
RunUntilIdle();
- EXPECT_NE(software_frame.get(), frame.get());
- EXPECT_EQ(3u, gles2_->gen_textures);
+ EXPECT_EQ(0u, gles2_->gen_textures);
}
} // namespace media
« no previous file with comments | « media/video/gpu_memory_buffer_video_frame_pool.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698