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

Side by Side Diff: content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc

Issue 1064963002: VideoCapture: add support for GpuMemoryBuffer allocation and lifetime mgmt in VideoCaptureBufferPool (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 // Unit test for VideoCaptureBufferPool. 5 // Unit test for VideoCaptureBufferPool.
6 6
7 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 7 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "cc/test/test_context_provider.h"
13 #include "cc/test/test_web_graphics_context_3d.h"
14 #include "content/browser/compositor/buffer_queue.h"
15 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
12 #include "content/browser/renderer_host/media/video_capture_controller.h" 16 #include "content/browser/renderer_host/media/video_capture_controller.h"
13 #include "media/base/video_frame.h" 17 #include "media/base/video_frame.h"
14 #include "media/base/video_util.h" 18 #include "media/base/video_util.h"
15 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
16 20
17 namespace content { 21 namespace content {
18 22
19 class VideoCaptureBufferPoolTest : public testing::Test { 23 static const media::VideoPixelFormat kCaptureFormats[] = {
24 media::PIXEL_FORMAT_I420,
25 media::PIXEL_FORMAT_TEXTURE,
26 media::PIXEL_FORMAT_GPUMEMORYBUFFER
27 };
28
29 class VideoCaptureBufferPoolTest
30 : public testing::TestWithParam<media::VideoPixelFormat> {
20 protected: 31 protected:
32 // A GpuMemoryBuffer Mock to provide a trivial RGBA buffer as Map() backing.
33 // We need to allocate on ctor and deallocate on dtor so that consecutive
34 // Map()-Unmap() cycles yield the same underlying data pointer.
35 class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer {
36 public:
37 explicit MockGpuMemoryBuffer(const gfx::Size& size)
38 : size_(size), data_(new uint8[size_.GetArea() * 4]), mapped_(false) {}
39 ~MockGpuMemoryBuffer() override { delete[] data_; }
40
41 bool Map(void** data) override {
42 EXPECT_EQ(mapped_, false);
43 mapped_ = true;
44 data[0] = static_cast<void*>(data_);
45 return true;
46 }
47 void Unmap() override {
48 EXPECT_EQ(mapped_, true);
49 mapped_ = false;
50 }
51 bool IsMapped() const override { return mapped_; }
52 Format GetFormat() const override { return BGRA_8888; }
53 void GetStride(uint32* stride) const override { return; }
54 gfx::GpuMemoryBufferHandle GetHandle() const override {
55 return gfx::GpuMemoryBufferHandle();
56 }
57 ClientBuffer AsClientBuffer() override { return nullptr; }
58
59 private:
60 const gfx::Size size_;
61 uint8* const data_;
62 bool mapped_;
63 };
64
65 // The next two classes are needed to replicate the GpuMemoryBuffer allocation
66 // on Browser side.
67 class StubBrowserGpuMemoryBufferManager
68 : public BrowserGpuMemoryBufferManager {
69 public:
70 StubBrowserGpuMemoryBufferManager()
71 : BrowserGpuMemoryBufferManager(nullptr, 1) {}
72
73 scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
74 const gfx::Size& size,
75 gfx::GpuMemoryBuffer::Format format,
76 gfx::GpuMemoryBuffer::Usage usage) override {
77 return make_scoped_ptr(new MockGpuMemoryBuffer(size));
78 }
79 };
80 class MockBufferQueue : public BufferQueue {
81 public:
82 MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
83 BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager,
84 unsigned int internalformat)
85 : BufferQueue(context_provider,
86 internalformat,
87 nullptr,
88 gpu_memory_buffer_manager,
89 1) {}
90 };
91
92 // This is a generic Buffer tracker
21 class Buffer { 93 class Buffer {
22 public: 94 public:
23 Buffer(const scoped_refptr<VideoCaptureBufferPool> pool, 95 Buffer(const scoped_refptr<VideoCaptureBufferPool> pool,
24 int id, 96 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle,
25 void* data, 97 int id)
26 size_t size) 98 : pool_(pool), id_(id), buffer_handle_(buffer_handle.Pass()) {}
27 : pool_(pool), id_(id), data_(data), size_(size) {}
28 ~Buffer() { pool_->RelinquishProducerReservation(id()); } 99 ~Buffer() { pool_->RelinquishProducerReservation(id()); }
29 int id() const { return id_; } 100 int id() const { return id_; }
30 void* data() const { return data_; } 101 scoped_ptr<media::DataHandle> GetDataHandle() {
31 size_t size() const { return size_; } 102 return buffer_handle_->GetDataHandle().Pass();
103 }
104 size_t size() { return buffer_handle_->size(); }
32 105
33 private: 106 private:
34 const scoped_refptr<VideoCaptureBufferPool> pool_; 107 const scoped_refptr<VideoCaptureBufferPool> pool_;
35 const int id_; 108 const int id_;
36 void* const data_; 109 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
37 const size_t size_; 110 };
38 }; 111
39 VideoCaptureBufferPoolTest() 112 VideoCaptureBufferPoolTest()
40 : expected_dropped_id_(0), 113 : expected_dropped_id_(0),
41 pool_(new VideoCaptureBufferPool(3)) {} 114 pool_(new VideoCaptureBufferPool(3)) {}
42 115
116 void SetUp() override {
117 scoped_refptr<cc::TestContextProvider> context_provider =
118 cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
119 context_provider->BindToCurrentThread();
120 gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager);
121 output_surface_.reset(new MockBufferQueue(
122 context_provider, gpu_memory_buffer_manager_.get(), GL_RGBA));
123 output_surface_->Initialize();
124 }
125
43 void ExpectDroppedId(int expected_dropped_id) { 126 void ExpectDroppedId(int expected_dropped_id) {
44 expected_dropped_id_ = expected_dropped_id; 127 expected_dropped_id_ = expected_dropped_id;
45 } 128 }
46 129
47 scoped_ptr<Buffer> ReserveI420Buffer(const gfx::Size& dimensions) { 130 scoped_ptr<Buffer> ReserveBuffer(const gfx::Size& dimensions,
48 // To verify that ReserveI420Buffer always sets |buffer_id_to_drop|, 131 media::VideoPixelFormat pixel_format) {
132 // To verify that ReserveBuffer always sets |buffer_id_to_drop|,
49 // initialize it to something different than the expected value. 133 // initialize it to something different than the expected value.
50 int buffer_id_to_drop = ~expected_dropped_id_; 134 int buffer_id_to_drop = ~expected_dropped_id_;
51 int buffer_id = pool_->ReserveForProducer(media::PIXEL_FORMAT_I420, 135 DVLOG(1) << media::VideoCaptureFormat::PixelFormatToString(pixel_format)
52 dimensions, &buffer_id_to_drop); 136 << " " << dimensions.ToString();
137 int buffer_id =
138 pool_->ReserveForProducer(pixel_format, dimensions, &buffer_id_to_drop);
53 if (buffer_id == VideoCaptureBufferPool::kInvalidId) 139 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
54 return scoped_ptr<Buffer>(); 140 return scoped_ptr<Buffer>();
55
56 void* memory;
57 size_t size;
58 pool_->GetBufferInfo(buffer_id, &memory, &size);
59 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop); 141 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);
60 return scoped_ptr<Buffer>(new Buffer(pool_, buffer_id, memory, size)); 142
143 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle =
144 pool_->GetBufferHandle(buffer_id);
145 return scoped_ptr<Buffer>(
146 new Buffer(pool_, buffer_handle.Pass(), buffer_id));
61 } 147 }
62 148
63 int expected_dropped_id_; 149 int expected_dropped_id_;
64 scoped_refptr<VideoCaptureBufferPool> pool_; 150 scoped_refptr<VideoCaptureBufferPool> pool_;
65 151
66 private: 152 private:
153 scoped_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
154 scoped_ptr<MockBufferQueue> output_surface_;
155
67 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest); 156 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest);
68 }; 157 };
69 158
70 TEST_F(VideoCaptureBufferPoolTest, BufferPool) { 159 TEST_P(VideoCaptureBufferPoolTest, BufferPool) {
71 const gfx::Size size_lo = gfx::Size(640, 480); 160 const gfx::Size size_lo = gfx::Size(10, 10);
72 const gfx::Size size_hi = gfx::Size(1024, 768); 161 const gfx::Size size_hi = gfx::Size(21, 33);
73 scoped_refptr<media::VideoFrame> non_pool_frame = 162 const media::VideoCaptureFormat format_lo(size_lo, 0.0, GetParam());
74 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo, 163 const media::VideoCaptureFormat format_hi(size_hi, 0.0, GetParam());
75 gfx::Rect(size_lo), size_lo,
76 base::TimeDelta());
77 164
78 // Reallocation won't happen for the first part of the test. 165 // Reallocation won't happen for the first part of the test.
79 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 166 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
80 167
81 scoped_ptr<Buffer> buffer1 = ReserveI420Buffer(size_lo); 168 scoped_ptr<Buffer> buffer1 = ReserveBuffer(size_lo, GetParam());
82 ASSERT_TRUE(NULL != buffer1.get()); 169 ASSERT_NE(nullptr, buffer1.get());
83 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo), 170 ASSERT_LE(format_lo.ImageAllocationSize(), buffer1->size());
84 buffer1->size()); 171 scoped_ptr<Buffer> buffer2 = ReserveBuffer(size_lo, GetParam());
85 scoped_ptr<Buffer> buffer2 = ReserveI420Buffer(size_lo); 172 ASSERT_NE(nullptr, buffer2.get());
86 ASSERT_TRUE(NULL != buffer2.get()); 173 ASSERT_LE(format_lo.ImageAllocationSize(), buffer2->size());
87 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo), 174 scoped_ptr<Buffer> buffer3 = ReserveBuffer(size_lo, GetParam());
88 buffer2->size()); 175 ASSERT_NE(nullptr, buffer3.get());
89 scoped_ptr<Buffer> buffer3 = ReserveI420Buffer(size_lo); 176 ASSERT_LE(format_lo.ImageAllocationSize(), buffer3->size());
90 ASSERT_TRUE(NULL != buffer3.get()); 177
91 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo), 178 // Texture backed Frames cannot be manipulated via mapping.
92 buffer3->size()); 179 if (GetParam() != media::PIXEL_FORMAT_TEXTURE) {
93 180 ASSERT_NE(nullptr, buffer1->GetDataHandle()->data());
181 ASSERT_NE(nullptr, buffer2->GetDataHandle()->data());
182 ASSERT_NE(nullptr, buffer3->GetDataHandle()->data());
183
184 }
94 // Touch the memory. 185 // Touch the memory.
95 memset(buffer1->data(), 0x11, buffer1->size()); 186 if (buffer1->GetDataHandle()->data() != nullptr)
96 memset(buffer2->data(), 0x44, buffer2->size()); 187 memset(buffer1->GetDataHandle()->data(), 0x11, buffer1->size());
97 memset(buffer3->data(), 0x77, buffer3->size()); 188 if (buffer2->GetDataHandle()->data() != nullptr)
189 memset(buffer2->GetDataHandle()->data(), 0x44, buffer2->size());
190 if (buffer3->GetDataHandle()->data() != nullptr)
191 memset(buffer3->GetDataHandle()->data(), 0x77, buffer3->size());
98 192
99 // Fourth buffer should fail. 193 // Fourth buffer should fail.
100 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 194 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
101 195
102 // Release 1st buffer and retry; this should succeed. 196 // Release 1st buffer and retry; this should succeed.
103 buffer1.reset(); 197 buffer1.reset();
104 scoped_ptr<Buffer> buffer4 = ReserveI420Buffer(size_lo); 198 scoped_ptr<Buffer> buffer4 = ReserveBuffer(size_lo, GetParam());
105 ASSERT_TRUE(NULL != buffer4.get()); 199 ASSERT_NE(nullptr, buffer4.get());
106 200
107 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 201 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
108 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty"; 202 ASSERT_FALSE(ReserveBuffer(size_hi, GetParam())) << "Pool should be empty";
109 203
110 // Validate the IDs 204 // Validate the IDs
111 int buffer_id2 = buffer2->id(); 205 int buffer_id2 = buffer2->id();
112 ASSERT_EQ(1, buffer_id2); 206 ASSERT_EQ(1, buffer_id2);
113 int buffer_id3 = buffer3->id(); 207 const int buffer_id3 = buffer3->id();
114 ASSERT_EQ(2, buffer_id3); 208 ASSERT_EQ(2, buffer_id3);
115 void* const memory_pointer3 = buffer3->data(); 209 const int buffer_id4 = buffer4->id();
116 int buffer_id4 = buffer4->id();
117 ASSERT_EQ(0, buffer_id4); 210 ASSERT_EQ(0, buffer_id4);
211 void* const memory_pointer3 = buffer3->GetDataHandle()->data();
118 212
119 // Deliver a buffer. 213 // Deliver a buffer.
120 pool_->HoldForConsumers(buffer_id3, 2); 214 pool_->HoldForConsumers(buffer_id3, 2);
121 215
122 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 216 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
123 217
124 buffer3.reset(); // Old producer releases buffer. Should be a noop. 218 buffer3.reset(); // Old producer releases buffer. Should be a noop.
125 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 219 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
126 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty"; 220 ASSERT_FALSE(ReserveBuffer(size_hi, GetParam())) << "Pool should be empty";
127 221
128 buffer2.reset(); // Active producer releases buffer. Should free a buffer. 222 buffer2.reset(); // Active producer releases buffer. Should free a buffer.
129 223
130 buffer1 = ReserveI420Buffer(size_lo); 224 buffer1 = ReserveBuffer(size_lo, GetParam());
131 ASSERT_TRUE(NULL != buffer1.get()); 225 ASSERT_NE(nullptr, buffer1.get());
132 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 226 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
133 227
134 // First consumer finishes. 228 // First consumer finishes.
135 pool_->RelinquishConsumerHold(buffer_id3, 1); 229 pool_->RelinquishConsumerHold(buffer_id3, 1);
136 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 230 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
137 231
138 // Second consumer finishes. This should free that buffer. 232 // Second consumer finishes. This should free that buffer.
139 pool_->RelinquishConsumerHold(buffer_id3, 1); 233 pool_->RelinquishConsumerHold(buffer_id3, 1);
140 buffer3 = ReserveI420Buffer(size_lo); 234 buffer3 = ReserveBuffer(size_lo, GetParam());
141 ASSERT_TRUE(NULL != buffer3.get()); 235 ASSERT_NE(nullptr, buffer3.get());
142 ASSERT_EQ(buffer_id3, buffer3->id()) << "Buffer ID should be reused."; 236 ASSERT_EQ(buffer_id3, buffer3->id()) << "Buffer ID should be reused.";
143 ASSERT_EQ(memory_pointer3, buffer3->data()); 237 ASSERT_EQ(memory_pointer3, buffer3->GetDataHandle()->data());
144 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 238 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
145 239
146 // Now deliver & consume buffer1, but don't release the buffer. 240 // Now deliver & consume buffer1, but don't release the buffer.
147 int buffer_id1 = buffer1->id(); 241 int buffer_id1 = buffer1->id();
148 ASSERT_EQ(1, buffer_id1); 242 ASSERT_EQ(1, buffer_id1);
149 pool_->HoldForConsumers(buffer_id1, 5); 243 pool_->HoldForConsumers(buffer_id1, 5);
150 pool_->RelinquishConsumerHold(buffer_id1, 5); 244 pool_->RelinquishConsumerHold(buffer_id1, 5);
151 245
152 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot 246 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot
153 // be re-allocated to the producer, because |buffer1| still references it. But 247 // be re-allocated to the producer, because |buffer1| still references it. But
154 // when |buffer1| goes away, we should be able to re-reserve the buffer (and 248 // when |buffer1| goes away, we should be able to re-reserve the buffer (and
155 // the ID ought to be the same). 249 // the ID ought to be the same).
156 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 250 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
157 buffer1.reset(); // Should free the buffer. 251 buffer1.reset(); // Should free the buffer.
158 buffer2 = ReserveI420Buffer(size_lo); 252 buffer2 = ReserveBuffer(size_lo, GetParam());
159 ASSERT_TRUE(NULL != buffer2.get()); 253 ASSERT_NE(nullptr, buffer2.get());
160 ASSERT_EQ(buffer_id1, buffer2->id()); 254 ASSERT_EQ(buffer_id1, buffer2->id());
161 buffer_id2 = buffer_id1; 255 buffer_id2 = buffer_id1;
162 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty"; 256 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
163 257
164 // Now try reallocation with different resolutions. We expect reallocation 258 // Now try reallocation with different resolutions. We expect reallocation
165 // to occur only when the old buffer is too small. 259 // to occur only when the old buffer is too small.
166 buffer2.reset(); 260 buffer2.reset();
167 ExpectDroppedId(buffer_id2); 261 ExpectDroppedId(buffer_id2);
168 buffer2 = ReserveI420Buffer(size_hi); 262 buffer2 = ReserveBuffer(size_hi, GetParam());
169 ASSERT_TRUE(NULL != buffer2.get()); 263 ASSERT_NE(nullptr, buffer2.get());
170 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_hi), 264 ASSERT_LE(format_hi.ImageAllocationSize(), buffer2->size());
171 buffer2->size());
172 ASSERT_EQ(3, buffer2->id()); 265 ASSERT_EQ(3, buffer2->id());
173 void* const memory_pointer_hi = buffer2->data(); 266 void* const memory_pointer_hi = buffer2->GetDataHandle()->data();
174 buffer2.reset(); // Frees it. 267 buffer2.reset(); // Frees it.
175 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 268 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
176 buffer2 = ReserveI420Buffer(size_lo); 269 buffer2 = ReserveBuffer(size_lo, GetParam());
177 void* const memory_pointer_lo = buffer2->data(); 270 void* const memory_pointer_lo = buffer2->GetDataHandle()->data();
178 ASSERT_EQ(memory_pointer_hi, memory_pointer_lo) 271 ASSERT_EQ(memory_pointer_hi, memory_pointer_lo)
179 << "Decrease in resolution should not reallocate buffer"; 272 << "Decrease in resolution should not reallocate buffer";
180 ASSERT_TRUE(NULL != buffer2.get()); 273 ASSERT_NE(nullptr, buffer2.get());
181 ASSERT_EQ(3, buffer2->id()); 274 ASSERT_EQ(3, buffer2->id());
182 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo), 275 ASSERT_LE(format_lo.ImageAllocationSize(), buffer2->size());
183 buffer2->size()); 276 ASSERT_FALSE(ReserveBuffer(size_lo, GetParam())) << "Pool should be empty";
184 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
185 277
186 // Tear down the pool_, writing into the buffers. The buffer should preserve 278 // Tear down the pool_, writing into the buffers. The buffer should preserve
187 // the lifetime of the underlying memory. 279 // the lifetime of the underlying memory.
188 buffer3.reset(); 280 buffer3.reset();
189 pool_ = NULL; 281 pool_ = NULL;
190 282
191 // Touch the memory. 283 // Touch the memory.
192 memset(buffer2->data(), 0x22, buffer2->size()); 284 if (buffer2->GetDataHandle()->data() != nullptr)
193 memset(buffer4->data(), 0x55, buffer4->size()); 285 memset(buffer2->GetDataHandle()->data(), 0x22, buffer2->size());
194 286 if (buffer4->GetDataHandle()->data() != nullptr)
287 memset(buffer4->GetDataHandle()->data(), 0x55, buffer4->size());
195 buffer2.reset(); 288 buffer2.reset();
196 289
197 memset(buffer4->data(), 0x77, buffer4->size()); 290 if (buffer4->GetDataHandle()->data() != nullptr)
291 memset(buffer4->GetDataHandle()->data(), 0x77, buffer4->size());
198 buffer4.reset(); 292 buffer4.reset();
199 } 293 }
200 294
295 INSTANTIATE_TEST_CASE_P(,
296 VideoCaptureBufferPoolTest,
297 testing::ValuesIn(kCaptureFormats));
298
201 } // namespace content 299 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698