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

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

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

Powered by Google App Engine
This is Rietveld 408576698