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

Side by Side Diff: media/gpu/android_video_decode_accelerator_unittest.cc

Issue 2813303003: Add AndroidVideoSurfaceChooser to manage overlays. (Closed)
Patch Set: cl feedback. Created 3 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 #include "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/android/jni_android.h" 11 #include "base/android/jni_android.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h" 17 #include "base/run_loop.h"
16 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
17 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" 19 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
18 #include "media/base/android/media_codec_util.h" 20 #include "media/base/android/media_codec_util.h"
19 #include "media/base/android/media_jni_registrar.h" 21 #include "media/base/android/media_jni_registrar.h"
22 #include "media/base/android/mock_android_overlay.h"
23 #include "media/base/android/mock_media_codec_bridge.h"
20 #include "media/gpu/android_video_decode_accelerator.h" 24 #include "media/gpu/android_video_decode_accelerator.h"
21 #include "media/gpu/avda_codec_allocator.h" 25 #include "media/gpu/avda_codec_allocator.h"
26 #include "media/gpu/avda_overlay_helper.h"
22 #include "media/video/picture.h" 27 #include "media/video/picture.h"
23 #include "media/video/video_decode_accelerator.h" 28 #include "media/video/video_decode_accelerator.h"
24 #include "testing/gmock/include/gmock/gmock.h" 29 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "ui/gl/android/surface_texture.h"
26 #include "ui/gl/gl_context.h" 32 #include "ui/gl/gl_context.h"
27 #include "ui/gl/gl_surface.h" 33 #include "ui/gl/gl_surface.h"
28 #include "ui/gl/init/gl_factory.h" 34 #include "ui/gl/init/gl_factory.h"
29 35
30 using ::testing::_; 36 using ::testing::_;
31 using ::testing::NiceMock; 37 using ::testing::NiceMock;
38 using ::testing::NotNull;
39 using ::testing::Return;
40 using ::testing::StrictMock;
32 41
33 namespace media { 42 namespace media {
34 namespace { 43 namespace {
35 44
36 #define SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE() \ 45 #define SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE() \
37 do { \ 46 do { \
38 if (!MediaCodecUtil::IsMediaCodecAvailable()) \ 47 if (!MediaCodecUtil::IsMediaCodecAvailable()) \
39 return; \ 48 return; \
40 } while (false) 49 } while (false)
41 50
42 bool MakeContextCurrent() { 51 bool MakeContextCurrent() {
43 return true; 52 return true;
44 } 53 }
45 54
46 base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder( 55 base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder(
47 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) { 56 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) {
48 return decoder; 57 return decoder;
49 } 58 }
50 59
51 ACTION(PostNullCodec) {
52 base::ThreadTaskRunnerHandle::Get()->PostTask(
53 FROM_HERE, base::Bind(&media::AVDACodecAllocatorClient::OnCodecConfigured,
54 arg0, nullptr));
55 }
56
57 } // namespace 60 } // namespace
58 61
59 class MockVDAClient : public VideoDecodeAccelerator::Client {
60 public:
61 MOCK_METHOD1(NotifyInitializationComplete, void(bool));
62 MOCK_METHOD5(
63 ProvidePictureBuffers,
64 void(uint32_t, VideoPixelFormat, uint32_t, const gfx::Size&, uint32_t));
65 MOCK_METHOD1(DismissPictureBuffer, void(int32_t));
66 MOCK_METHOD1(PictureReady, void(const Picture&));
67 MOCK_METHOD1(NotifyEndOfBitstreamBuffer, void(int32_t));
68 MOCK_METHOD0(NotifyFlushDone, void());
69 MOCK_METHOD0(NotifyResetDone, void());
70 MOCK_METHOD1(NotifyError, void(VideoDecodeAccelerator::Error));
71 };
72
73 class MockCodecAllocator : public AVDACodecAllocator {
74 public:
75 MOCK_METHOD2(CreateMediaCodecAsync,
76 void(base::WeakPtr<AVDACodecAllocatorClient>,
77 scoped_refptr<CodecConfig>));
78 };
79
80 class AndroidVideoDecodeAcceleratorTest : public testing::Test { 62 class AndroidVideoDecodeAcceleratorTest : public testing::Test {
81 public: 63 public:
64 class MockVDAClient : public VideoDecodeAccelerator::Client {
65 public:
66 MockVDAClient() {}
67
68 MOCK_METHOD1(NotifyInitializationComplete, void(bool));
69 MOCK_METHOD5(
70 ProvidePictureBuffers,
71 void(uint32_t, VideoPixelFormat, uint32_t, const gfx::Size&, uint32_t));
72 MOCK_METHOD1(DismissPictureBuffer, void(int32_t));
73 MOCK_METHOD1(PictureReady, void(const Picture&));
74 MOCK_METHOD1(NotifyEndOfBitstreamBuffer, void(int32_t));
75 MOCK_METHOD0(NotifyFlushDone, void());
76 MOCK_METHOD0(NotifyResetDone, void());
77 MOCK_METHOD1(NotifyError, void(VideoDecodeAccelerator::Error));
78
79 private:
80 DISALLOW_COPY_AND_ASSIGN(MockVDAClient);
81 };
82
83 // Codec allocator that lets you count calls on Mock* methods, and also
84 // lets you answer the codec.
85 class FakeCodecAllocator : public StrictMock<AVDACodecAllocator> {
86 public:
87 FakeCodecAllocator() {}
88
89 // These are called with some parameters of the codec config by our
90 // implementatin of their respective functions. This allows tests to set
91 // expectations on them.
92 MOCK_METHOD2(MockCreateMediaCodecSync,
93 void(AndroidOverlay*, gl::SurfaceTexture*));
94 MOCK_METHOD2(MockCreateMediaCodecAsync,
95 void(AndroidOverlay*, gl::SurfaceTexture*));
96
97 // Note that this doesn't exactly match the signature, since unique_ptr
98 // doesn't work. plus, we expand |surface_bundle| a bit to make it more
99 // convenient to set expectations.
100 MOCK_METHOD3(MockReleaseMediaCodec,
101 void(MediaCodecBridge*, AndroidOverlay*, gl::SurfaceTexture*));
102
103 std::unique_ptr<MediaCodecBridge> CreateMediaCodecSync(
104 scoped_refptr<CodecConfig> codec_config) override {
105 MockCreateMediaCodecSync(
106 codec_config->surface_bundle->overlay.get(),
107 codec_config->surface_bundle->surface_texture.get());
108
109 CopyCodecAllocParams(codec_config);
110
111 std::unique_ptr<MockMediaCodecBridge> codec;
112 if (allow_sync_creation)
113 codec = base::MakeUnique<MockMediaCodecBridge>();
114
115 if (codec)
116 most_recent_codec_ = codec->GetWeakPtr();
117 else
118 most_recent_codec_ = nullptr;
119
120 return std::move(codec);
121 }
122
123 void CreateMediaCodecAsync(base::WeakPtr<AVDACodecAllocatorClient> client,
124 scoped_refptr<CodecConfig> config) override {
125 // Clear |most_recent_codec_| until somebody calls Provide*CodecAsync().
126 most_recent_codec_ = nullptr;
127 CopyCodecAllocParams(config);
128 client_ = client;
129
130 MockCreateMediaCodecAsync(most_recent_overlay(),
131 most_recent_surface_texture());
132 }
133
134 void ReleaseMediaCodec(
135 std::unique_ptr<MediaCodecBridge> media_codec,
136 TaskType task_type,
137 const scoped_refptr<AVDASurfaceBundle>& surface_bundle) override {
138 MockReleaseMediaCodec(media_codec.get(), surface_bundle->overlay.get(),
139 surface_bundle->surface_texture.get());
140 }
141
142 // Provide AVDA with a mock codec.
143 void ProvideMockCodecAsync() {
144 // If AVDA hasn't requested a codec, then get mad.
145 ASSERT_TRUE(client_);
146 if (!client_)
147 return;
148
149 std::unique_ptr<MockMediaCodecBridge> codec =
150 base::MakeUnique<MockMediaCodecBridge>();
151 most_recent_codec_ = codec->GetWeakPtr();
152 client_->OnCodecConfigured(std::move(codec));
153 }
154
155 // Provide AVDA will a null codec.
156 void ProvideNullCodecAsync() {
157 // If AVDA hasn't requested a codec, then get mad.
158 ASSERT_TRUE(client_);
159 if (!client_)
160 return;
161
162 most_recent_codec_ = nullptr;
163 client_->OnCodecConfigured(nullptr);
164 }
165
166 // Return the most recent bundle that we've received for codec allocation.
167 scoped_refptr<AVDASurfaceBundle> most_recent_bundle() {
168 return most_recent_bundle_;
169 }
170
171 // Return the most recent codec that we provided, or null if it has been
172 // freed already.
173 MockMediaCodecBridge* most_recent_codec() {
174 return most_recent_codec_.get();
175 }
176
177 // Return the most recent overlay / etc. that we were given during codec
178 // allocation (sync or async).
179 AndroidOverlay* most_recent_overlay() { return most_recent_overlay_; }
180 gl::SurfaceTexture* most_recent_surface_texture() {
181 return most_recent_surface_texture_;
182 }
183
184 // Most recent codec that we've created via CreateMockCodec, since we have
185 // to assign ownership.
186 base::WeakPtr<MockMediaCodecBridge> most_recent_codec_;
187
188 // Most recent surface bundle that we've gotten during codec allocation.
189 // This should be the same as |config_->surface_bundle| initially, but AVDA
190 // might change it.
191 scoped_refptr<AVDASurfaceBundle> most_recent_bundle_;
192
193 // Most recent overlay provided during codec allocation.
194 AndroidOverlay* most_recent_overlay_ = nullptr;
195
196 // Most recent surface texture provided during codec allocation.
197 gl::SurfaceTexture* most_recent_surface_texture_ = nullptr;
198
199 // Should a call to CreateMediaCodecSync succeed?
200 bool allow_sync_creation = true;
201
202 private:
203 // Copy |config| and all of the parameters we care about. We don't leave
204 // them all in config, since AVDA could change them at any time.
205 void CopyCodecAllocParams(scoped_refptr<CodecConfig> config) {
206 config_ = config;
207 most_recent_bundle_ = config->surface_bundle;
208 most_recent_overlay_ = config->surface_bundle->overlay.get();
209
210 most_recent_surface_texture_ =
211 config->surface_bundle->surface_texture.get();
212 }
213
214 base::WeakPtr<AVDACodecAllocatorClient> client_;
215 scoped_refptr<CodecConfig> config_;
216
217 DISALLOW_COPY_AND_ASSIGN(FakeCodecAllocator);
218 };
219
220 // Overlay helper that calls mocked functions to allow counting calls, but
221 // also records arguments. Note that gmock can't mock out unique_ptrs
222 // anyway, so we can't mock AVDAOverlayHelper directly.
223 class FakeOverlayHelper : public StrictMock<AVDAOverlayHelper> {
224 public:
225 FakeOverlayHelper() : weak_factory_(this) {}
226
227 // These are called by the real functions. You may set expectations on
228 // them if you like.
229 MOCK_METHOD0(MockStartup, void());
230 MOCK_METHOD0(MockOnOverlayFactory, void());
231
232 base::WeakPtr<FakeOverlayHelper> GetWeakPtr() {
233 return weak_factory_.GetWeakPtr();
234 }
235
236 void Startup(
237 const UseOverlayCB& use_overlay_cb,
238 const UseSurfaceTextureCB& use_surface_texture_cb,
239 const StopUsingOverlayImmediatelyCB& stop_immediately_cb,
240 std::unique_ptr<AndroidOverlayFactory> initial_factory) override {
241 MockStartup();
242
243 factory_ = std::move(initial_factory);
244 use_overlay_cb_ = use_overlay_cb;
245 use_surface_texture_cb_ = use_surface_texture_cb;
246 stop_immediately_cb_ = stop_immediately_cb;
247 }
248
249 void OnOverlayFactory(
250 std::unique_ptr<AndroidOverlayFactory> factory) override {
251 MockOnOverlayFactory();
252 factory_ = std::move(factory);
253 }
254
255 // Notify AVDA to use a surface texture.
256 void ProvideSurfaceTexture() {
257 use_surface_texture_cb_.Run();
258 base::RunLoop().RunUntilIdle();
259 }
260
261 void ProvideOverlay(std::unique_ptr<AndroidOverlay> overlay) {
262 use_overlay_cb_.Run(std::move(overlay));
263 base::RunLoop().RunUntilIdle();
264 }
265
266 void StopImmediately(AndroidOverlay* overlay) {
267 stop_immediately_cb_.Run(overlay);
268 base::RunLoop().RunUntilIdle();
269 }
270
271 UseOverlayCB use_overlay_cb_;
272 UseSurfaceTextureCB use_surface_texture_cb_;
273 StopUsingOverlayImmediatelyCB stop_immediately_cb_;
274
275 std::unique_ptr<AndroidOverlayFactory> factory_;
276
277 base::WeakPtrFactory<FakeOverlayHelper> weak_factory_;
278
279 private:
280 DISALLOW_COPY_AND_ASSIGN(FakeOverlayHelper);
281 };
282
283 // We pick this profile since it's always supported.
284 AndroidVideoDecodeAcceleratorTest() : config_(H264PROFILE_BASELINE) {}
285
82 ~AndroidVideoDecodeAcceleratorTest() override {} 286 ~AndroidVideoDecodeAcceleratorTest() override {}
83 287
84 void SetUp() override { 288 void SetUp() override {
85 JNIEnv* env = base::android::AttachCurrentThread(); 289 JNIEnv* env = base::android::AttachCurrentThread();
86 RegisterJni(env); 290 RegisterJni(env);
87 291
292 main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
293
88 gl::init::ShutdownGL(); 294 gl::init::ShutdownGL();
89 ASSERT_TRUE(gl::init::InitializeGLOneOff()); 295 ASSERT_TRUE(gl::init::InitializeGLOneOff());
90 surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size(16, 16)); 296 surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size(16, 16));
91 context_ = gl::init::CreateGLContext(nullptr, surface_.get(), 297 context_ = gl::init::CreateGLContext(nullptr, surface_.get(),
92 gl::GLContextAttribs()); 298 gl::GLContextAttribs());
93 context_->MakeCurrent(surface_.get()); 299 context_->MakeCurrent(surface_.get());
94 300
95 vda_.reset(new AndroidVideoDecodeAccelerator( 301 helper_that_is_usually_null_ = base::MakeUnique<FakeOverlayHelper>();
96 &codec_allocator_, base::Bind(&MakeContextCurrent), 302 helper_ = helper_that_is_usually_null_->GetWeakPtr();
97 base::Bind(&GetGLES2Decoder, gl_decoder_.AsWeakPtr()))); 303
304 platform_config_.sdk_int = base::android::SDK_VERSION_MARSHMALLOW;
305 platform_config_.allow_setsurface = true;
306 platform_config_.force_deferred_surface_creation = false;
307
308 // By default, allow deferred init.
309 config_.is_deferred_initialization_allowed = true;
310 }
311
312 // Create and initialize AVDA with |config_|, and return the result.
313 bool InitializeAVDA() {
314 // Because VDA has a custom deleter, we must assign it to |vda_| carefully.
315 AndroidVideoDecodeAccelerator* avda = new AndroidVideoDecodeAccelerator(
316 &codec_allocator_, std::move(helper_that_is_usually_null_),
317 base::Bind(&MakeContextCurrent),
318 base::Bind(&GetGLES2Decoder, gl_decoder_.AsWeakPtr()),
319 &platform_config_);
320 avda_ = avda->GetWeakPtr();
321 vda_.reset(avda);
322
323 bool result = vda_->Initialize(config_, &client_);
324 base::RunLoop().RunUntilIdle();
325 return result;
326 }
327
328 // Initialize |vda_|, providing a new surface for it. You may get the surface
329 // by asking |codec_allocator_|.
330 void InitializeAVDAWithOverlay() {
331 EXPECT_CALL(*helper_, MockStartup());
332
333 config_.surface_id = 123;
334 ASSERT_TRUE(InitializeAVDA());
335 base::RunLoop().RunUntilIdle();
336 ASSERT_TRUE(helper_->factory_ != nullptr);
337
338 // Have the factory provide an overlay, and verify that codec creation is
339 // provided with that overlay.
340 std::unique_ptr<MockAndroidOverlay> overlay =
341 base::MakeUnique<MockAndroidOverlay>();
342 // Set the expectations first, since ProvideOverlay might cause callbacks.
343 EXPECT_CALL(codec_allocator_,
344 MockCreateMediaCodecAsync(overlay.get(), nullptr));
345 helper_->ProvideOverlay(std::move(overlay));
346
347 // Provide the codec so that we can check if it's freed properly.
348 EXPECT_CALL(client_, NotifyInitializationComplete(true));
349 codec_allocator_.ProvideMockCodecAsync();
350 base::RunLoop().RunUntilIdle();
351 }
352
353 void InitializeAVDAWithSurfaceTexture() {
354 EXPECT_CALL(*helper_, MockStartup());
355
356 ASSERT_TRUE(InitializeAVDA());
357 base::RunLoop().RunUntilIdle();
358 // We do not expect a factory, since we are using SurfaceTexture.
359 ASSERT_TRUE(helper_->factory_ == nullptr);
360
361 // Set the expectations first, since ProvideOverlay might cause callbacks.
362 EXPECT_CALL(codec_allocator_,
363 MockCreateMediaCodecAsync(nullptr, NotNull()));
364 helper_->ProvideSurfaceTexture();
365
366 // Provide the codec so that we can check if it's freed properly.
367 EXPECT_CALL(client_, NotifyInitializationComplete(true));
368 codec_allocator_.ProvideMockCodecAsync();
369 base::RunLoop().RunUntilIdle();
370 }
371
372 // Set whether HasUnrendereredPictureBuffers will return true or false.
373 // TODO(liberato): We can't actually do this yet. It turns out to be okay,
374 // because AVDA doesn't actually SetSurface before DequeueOutput. It could do
375 // so, though, if there aren't unrendered buffers. Should AVDA ever start
376 // switching surfaces immediately upon receiving them, rather than waiting for
377 // DequeueOutput, then we'll want to be able to indicate that it has
378 // unrendered pictures to prevent that behavior.
379 void SetHasUnrenderedPictureBuffers(bool flag) {}
380
381 // Tell |avda_| to switch surfaces to its incoming surface. This is a method
382 // since we're a friend of AVDA, and the tests are subclasses. It's also
383 // somewhat hacky, but much less hacky than trying to run it via a timer.
384 void LetAVDAUpdateSurface() {
385 SetHasUnrenderedPictureBuffers(false);
386 avda_->DequeueOutput();
98 } 387 }
99 388
100 base::MessageLoop message_loop_; 389 base::MessageLoop message_loop_;
101 scoped_refptr<gl::GLSurface> surface_; 390 scoped_refptr<gl::GLSurface> surface_;
102 scoped_refptr<gl::GLContext> context_; 391 scoped_refptr<gl::GLContext> context_;
392 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
103 NiceMock<gpu::gles2::MockGLES2Decoder> gl_decoder_; 393 NiceMock<gpu::gles2::MockGLES2Decoder> gl_decoder_;
104 NiceMock<MockVDAClient> client_; 394 StrictMock<MockVDAClient> client_;
105 NiceMock<MockCodecAllocator> codec_allocator_; 395 FakeCodecAllocator codec_allocator_;
396 VideoDecodeAccelerator::Config config_;
397
398 AndroidVideoDecodeAccelerator::PlatformConfig platform_config_;
399
400 // We maintain a weak ref to this since AVDA owns it.
401 base::WeakPtr<FakeOverlayHelper> helper_;
106 402
107 // This must be a unique pointer to a VDA, not an AVDA, to ensure the 403 // This must be a unique pointer to a VDA, not an AVDA, to ensure the
108 // the default_delete specialization that calls Destroy() will be used. 404 // the default_delete specialization that calls Destroy() will be used.
109 std::unique_ptr<VideoDecodeAccelerator> vda_; 405 std::unique_ptr<VideoDecodeAccelerator> vda_;
406
407 // Weak ptr to |vda_| as an AVDA.
408 base::WeakPtr<AndroidVideoDecodeAccelerator> avda_;
409
410 private:
411 // This is the object that |helper_| points to, or nullptr once we assign
412 // ownership to AVDA.
413 std::unique_ptr<FakeOverlayHelper> helper_that_is_usually_null_;
110 }; 414 };
111 415
112 TEST_F(AndroidVideoDecodeAcceleratorTest, ConfigureUnsupportedCodec) { 416 TEST_F(AndroidVideoDecodeAcceleratorTest, ConfigureUnsupportedCodec) {
113 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE(); 417 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
114 418
115 ASSERT_FALSE(vda_->Initialize( 419 config_ = VideoDecodeAccelerator::Config(VIDEO_CODEC_PROFILE_UNKNOWN);
116 VideoDecodeAccelerator::Config(VIDEO_CODEC_PROFILE_UNKNOWN), &client_)); 420 ASSERT_FALSE(InitializeAVDA());
117 } 421 }
118 422
119 TEST_F(AndroidVideoDecodeAcceleratorTest, ConfigureSupportedCodec) { 423 TEST_F(AndroidVideoDecodeAcceleratorTest,
120 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE(); 424 ConfigureSupportedCodecSynchronously) {
121 425 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
122 // H264 is always supported by AVDA. 426
123 ASSERT_TRUE(vda_->Initialize( 427 config_.is_deferred_initialization_allowed = false;
124 VideoDecodeAccelerator::Config(H264PROFILE_BASELINE), &client_)); 428
125 } 429 EXPECT_CALL(codec_allocator_, MockCreateMediaCodecSync(nullptr, NotNull()));
watk 2017/04/22 00:29:07 This looks like noise caused by StrictMock.
liberato (no reviews please) 2017/04/27 18:30:12 i want to be sure that it uses the sync path for c
126 430 ASSERT_TRUE(InitializeAVDA());
127 TEST_F(AndroidVideoDecodeAcceleratorTest, FailingToCreateACodecIsAnError) { 431 }
128 EXPECT_CALL(codec_allocator_, CreateMediaCodecAsync(_, _)) 432
129 .WillOnce(PostNullCodec()); 433 TEST_F(AndroidVideoDecodeAcceleratorTest, FailingToCreateACodecSyncIsAnError) {
434 // Failuew to create a codec during sync init should cause Initialize to fail.
435 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
436
437 config_.is_deferred_initialization_allowed = false;
438 codec_allocator_.allow_sync_creation = false;
439
440 EXPECT_CALL(codec_allocator_, MockCreateMediaCodecSync(nullptr, NotNull()));
441 ASSERT_FALSE(InitializeAVDA());
442 }
443
444 TEST_F(AndroidVideoDecodeAcceleratorTest, FailingToCreateACodecAsyncIsAnError) {
445 // Verify that a null codec signals error for async init when it doesn't get a
446 // mediacodec instance.
447 //
448 // Also assert that there's only one call to CreateMediaCodecAsync. And since
449 // it replies with a null codec, AVDA will be in an error state when it shuts
450 // down. Since we know that it's constructed before we destroy the VDA, we
451 // verify that AVDA doens't create codecs during destruction.
452 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
453
454 // Note that if we somehow end up deferring surface creation, then this would
455 // no longer be expected to fail. It would signal success before asking for a
456 // surface or codec.
457 EXPECT_CALL(*helper_, MockStartup());
watk 2017/04/22 00:29:07 Seems like noise.
liberato (no reviews please) 2017/04/27 18:30:12 Done.
458 EXPECT_CALL(codec_allocator_, MockCreateMediaCodecAsync(_, NotNull()));
130 EXPECT_CALL(client_, NotifyInitializationComplete(false)); 459 EXPECT_CALL(client_, NotifyInitializationComplete(false));
131 460
132 VideoDecodeAccelerator::Config config(H264PROFILE_BASELINE); 461 ASSERT_TRUE(InitializeAVDA());
133 config.is_deferred_initialization_allowed = true; 462 helper_->ProvideSurfaceTexture();
134 vda_->Initialize(config, &client_); 463 codec_allocator_.ProvideNullCodecAsync();
135 base::RunLoop().RunUntilIdle(); 464
136 } 465 // Make sure that codec allocation has happened before destroying the VDA.
137 466 testing::Mock::VerifyAndClearExpectations(&codec_allocator_);
138 TEST_F(AndroidVideoDecodeAcceleratorTest, NoCodecsAreCreatedDuringDestruction) { 467
139 // Assert that there's only one call to CreateMediaCodecAsync. And since it 468 vda_ = nullptr;
140 // replies with a null codec, AVDA will be in an error state when it shuts 469 base::RunLoop().RunUntilIdle();
141 // down. 470 }
142 EXPECT_CALL(codec_allocator_, CreateMediaCodecAsync(_, _)) 471
143 .WillOnce(PostNullCodec()); 472 TEST_F(AndroidVideoDecodeAcceleratorTest,
144 473 LowEndDevicesSucceedInitWithoutASurface) {
145 VideoDecodeAccelerator::Config config(H264PROFILE_BASELINE); 474 // If AVDA decides that we should defer surface creation, then it should
146 config.is_deferred_initialization_allowed = true; 475 // signal success before we provide a surface. It should still ask for a
147 vda_->Initialize(config, &client_); 476 // surface, though.
148 base::RunLoop().RunUntilIdle(); 477 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
149 } 478
150 479 // It would be nicer if we didn't just force this on, since we might do so
480 // in a state that AVDA isn't supposed to handle (e.g., if we give it a
481 // surface, then it would never decide to defer surface creation).
482 platform_config_.force_deferred_surface_creation = true;
483 config_.surface_id = SurfaceManager::kNoSurfaceID;
484
485 EXPECT_CALL(*helper_, MockStartup()).Times(0);
486 EXPECT_CALL(client_, NotifyInitializationComplete(true));
487
488 InitializeAVDA();
489 }
490
491 TEST_F(AndroidVideoDecodeAcceleratorTest, WillStartHelperImmediately) {
492 // AVDA should initialize |helper_| immediately if it's not waiting for a Cdm.
493 // It should provide a null factory, since |config_| defaults to
494 // SurfaceTexture. We also expect that AVDA will not create a codec before it
495 // gets a surface, nor will it signal deferred init success to us.
496 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
497
498 EXPECT_CALL(*helper_, MockStartup());
499 EXPECT_CALL(codec_allocator_, MockCreateMediaCodecAsync(_, NotNull()))
500 .Times(0);
501 EXPECT_CALL(client_, NotifyInitializationComplete(_)).Times(0);
502
503 InitializeAVDA();
504 ASSERT_TRUE(helper_->factory_ == nullptr);
505 }
506
507 TEST_F(AndroidVideoDecodeAcceleratorTest,
508 AsyncInitWithSurfaceTextureAndDelete) {
509 // When configuring with a SurfaceTexture and deferred init, we should be
510 // asked for a codec, and be notified of init success if we provide one. When
511 // AVDA is destroyed, it should release the codec and surface texture.
512 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
513
514 InitializeAVDAWithSurfaceTexture();
515
516 // Delete the VDA, and make sure that it tries to free the codec and the right
517 // surface texture.
518 EXPECT_CALL(
519 codec_allocator_,
520 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
521 codec_allocator_.most_recent_overlay(),
522 codec_allocator_.most_recent_surface_texture()));
523 vda_ = nullptr;
524 base::RunLoop().RunUntilIdle();
525 }
526
527 TEST_F(AndroidVideoDecodeAcceleratorTest, AsyncInitWithSurfaceAndDelete) {
528 // When |config_| specifies a surface, we should be given a factory during
529 // startup for it. When |helper_| provides an overlay, the codec should be
530 // allocated using it. Shutdown should provide the overlay when releasing the
531 // media codec.
532 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
533
534 InitializeAVDAWithOverlay();
535
536 // Delete the VDA, and make sure that it tries to free the codec and the
537 // overlay that it provided to us.
538 EXPECT_CALL(
539 codec_allocator_,
540 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
541 codec_allocator_.most_recent_overlay(),
542 codec_allocator_.most_recent_surface_texture()));
543 vda_ = nullptr;
544 base::RunLoop().RunUntilIdle();
545 }
546
547 TEST_F(AndroidVideoDecodeAcceleratorTest,
548 SwitchesToSurfaceTextureWhenSurfaceDestroyed) {
549 // Provide a surface, and a codec, then destroy the surface. AVDA should use
550 // SetSurface to switch to SurfaceTexture.
551 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
552
553 InitializeAVDAWithOverlay();
554
555 // It would be nice if we knew that this was a surface texture. As it is, we
556 // just destroy the VDA and expect that we're provided with one. Hopefully,
557 // AVDA is actually calling SetSurface properly.
558 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_))
559 .WillOnce(Return(true));
560 helper_->StopImmediately(codec_allocator_.most_recent_overlay());
561
562 EXPECT_CALL(codec_allocator_,
563 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
564 nullptr, NotNull()));
565 vda_ = nullptr;
566 base::RunLoop().RunUntilIdle();
567 }
568
569 TEST_F(AndroidVideoDecodeAcceleratorTest, SwitchesToSurfaceTextureEventually) {
570 // Provide a surface, and a codec, then request that AVDA switches to a
571 // surface texture. Verify that it does.
572 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
573
574 InitializeAVDAWithOverlay();
575
576 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_))
577 .WillOnce(Return(true));
578
579 // Note that it's okay if |avda_| switches before ProvideSurfaceTexture
580 // returns, since it has no queued output anyway.
581 helper_->ProvideSurfaceTexture();
582 LetAVDAUpdateSurface();
583
584 // Verify that we're now using some surface texture.
585 EXPECT_CALL(codec_allocator_,
586 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
587 nullptr, NotNull()));
588 vda_ = nullptr;
589 base::RunLoop().RunUntilIdle();
590 }
591
592 TEST_F(AndroidVideoDecodeAcceleratorTest,
593 SetSurfaceFailureDoesntSwitchSurfaces) {
594 // Initialize AVDA with a surface, then request that AVDA switches to a
595 // surface texture. When it tries to UpdateSurface, pretend to fail. AVDA
596 // should notify error, and also release the original surface.
597 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
598
599 InitializeAVDAWithOverlay();
600
601 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_))
602 .WillOnce(Return(false));
603 EXPECT_CALL(client_,
604 NotifyError(AndroidVideoDecodeAccelerator::PLATFORM_FAILURE))
605 .Times(1);
606 helper_->ProvideSurfaceTexture();
607
608 // Verify that we're still using an overlay.
609 EXPECT_CALL(codec_allocator_,
610 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
611 NotNull(), nullptr));
612
613 // Also destroy the VDA to be sure that it cleans up the codec. It can do so
614 // earlier if it wants to, but isn't required to.
615 LetAVDAUpdateSurface();
616 vda_ = nullptr;
617 base::RunLoop().RunUntilIdle();
618 }
619
620 TEST_F(AndroidVideoDecodeAcceleratorTest,
621 SwitchToSurfaceAndBackBeforeSetSurface) {
622 // Ask AVDA to switch from ST to overlay, then back to ST before it has a
623 // chance to do the first switch. It should simply drop the overlay.
624 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
625
626 InitializeAVDAWithSurfaceTexture();
627
628 // Don't let AVDA switch immediately, else it could choose to SetSurface when
629 // it first gets the overlay.
630 SetHasUnrenderedPictureBuffers(true);
631 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_)).Times(0);
632 std::unique_ptr<MockAndroidOverlay> overlay =
633 base::MakeUnique<MockAndroidOverlay>();
634 auto overlay_weak = overlay->GetWeakPtr();
635 helper_->ProvideOverlay(std::move(overlay));
636 // ProvideOverlay should not drop |overlay_weak| yet.
637 ASSERT_TRUE(overlay_weak.get() != nullptr);
638
639 // While the incoming surface is pending, switch back to SurfaceTexture.
640 helper_->ProvideSurfaceTexture();
641 // ProvideOverlay should drop |overlay_weak|.
642 ASSERT_TRUE(overlay_weak.get() == nullptr);
643
644 // Cleanup should free the the original SurfaceTexture. It would probably be
645 // fine to free a new one, but that seems like a waste of resources. So, we
646 // enforce that it should elide the switch entirely.
647 EXPECT_CALL(
648 codec_allocator_,
649 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(), nullptr,
650 codec_allocator_.most_recent_surface_texture()));
651 LetAVDAUpdateSurface();
652 vda_ = nullptr;
653 base::RunLoop().RunUntilIdle();
654 }
655
656 TEST_F(AndroidVideoDecodeAcceleratorTest,
657 ChangingOutputSurfaceVoluntarilyWithoutSetSurfaceIsIgnored) {
658 // If we ask AVDA to change to SurfaceTexture should be ignored on platforms
659 // that don't support SetSurface (pre-M or blacklisted). It should also
660 // ignore SurfaceTexture => overlay, but we don't check that.
661 //
662 // Also note that there are other probably reasonable things to do (like
663 // signal an error), but we want to be sure that it doesn't try to SetSurface.
664 // We also want to be sure that, if it doesn't signal an error, that it also
665 // doesn't get confused about which surface is in use. So, we assume that it
666 // doesn't signal an error, and we check that it releases the right surface
667 // with the codec.
668 EXPECT_CALL(client_, NotifyError(_)).Times(0);
669
670 platform_config_.allow_setsurface = false;
671 InitializeAVDAWithOverlay();
672 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_)).Times(0);
673
674 // This should not switch to SurfaceTexture.
675 helper_->ProvideSurfaceTexture();
676 LetAVDAUpdateSurface();
677
678 // It should free an overlay with the codec.
679 EXPECT_CALL(
680 codec_allocator_,
681 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
682 codec_allocator_.most_recent_overlay(), nullptr));
683 vda_ = nullptr;
684 base::RunLoop().RunUntilIdle();
685 }
686
687 TEST_F(AndroidVideoDecodeAcceleratorTest,
688 OnSurfaceDestroyedWithoutSetSurfaceFreesTheCodec) {
689 // If AVDA receives OnSurfaceDestroyed without support for SetSurface, then it
690 // should free the codec.
691 platform_config_.allow_setsurface = false;
692 InitializeAVDAWithOverlay();
693 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_)).Times(0);
694
695 // This should free the codec.
696 EXPECT_CALL(
697 codec_allocator_,
698 MockReleaseMediaCodec(codec_allocator_.most_recent_codec(),
699 codec_allocator_.most_recent_overlay(), nullptr));
700 helper_->StopImmediately(codec_allocator_.most_recent_overlay());
701 base::RunLoop().RunUntilIdle();
702
703 // Verify that the codec has been released, since |vda_| will be destroyed
704 // soon. The expectations must be met before that.
705 testing::Mock::VerifyAndClearExpectations(&codec_allocator_);
706 }
707
708 TEST_F(AndroidVideoDecodeAcceleratorTest,
709 MultipleSurfaceTextureCallbacksAreIgnored) {
710 // Ask AVDA to switch to ST when it's already using ST, nothing should happen.
711 SKIP_IF_MEDIACODEC_IS_NOT_AVAILABLE();
712
713 InitializeAVDAWithSurfaceTexture();
714
715 // This should do nothing.
716 EXPECT_CALL(*codec_allocator_.most_recent_codec(), SetSurface(_)).Times(0);
717 helper_->ProvideSurfaceTexture();
718
719 base::RunLoop().RunUntilIdle();
720 }
721
151 } // namespace media 722 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698