[M120 Migration][MM][CAPI] Fix the logic for media using capi player.
[platform/framework/web/chromium-efl.git] / media / mojo / services / mojo_cdm_allocator_unittest.cc
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <cstring>
9
10 #include "base/memory/shared_memory_mapping.h"
11 #include "base/memory/unsafe_shared_memory_region.h"
12 #include "media/base/video_frame.h"
13 #include "media/cdm/api/content_decryption_module.h"
14 #include "media/cdm/cdm_helpers.h"
15 #include "media/mojo/services/mojo_cdm_allocator.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/gfx/geometry/size.h"
18
19 namespace media {
20
21 class MojoCdmAllocatorTest : public testing::Test {
22  public:
23   MojoCdmAllocatorTest() = default;
24
25   MojoCdmAllocatorTest(const MojoCdmAllocatorTest&) = delete;
26   MojoCdmAllocatorTest& operator=(const MojoCdmAllocatorTest&) = delete;
27
28   ~MojoCdmAllocatorTest() override = default;
29
30  protected:
31   cdm::Buffer* CreateCdmBuffer(size_t capacity) {
32     return allocator_.CreateCdmBuffer(capacity);
33   }
34
35   std::unique_ptr<VideoFrameImpl> CreateCdmVideoFrame() {
36     return allocator_.CreateCdmVideoFrame();
37   }
38
39   const base::MappedReadOnlyRegion& GetRegion(cdm::Buffer* buffer) {
40     return allocator_.GetRegionForTesting(buffer);
41   }
42
43   size_t GetAvailableRegionCount() {
44     return allocator_.GetAvailableRegionCountForTesting();
45   }
46
47  private:
48   MojoCdmAllocator allocator_;
49 };
50
51 TEST_F(MojoCdmAllocatorTest, CreateCdmBuffer) {
52   cdm::Buffer* buffer = CreateCdmBuffer(100);
53   EXPECT_GE(buffer->Capacity(), 100u);
54   buffer->SetSize(50);
55   EXPECT_EQ(50u, buffer->Size());
56   buffer->Destroy();
57 }
58
59 TEST_F(MojoCdmAllocatorTest, ReuseCdmBuffer) {
60   const size_t kRandomDataSize = 46;
61
62   const char kTestData[] = "reduce reuse recycle";
63
64   // Create a small buffer.
65   cdm::Buffer* buffer = CreateCdmBuffer(kRandomDataSize);
66   {
67     // Create a mapping and write some test data.
68     auto& mapping = GetRegion(buffer).mapping;
69     // Note: deliberately using sizeof() to include the null terminator.
70     memcpy(mapping.memory(), kTestData, sizeof(kTestData));
71   }
72   buffer->Destroy();
73
74   // Now allocate a new buffer of the same size, it should reuse the one
75   // just freed.
76   cdm::Buffer* new_buffer = CreateCdmBuffer(kRandomDataSize);
77   {
78     auto& mapping = GetRegion(new_buffer).mapping;
79     // Check that the test data that was written there is still there as a proxy
80     // signal for checking that the shmem region is reused.
81     EXPECT_STREQ(kTestData, mapping.GetMemoryAs<char>());
82   }
83   new_buffer->Destroy();
84 }
85
86 TEST_F(MojoCdmAllocatorTest, MaxFreeBuffers) {
87   const size_t kMaxExpectedFreeBuffers = 3;
88   size_t buffer_size = 0;
89   const size_t kBufferSizeIncrease = 1000;
90   std::vector<cdm::Buffer*> buffers;
91
92   // Allocate and destroy 10 buffers in increasing size (to avoid buffer reuse).
93   // Eventually allocating a new buffer will free the smallest free buffer, so
94   // the number of free buffers will be capped at |kMaxExpectedFreeBuffers|.
95   for (int i = 0; i < 10; ++i) {
96     buffer_size += kBufferSizeIncrease;
97     cdm::Buffer* buffer = CreateCdmBuffer(buffer_size);
98     buffer->Destroy();
99     EXPECT_LE(GetAvailableRegionCount(), kMaxExpectedFreeBuffers);
100   }
101 }
102
103 TEST_F(MojoCdmAllocatorTest, CreateCdmVideoFrame) {
104   const int kWidth = 16;
105   const int kHeight = 9;
106   const VideoPixelFormat kFormat = PIXEL_FORMAT_I420;
107   const gfx::Size kSize(kWidth, kHeight);
108   const size_t kBufferSize = VideoFrame::AllocationSize(kFormat, kSize);
109
110   // Create a VideoFrameImpl and initialize it.
111   std::unique_ptr<VideoFrameImpl> video_frame = CreateCdmVideoFrame();
112   video_frame->SetFormat(cdm::kI420);
113   video_frame->SetSize({kWidth, kHeight});
114   video_frame->SetStride(
115       cdm::kYPlane, static_cast<uint32_t>(
116                         VideoFrame::RowBytes(cdm::kYPlane, kFormat, kWidth)));
117   video_frame->SetStride(
118       cdm::kUPlane, static_cast<uint32_t>(
119                         VideoFrame::RowBytes(cdm::kUPlane, kFormat, kWidth)));
120   video_frame->SetStride(
121       cdm::kVPlane, static_cast<uint32_t>(
122                         VideoFrame::RowBytes(cdm::kVPlane, kFormat, kWidth)));
123   EXPECT_EQ(nullptr, video_frame->FrameBuffer());
124
125   // Now create a buffer to hold the frame and assign it to the VideoFrameImpl.
126   cdm::Buffer* buffer = CreateCdmBuffer(kBufferSize);
127   EXPECT_EQ(0u, GetAvailableRegionCount());
128   buffer->SetSize(static_cast<uint32_t>(kBufferSize));
129   video_frame->SetFrameBuffer(buffer);
130   EXPECT_NE(nullptr, video_frame->FrameBuffer());
131
132   // Transform it into a VideoFrame and make sure the buffer is no longer owned.
133   scoped_refptr<VideoFrame> frame = video_frame->TransformToVideoFrame(kSize);
134   EXPECT_EQ(nullptr, video_frame->FrameBuffer());
135   EXPECT_EQ(0u, GetAvailableRegionCount());
136   video_frame.reset();
137
138   // Check that the buffer is still in use. It will be freed when |frame|
139   // is destroyed.
140   EXPECT_EQ(0u, GetAvailableRegionCount());
141   frame = nullptr;
142
143   // Check that the buffer is now in the free list.
144   EXPECT_EQ(1u, GetAvailableRegionCount());
145 }
146
147 }  // namespace media