~phablet-team/aethercast/fix-for-microsoft-dongle

« back to all changes in this revision

Viewing changes to tests/mcs/android/h264encoder_tests.cpp

Add hardware encoding and video streaming support.

The hardware encoding is currently only for Android 5.x based devices. On all others encoding will simply not work. The streaming part of aethercast (MPEGTS packetizing, RTP sending) as based on some code from Android.

Approved by PS Jenkins bot, Thomas Voß, Jim Hodapp.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2016 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 */
 
17
 
 
18
#include <gmock/gmock.h>
 
19
 
 
20
#include <system/window.h>
 
21
 
 
22
#include "mcs/android/h264encoder.h"
 
23
 
 
24
#include "mockmedia.h"
 
25
 
 
26
using namespace ::testing;
 
27
 
 
28
namespace {
 
29
// From frameworks/native/include/media/openmax/OMX_IVCommon.h
 
30
const int32_t kOMXColorFormatAndroidOpaque = 0x7F000789;
 
31
const int32_t kOMXVideoIntraRefreshCyclic = 0;
 
32
// From frameworks/native/include/media/openmax/OMX_Video.h
 
33
const int32_t kOMXVideoControlRateConstant = 2;
 
34
// From frameworks/native/include/media/hardware/MetadataBufferType.h
 
35
const uint32_t kMetadataBufferTypeGrallocSource = 1;
 
36
 
 
37
class MockEncoderDelegate : public mcs::video::BaseEncoder::Delegate {
 
38
public:
 
39
    MOCK_METHOD1(OnBufferAvailable, void(const mcs::video::Buffer::Ptr&));
 
40
    MOCK_METHOD1(OnBufferWithCodecConfig, void(const mcs::video::Buffer::Ptr&));
 
41
    MOCK_METHOD0(OnBufferReturned, void());
 
42
};
 
43
 
 
44
class MockBufferDelegate : public mcs::video::Buffer::Delegate {
 
45
public:
 
46
    MOCK_METHOD1(OnBufferFinished, void(const mcs::video::Buffer::Ptr&));
 
47
};
 
48
 
 
49
struct DummyMediaMessageWrapper {
 
50
};
 
51
 
 
52
struct DummyMediaSourceWrapper {
 
53
};
 
54
 
 
55
struct DummyMediaMetaDataWrapper {
 
56
};
 
57
 
 
58
struct DummyMediaCodecSource {
 
59
};
 
60
 
 
61
struct DummyMediaBufferWrapper {
 
62
};
 
63
 
 
64
class H264EncoderFixture : public ::testing::Test {
 
65
public:
 
66
    void ExpectValidConfiguration(const mcs::video::BaseEncoder::Config &config, const mcs::test::android::MockMedia::Ptr &mock) {
 
67
        auto message = new DummyMediaMessageWrapper;
 
68
 
 
69
        EXPECT_CALL(*mock, media_message_create())
 
70
                .Times(1)
 
71
                .WillRepeatedly(Return(message));
 
72
        EXPECT_CALL(*mock, media_message_release(message))
 
73
                .Times(1)
 
74
                .WillOnce(Invoke([](MediaMessageWrapper *msg) { delete msg; }));
 
75
        EXPECT_CALL(*mock, media_message_set_string(message, _, _, _))
 
76
                .Times(AtLeast(0));
 
77
        EXPECT_CALL(*mock, media_message_set_int32(message, _, _))
 
78
                .Times(AtLeast(0));
 
79
 
 
80
        auto source = new DummyMediaSourceWrapper;
 
81
 
 
82
        EXPECT_CALL(*mock, media_source_create())
 
83
                .Times(1)
 
84
                .WillRepeatedly(Return(source));
 
85
        EXPECT_CALL(*mock, media_source_release(source))
 
86
                .Times(1)
 
87
                .WillOnce(Invoke([](MediaSourceWrapper *source) { delete source; }));
 
88
 
 
89
        auto meta_data = new DummyMediaMetaDataWrapper;
 
90
 
 
91
        EXPECT_CALL(*mock, media_meta_data_create())
 
92
                .Times(1)
 
93
                .WillRepeatedly(Return(meta_data));
 
94
        EXPECT_CALL(*mock, media_meta_data_release(meta_data))
 
95
                .Times(1)
 
96
                .WillOnce(Invoke([](MediaMetaDataWrapper *meta) { delete meta; }));
 
97
        EXPECT_CALL(*mock, media_meta_data_set_cstring(meta_data, _, _))
 
98
                .Times(AtLeast(0));
 
99
        EXPECT_CALL(*mock, media_meta_data_set_int32(meta_data, _, _))
 
100
                .Times(AtLeast(0));
 
101
 
 
102
        EXPECT_CALL(*mock, media_meta_data_get_key_id(_))
 
103
                .Times(AtLeast(0))
 
104
                .WillRepeatedly(Return(0));
 
105
 
 
106
        EXPECT_CALL(*mock, media_source_set_format(source, meta_data))
 
107
                .Times(1);
 
108
        EXPECT_CALL(*mock, media_source_set_start_callback(source, _, _))
 
109
                .Times(1);
 
110
        EXPECT_CALL(*mock, media_source_set_stop_callback(source, _, _))
 
111
                .Times(1);
 
112
        EXPECT_CALL(*mock, media_source_set_pause_callback(source, _, _))
 
113
                .Times(1);
 
114
        EXPECT_CALL(*mock, media_source_set_read_callback(source, _, _))
 
115
                .Times(1)
 
116
                .WillRepeatedly(DoAll(SaveArg<1>(&source_read_callback),
 
117
                                      SaveArg<2>(&source_read_callback_data)));
 
118
 
 
119
        auto codec_source = new DummyMediaCodecSource;
 
120
 
 
121
        EXPECT_CALL(*mock, media_codec_source_create(message, source, _))
 
122
                .Times(1)
 
123
                .WillRepeatedly(Return(codec_source));
 
124
        EXPECT_CALL(*mock, media_codec_source_release(codec_source))
 
125
                .Times(1)
 
126
                .WillOnce(Invoke([](MediaCodecSourceWrapper *source) { delete source; }));
 
127
    }
 
128
 
 
129
    void ExpectValidStartAndStop(const mcs::test::android::MockMedia::Ptr &mock) {
 
130
        EXPECT_CALL(*mock, media_codec_source_start(_))
 
131
                .Times(1)
 
132
                .WillRepeatedly(Return(true));
 
133
 
 
134
        EXPECT_CALL(*mock, media_codec_source_stop(_))
 
135
                .Times(1)
 
136
                .WillRepeatedly(Return(true));
 
137
    }
 
138
 
 
139
    MediaSourceReadCallback source_read_callback;
 
140
    void *source_read_callback_data;
 
141
};
 
142
}
 
143
 
 
144
TEST(H264Encoder, ValidDefaultConfiguration) {
 
145
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
146
    EXPECT_EQ(-1, config.framerate);
 
147
    EXPECT_EQ(5000000, config.bitrate);
 
148
    EXPECT_EQ(15, config.i_frame_interval);
 
149
    EXPECT_EQ(0, config.intra_refresh_mode);
 
150
    EXPECT_EQ(0, config.width);
 
151
    EXPECT_EQ(0, config.height);
 
152
    EXPECT_EQ(0, config.profile);
 
153
    EXPECT_EQ(0, config.profile_idc);
 
154
    EXPECT_EQ(0, config.level);
 
155
    EXPECT_EQ(0, config.level_idc);
 
156
    EXPECT_EQ(0, config.constraint_set);
 
157
}
 
158
 
 
159
TEST(H264Encoder, MediaMessageCreationFails) {
 
160
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
161
 
 
162
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
163
 
 
164
    EXPECT_CALL(*mock, media_message_create())
 
165
            .Times(1)
 
166
            .WillRepeatedly(Return(nullptr));
 
167
 
 
168
    auto encoder = mcs::android::H264Encoder::Create();
 
169
 
 
170
    EXPECT_FALSE(encoder->Configure(config));
 
171
}
 
172
 
 
173
TEST(H264Encoder, MediaSourceCreationFails) {
 
174
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
175
 
 
176
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
177
 
 
178
    auto message = new DummyMediaMessageWrapper;
 
179
 
 
180
    EXPECT_CALL(*mock, media_message_create())
 
181
            .Times(1)
 
182
            .WillRepeatedly(Return(message));
 
183
    EXPECT_CALL(*mock, media_message_release(message))
 
184
            .Times(1);
 
185
    EXPECT_CALL(*mock, media_message_set_string(message, _, _, _))
 
186
            .Times(AtLeast(0));
 
187
    EXPECT_CALL(*mock, media_message_set_int32(message, _, _))
 
188
            .Times(AtLeast(0));
 
189
 
 
190
    EXPECT_CALL(*mock, media_source_create())
 
191
            .Times(1)
 
192
            .WillRepeatedly(Return(nullptr));
 
193
 
 
194
    auto encoder = mcs::android::H264Encoder::Create();
 
195
 
 
196
    EXPECT_FALSE(encoder->Configure(config));
 
197
}
 
198
 
 
199
TEST(H264Encoder, MediaMetaDataCreationFails) {
 
200
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
201
 
 
202
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
203
 
 
204
    auto message = new DummyMediaMessageWrapper;
 
205
 
 
206
    EXPECT_CALL(*mock, media_message_create())
 
207
            .Times(1)
 
208
            .WillRepeatedly(Return(message));
 
209
    EXPECT_CALL(*mock, media_message_release(message))
 
210
            .Times(1);
 
211
    EXPECT_CALL(*mock, media_message_set_string(message, _, _, _))
 
212
            .Times(AtLeast(0));
 
213
    EXPECT_CALL(*mock, media_message_set_int32(message, _, _))
 
214
            .Times(AtLeast(0));
 
215
 
 
216
    auto source = new DummyMediaSourceWrapper;
 
217
 
 
218
    EXPECT_CALL(*mock, media_source_create())
 
219
            .Times(1)
 
220
            .WillRepeatedly(Return(source));
 
221
    EXPECT_CALL(*mock, media_source_release(source))
 
222
            .Times(1);
 
223
 
 
224
    EXPECT_CALL(*mock, media_meta_data_create())
 
225
            .Times(1)
 
226
            .WillRepeatedly(Return(nullptr));
 
227
 
 
228
    auto encoder = mcs::android::H264Encoder::Create();
 
229
 
 
230
    EXPECT_FALSE(encoder->Configure(config));
 
231
}
 
232
 
 
233
TEST(H264Encoder, MediaCodecSourceCreationFails) {
 
234
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
235
 
 
236
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
237
 
 
238
    auto message = new DummyMediaMessageWrapper;
 
239
 
 
240
    EXPECT_CALL(*mock, media_message_create())
 
241
            .Times(1)
 
242
            .WillRepeatedly(Return(message));
 
243
    EXPECT_CALL(*mock, media_message_release(message))
 
244
            .Times(1);
 
245
    EXPECT_CALL(*mock, media_message_set_string(message, _, _, _))
 
246
            .Times(AtLeast(0));
 
247
    EXPECT_CALL(*mock, media_message_set_int32(message, _, _))
 
248
            .Times(AtLeast(0));
 
249
 
 
250
    auto source = new DummyMediaSourceWrapper;
 
251
 
 
252
    EXPECT_CALL(*mock, media_source_create())
 
253
            .Times(1)
 
254
            .WillRepeatedly(Return(source));
 
255
    EXPECT_CALL(*mock, media_source_release(source))
 
256
            .Times(1);
 
257
 
 
258
    auto meta_data = new DummyMediaMetaDataWrapper;
 
259
 
 
260
    EXPECT_CALL(*mock, media_meta_data_create())
 
261
            .Times(1)
 
262
            .WillRepeatedly(Return(meta_data));
 
263
    EXPECT_CALL(*mock, media_meta_data_release(meta_data))
 
264
            .Times(1);
 
265
    EXPECT_CALL(*mock, media_meta_data_set_cstring(meta_data, _, _))
 
266
            .Times(AtLeast(0));
 
267
    EXPECT_CALL(*mock, media_meta_data_set_int32(meta_data, _, _))
 
268
            .Times(AtLeast(0));
 
269
 
 
270
    EXPECT_CALL(*mock, media_meta_data_get_key_id(_))
 
271
            .Times(AtLeast(0))
 
272
            .WillRepeatedly(Return(0));
 
273
 
 
274
    EXPECT_CALL(*mock, media_source_set_format(source, meta_data))
 
275
            .Times(1);
 
276
    EXPECT_CALL(*mock, media_source_set_start_callback(source, _, _))
 
277
            .Times(1);
 
278
    EXPECT_CALL(*mock, media_source_set_stop_callback(source, _, _))
 
279
            .Times(1);
 
280
    EXPECT_CALL(*mock, media_source_set_pause_callback(source, _, _))
 
281
            .Times(1);
 
282
    EXPECT_CALL(*mock, media_source_set_read_callback(source, _, _))
 
283
            .Times(1);
 
284
 
 
285
    EXPECT_CALL(*mock, media_codec_source_create(message, source, _))
 
286
            .Times(1)
 
287
            .WillRepeatedly(Return(nullptr));
 
288
 
 
289
    auto encoder = mcs::android::H264Encoder::Create();
 
290
 
 
291
    EXPECT_FALSE(encoder->Configure(config));
 
292
}
 
293
 
 
294
TEST(H264Encoder, CorrectConfiguration) {
 
295
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
296
 
 
297
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
298
    config.width = 1280;
 
299
    config.height = 720;
 
300
    config.framerate = 30;
 
301
    config.profile_idc = 1;
 
302
    config.level_idc = 2;
 
303
    config.constraint_set = 3;
 
304
 
 
305
    auto format_message = new DummyMediaMessageWrapper;
 
306
 
 
307
    EXPECT_CALL(*mock, media_message_create())
 
308
            .Times(1)
 
309
            .WillRepeatedly(Return(format_message));
 
310
    EXPECT_CALL(*mock, media_message_release(format_message))
 
311
            .Times(1)
 
312
            .WillOnce(Invoke([](MediaMessageWrapper *msg) { delete msg; }));
 
313
 
 
314
    EXPECT_CALL(*mock, media_message_set_string(format_message, StrEq("mime"), StrEq("video/avc"), 0))
 
315
            .Times(1);
 
316
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("store-metadata-in-buffers"), 1))
 
317
            .Times(1);
 
318
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("store-metadata-in-buffers-output"), 0))
 
319
            .Times(1);
 
320
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("width"), config.width))
 
321
            .Times(1);
 
322
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("height"), config.height))
 
323
            .Times(1);
 
324
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("stride"), config.width))
 
325
            .Times(1);
 
326
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("slice-height"), config.width))
 
327
            .Times(1);
 
328
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("color-format"), kOMXColorFormatAndroidOpaque))
 
329
            .Times(1);
 
330
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("bitrate"), config.bitrate))
 
331
            .Times(1);
 
332
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("bitrate-mode"), kOMXVideoControlRateConstant))
 
333
            .Times(1);
 
334
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("frame-rate"), config.framerate))
 
335
            .Times(1);
 
336
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("intra-refresh-mode"), config.intra_refresh_mode))
 
337
            .Times(1);
 
338
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("intra-refresh-CIR-mbs"), 360))
 
339
            .Times(1);
 
340
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("i-frame-interval"), config.i_frame_interval))
 
341
            .Times(1);
 
342
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("prepend-sps-pps-to-idr-frames"), 1))
 
343
            .Times(1);
 
344
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("profile-idc"), 1))
 
345
            .Times(1);
 
346
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("level-idc"), 2))
 
347
            .Times(1);
 
348
    EXPECT_CALL(*mock, media_message_set_int32(format_message, StrEq("constraint-set"), 3))
 
349
            .Times(1);
 
350
 
 
351
    auto meta_data = new DummyMediaMetaDataWrapper;
 
352
 
 
353
    EXPECT_CALL(*mock, media_meta_data_create())
 
354
            .Times(1)
 
355
            .WillRepeatedly(Return(meta_data));
 
356
    EXPECT_CALL(*mock, media_meta_data_release(meta_data))
 
357
            .Times(1)
 
358
            .WillRepeatedly(Invoke([](MediaMetaDataWrapper *meta) { delete meta; }));
 
359
    EXPECT_CALL(*mock, media_meta_data_set_cstring(meta_data, _, _))
 
360
            .Times(1);
 
361
    EXPECT_CALL(*mock, media_meta_data_set_int32(meta_data, _, _))
 
362
            .Times(6);
 
363
 
 
364
    EXPECT_CALL(*mock, media_meta_data_get_key_id(_))
 
365
            .Times(0);
 
366
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_MIME))
 
367
            .Times(1);
 
368
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_COLOR_FORMAT))
 
369
            .Times(1);
 
370
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_WIDTH))
 
371
            .Times(1);
 
372
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_HEIGHT))
 
373
            .Times(1);
 
374
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_STRIDE))
 
375
            .Times(1);
 
376
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_SLICE_HEIGHT))
 
377
            .Times(1);
 
378
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_FRAMERATE))
 
379
            .Times(1);
 
380
 
 
381
    auto source = new DummyMediaSourceWrapper;
 
382
 
 
383
    EXPECT_CALL(*mock, media_source_create())
 
384
            .Times(1)
 
385
            .WillRepeatedly(Return(source));
 
386
    EXPECT_CALL(*mock, media_source_release(source))
 
387
            .Times(1)
 
388
            .WillOnce(Invoke([](MediaSourceWrapper *source) { delete source; }));
 
389
    EXPECT_CALL(*mock, media_source_set_format(source, meta_data))
 
390
            .Times(1);
 
391
    EXPECT_CALL(*mock, media_source_set_start_callback(source, _, _))
 
392
            .Times(1);
 
393
    EXPECT_CALL(*mock, media_source_set_stop_callback(source, _, _))
 
394
            .Times(1);
 
395
    EXPECT_CALL(*mock, media_source_set_pause_callback(source, _, _))
 
396
            .Times(1);
 
397
    EXPECT_CALL(*mock, media_source_set_read_callback(source, _, NotNull()))
 
398
            .Times(1);
 
399
 
 
400
    auto codec_source = new DummyMediaCodecSource;
 
401
 
 
402
    EXPECT_CALL(*mock, media_codec_source_create(NotNull(), NotNull(), _))
 
403
            .Times(1)
 
404
            .WillRepeatedly(Return(codec_source));
 
405
    EXPECT_CALL(*mock, media_codec_source_release(codec_source))
 
406
            .Times(1)
 
407
            .WillOnce(Invoke([](MediaCodecSourceWrapper *source) { delete source; }));
 
408
 
 
409
    auto encoder = mcs::android::H264Encoder::Create();
 
410
 
 
411
    EXPECT_TRUE(encoder->Configure(config));
 
412
 
 
413
    // We can configure the encoder only once
 
414
    EXPECT_FALSE(encoder->Configure(config));
 
415
 
 
416
    auto stored_config = encoder->Configuration();
 
417
    EXPECT_EQ(config, stored_config);
 
418
}
 
419
 
 
420
TEST_F(H264EncoderFixture, CorrectStartAndStopBehavior) {
 
421
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
422
 
 
423
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
424
 
 
425
    ExpectValidConfiguration(config, mock);
 
426
 
 
427
    auto encoder = mcs::android::H264Encoder::Create();
 
428
 
 
429
    ExpectValidStartAndStop(mock);
 
430
 
 
431
    EXPECT_FALSE(encoder->Start());
 
432
    EXPECT_FALSE(encoder->Stop());
 
433
 
 
434
    EXPECT_TRUE(encoder->Configure(config));
 
435
 
 
436
    EXPECT_TRUE(encoder->Start());
 
437
    EXPECT_TRUE(encoder->Running());
 
438
    EXPECT_FALSE(encoder->Start());
 
439
    EXPECT_TRUE(encoder->Stop());
 
440
    EXPECT_FALSE(encoder->Running());
 
441
    EXPECT_FALSE(encoder->Stop());
 
442
}
 
443
 
 
444
TEST_F(H264EncoderFixture, StartFailsCorrectly) {
 
445
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
446
 
 
447
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
448
 
 
449
    ExpectValidConfiguration(config, mock);
 
450
 
 
451
    auto encoder = mcs::android::H264Encoder::Create();
 
452
 
 
453
    EXPECT_TRUE(encoder->Configure(config));
 
454
 
 
455
    EXPECT_CALL(*mock, media_codec_source_start(_))
 
456
            .Times(1)
 
457
            .WillRepeatedly(Return(false));
 
458
 
 
459
    EXPECT_FALSE(encoder->Start());
 
460
}
 
461
 
 
462
TEST_F(H264EncoderFixture, StopFailsCorrectly) {
 
463
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
464
 
 
465
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
466
 
 
467
    ExpectValidConfiguration(config, mock);
 
468
 
 
469
    auto encoder = mcs::android::H264Encoder::Create();
 
470
 
 
471
    EXPECT_TRUE(encoder->Configure(config));
 
472
 
 
473
    EXPECT_CALL(*mock, media_codec_source_start(_))
 
474
            .Times(1)
 
475
            .WillRepeatedly(Return(true));
 
476
    EXPECT_CALL(*mock, media_codec_source_stop(_))
 
477
            // Will be called twice as the d'tor also calls Stop to
 
478
            // ensure the encoder is stopped correctly on cleanup.
 
479
            .Times(2)
 
480
            .WillRepeatedly(Return(false));
 
481
 
 
482
    EXPECT_TRUE(encoder->Start());
 
483
    EXPECT_FALSE(encoder->Stop());
 
484
}
 
485
 
 
486
TEST_F(H264EncoderFixture, ReturnsCorrectNativeWindowHandle) {
 
487
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
488
 
 
489
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
490
 
 
491
    ExpectValidConfiguration(config, mock);
 
492
 
 
493
    auto encoder = mcs::android::H264Encoder::Create();
 
494
 
 
495
    EXPECT_EQ(nullptr, encoder->NativeWindowHandle());
 
496
 
 
497
    EXPECT_TRUE(encoder->Configure(config));
 
498
 
 
499
    auto expected_handle = reinterpret_cast<void*>(1);
 
500
 
 
501
    EXPECT_CALL(*mock, media_codec_source_get_native_window_handle(_))
 
502
            .Times(1)
 
503
            .WillRepeatedly(Return(expected_handle));
 
504
 
 
505
    EXPECT_EQ(expected_handle, encoder->NativeWindowHandle());
 
506
}
 
507
 
 
508
TEST_F(H264EncoderFixture, RequestIDRFrame) {
 
509
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
510
 
 
511
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
512
 
 
513
    ExpectValidConfiguration(config, mock);
 
514
 
 
515
    auto encoder = mcs::android::H264Encoder::Create();
 
516
 
 
517
    encoder->SendIDRFrame();
 
518
 
 
519
    EXPECT_TRUE(encoder->Configure(config));
 
520
 
 
521
    EXPECT_CALL(*mock, media_codec_source_request_idr_frame(_))
 
522
            .Times(1);
 
523
 
 
524
    encoder->SendIDRFrame();
 
525
}
 
526
 
 
527
TEST_F(H264EncoderFixture, ReturnsPackedBufferAndReleaseProperly) {
 
528
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
529
 
 
530
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
531
 
 
532
    ExpectValidConfiguration(config, mock);
 
533
 
 
534
    auto encoder = mcs::android::H264Encoder::Create();
 
535
 
 
536
    EXPECT_TRUE(encoder->Configure(config));
 
537
    EXPECT_NE(nullptr, source_read_callback);
 
538
    EXPECT_NE(nullptr, source_read_callback_data);
 
539
 
 
540
    ExpectValidStartAndStop(mock);
 
541
 
 
542
    EXPECT_TRUE(encoder->Start());
 
543
 
 
544
    auto anwb = new ANativeWindowBuffer;
 
545
    anwb->handle = new native_handle_t;
 
546
 
 
547
    auto buffer_delegate = std::make_shared<MockBufferDelegate>();
 
548
 
 
549
    auto input_buffer = mcs::video::Buffer::Create(anwb);
 
550
    input_buffer->SetDelegate(buffer_delegate);
 
551
    auto now = mcs::Utils::GetNowUs();
 
552
    input_buffer->SetTimestamp(now);
 
553
 
 
554
    encoder->QueueBuffer(input_buffer);
 
555
 
 
556
    MediaBufferWrapper *output_buffer = nullptr;
 
557
    auto mbuf = new DummyMediaBufferWrapper;
 
558
    size_t mbuf_size = sizeof(buffer_handle_t) + 4;
 
559
    auto mbuf_data = new uint8_t[mbuf_size];
 
560
 
 
561
    EXPECT_CALL(*mock, media_buffer_create(mbuf_size))
 
562
            .Times(1)
 
563
            .WillRepeatedly(Return(mbuf));
 
564
 
 
565
    EXPECT_CALL(*mock, media_buffer_get_data(mbuf))
 
566
            .Times(1)
 
567
            .WillRepeatedly(Return(mbuf_data));
 
568
 
 
569
    EXPECT_CALL(*mock, media_buffer_ref(mbuf))
 
570
            .Times(1);
 
571
 
 
572
    EXPECT_CALL(*mock, media_buffer_get_meta_data(mbuf))
 
573
            .Times(1);
 
574
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_TIME))
 
575
            .Times(1)
 
576
            .WillRepeatedly(Return(42));
 
577
    EXPECT_CALL(*mock, media_meta_data_set_int64(_, 42, now));
 
578
 
 
579
    MediaBufferReturnCallback return_callback;
 
580
    void *return_callback_data = nullptr;
 
581
 
 
582
    EXPECT_CALL(*mock, media_buffer_set_return_callback(mbuf, NotNull(), NotNull()))
 
583
            .Times(1)
 
584
            .WillRepeatedly(DoAll(SaveArg<1>(&return_callback),
 
585
                                  SaveArg<2>(&return_callback_data)));
 
586
 
 
587
 
 
588
    EXPECT_CALL(*mock, media_buffer_set_return_callback(mbuf, nullptr, nullptr))
 
589
            .Times(1);
 
590
 
 
591
    EXPECT_EQ(0, source_read_callback(&output_buffer, source_read_callback_data));
 
592
 
 
593
    EXPECT_EQ(mbuf, output_buffer);
 
594
 
 
595
    EXPECT_CALL(*buffer_delegate, OnBufferFinished(input_buffer))
 
596
            .Times(1);
 
597
 
 
598
    EXPECT_CALL(*mock, media_buffer_release(output_buffer))
 
599
            .Times(1);
 
600
 
 
601
    return_callback(output_buffer, return_callback_data);
 
602
 
 
603
    // Doesn't crash or fail badly when no real buffer is returned
 
604
    return_callback(nullptr, return_callback_data);
 
605
 
 
606
    EXPECT_TRUE(encoder->Stop());
 
607
 
 
608
    delete anwb;
 
609
    delete anwb->handle;
 
610
}
 
611
 
 
612
TEST_F(H264EncoderFixture, SourceReadFailsForInvalidState) {
 
613
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
614
 
 
615
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
616
 
 
617
    ExpectValidConfiguration(config, mock);
 
618
 
 
619
    auto encoder = mcs::android::H264Encoder::Create();
 
620
 
 
621
    ExpectValidStartAndStop(mock);
 
622
 
 
623
    EXPECT_TRUE(encoder->Configure(config));
 
624
    EXPECT_NE(nullptr, source_read_callback);
 
625
    EXPECT_NE(nullptr, source_read_callback_data);
 
626
 
 
627
    // Must fail as the encoder isn't started yet
 
628
    EXPECT_GE(0, source_read_callback(reinterpret_cast<MediaBufferWrapper**>(1), source_read_callback_data));
 
629
 
 
630
    // Must also fail when encoder isn't started and when started
 
631
    EXPECT_GE(0, source_read_callback(nullptr, source_read_callback_data));
 
632
    EXPECT_TRUE(encoder->Start());
 
633
    EXPECT_GE(0, source_read_callback(nullptr, source_read_callback_data));
 
634
}
 
635
 
 
636
TEST_F(H264EncoderFixture, QueueBufferDoesNotCrashWhenInactive) {
 
637
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
638
 
 
639
    auto encoder = mcs::android::H264Encoder::Create();
 
640
 
 
641
    auto buffer = mcs::video::Buffer::Create(nullptr);
 
642
    encoder->QueueBuffer(buffer);
 
643
}
 
644
 
 
645
TEST_F(H264EncoderFixture, ExecuteFailForInvalidState) {
 
646
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
647
 
 
648
    auto encoder = mcs::android::H264Encoder::Create();
 
649
 
 
650
    EXPECT_FALSE(encoder->Execute());
 
651
}
 
652
 
 
653
TEST_F(H264EncoderFixture, ExecuteFailsForFailedSourceRead) {
 
654
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
655
 
 
656
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
657
 
 
658
    ExpectValidConfiguration(config, mock);
 
659
    ExpectValidStartAndStop(mock);
 
660
 
 
661
    auto encoder = mcs::android::H264Encoder::Create();
 
662
 
 
663
    EXPECT_TRUE(encoder->Configure(config));
 
664
 
 
665
    EXPECT_TRUE(encoder->Start());
 
666
 
 
667
    EXPECT_CALL(*mock, media_codec_source_read(_, _))
 
668
            .Times(1)
 
669
            .WillRepeatedly(Return(false));
 
670
 
 
671
    EXPECT_FALSE(encoder->Execute());
 
672
 
 
673
    EXPECT_TRUE(encoder->Stop());
 
674
}
 
675
 
 
676
TEST_F(H264EncoderFixture, ExecuteProvidesBuffers) {
 
677
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
678
 
 
679
    auto encoder_delegate = std::make_shared<MockEncoderDelegate>();
 
680
 
 
681
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
682
 
 
683
    ExpectValidConfiguration(config, mock);
 
684
    ExpectValidStartAndStop(mock);
 
685
 
 
686
    auto encoder = mcs::android::H264Encoder::Create();
 
687
    encoder->SetDelegate(encoder_delegate);
 
688
 
 
689
    EXPECT_TRUE(encoder->Configure(config));
 
690
    EXPECT_TRUE(encoder->Start());
 
691
 
 
692
    auto input_buffer = new DummyMediaBufferWrapper;
 
693
    mcs::TimestampUs input_buffer_timestamp = 23ll;
 
694
 
 
695
    EXPECT_CALL(*mock, media_codec_source_read(_, _))
 
696
            .Times(1)
 
697
            .WillRepeatedly(DoAll(SetArgPointee<1>(input_buffer), Return(true)));
 
698
 
 
699
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_TIME))
 
700
            .Times(1)
 
701
            .WillRepeatedly(Return(1));
 
702
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_IS_CODEC_CONFIG))
 
703
            .Times(1)
 
704
            .WillRepeatedly(Return(2));
 
705
 
 
706
    auto meta_data = new DummyMediaMetaDataWrapper;
 
707
 
 
708
    EXPECT_CALL(*mock, media_buffer_get_meta_data(input_buffer))
 
709
            .Times(2)
 
710
            .WillRepeatedly(Return(meta_data));
 
711
 
 
712
    EXPECT_CALL(*mock, media_meta_data_find_int64(meta_data, 1, _))
 
713
            .Times(1)
 
714
            .WillRepeatedly(DoAll(SetArgPointee<2>(input_buffer_timestamp), Return(true)));
 
715
    EXPECT_CALL(*mock, media_meta_data_find_int32(meta_data, 2, _))
 
716
            .Times(1)
 
717
            .WillRepeatedly(DoAll(SetArgPointee<2>(0), Return(true)));
 
718
 
 
719
    EXPECT_CALL(*mock, media_buffer_get_refcount(input_buffer))
 
720
            .Times(1)
 
721
            .WillRepeatedly(Return(0));
 
722
 
 
723
    EXPECT_CALL(*mock, media_buffer_destroy(input_buffer))
 
724
            .Times(1);
 
725
 
 
726
    EXPECT_CALL(*encoder_delegate, OnBufferAvailable(_))
 
727
            .Times(1);
 
728
    EXPECT_CALL(*encoder_delegate, OnBufferWithCodecConfig(_))
 
729
            .Times(0);
 
730
 
 
731
    EXPECT_TRUE(encoder->Execute());
 
732
 
 
733
    EXPECT_TRUE(encoder->Stop());
 
734
}
 
735
 
 
736
TEST_F(H264EncoderFixture, HandsBuffersWithCodecSpecificDataBack) {
 
737
    auto mock = std::make_shared<mcs::test::android::MockMedia>();
 
738
 
 
739
    auto encoder_delegate = std::make_shared<MockEncoderDelegate>();
 
740
 
 
741
    auto config = mcs::android::H264Encoder::DefaultConfiguration();
 
742
 
 
743
    ExpectValidConfiguration(config, mock);
 
744
    ExpectValidStartAndStop(mock);
 
745
 
 
746
    auto encoder = mcs::android::H264Encoder::Create();
 
747
    encoder->SetDelegate(encoder_delegate);
 
748
 
 
749
    EXPECT_TRUE(encoder->Configure(config));
 
750
    EXPECT_TRUE(encoder->Start());
 
751
 
 
752
    auto input_buffer = new DummyMediaBufferWrapper;
 
753
    mcs::TimestampUs input_buffer_timestamp = 23ll;
 
754
 
 
755
    EXPECT_CALL(*mock, media_codec_source_read(_, _))
 
756
            .Times(1)
 
757
            .WillRepeatedly(DoAll(SetArgPointee<1>(input_buffer), Return(true)));
 
758
 
 
759
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_TIME))
 
760
            .Times(1)
 
761
            .WillRepeatedly(Return(1));
 
762
    EXPECT_CALL(*mock, media_meta_data_get_key_id(MEDIA_META_DATA_KEY_IS_CODEC_CONFIG))
 
763
            .Times(1)
 
764
            .WillRepeatedly(Return(2));
 
765
 
 
766
    auto meta_data = new DummyMediaMetaDataWrapper;
 
767
 
 
768
    EXPECT_CALL(*mock, media_buffer_get_meta_data(input_buffer))
 
769
            .Times(2)
 
770
            .WillRepeatedly(Return(meta_data));
 
771
 
 
772
    EXPECT_CALL(*mock, media_meta_data_find_int64(meta_data, 1, _))
 
773
            .Times(1)
 
774
            .WillRepeatedly(DoAll(SetArgPointee<2>(input_buffer_timestamp), Return(true)));
 
775
    EXPECT_CALL(*mock, media_meta_data_find_int32(meta_data, 2, _))
 
776
            .Times(1)
 
777
            .WillRepeatedly(DoAll(SetArgPointee<2>(1 /* marks this as a buffer with CSD */), Return(true)));
 
778
 
 
779
    EXPECT_CALL(*mock, media_buffer_get_refcount(input_buffer))
 
780
            .Times(1)
 
781
            .WillRepeatedly(Return(0));
 
782
 
 
783
    EXPECT_CALL(*mock, media_buffer_destroy(input_buffer))
 
784
            .Times(1);
 
785
 
 
786
    EXPECT_CALL(*encoder_delegate, OnBufferWithCodecConfig(_))
 
787
            .Times(1);
 
788
    EXPECT_CALL(*encoder_delegate, OnBufferAvailable(_))
 
789
            .Times(1);
 
790
 
 
791
    EXPECT_TRUE(encoder->Execute());
 
792
 
 
793
    EXPECT_TRUE(encoder->Stop());
 
794
}