1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // Unit Test for ECOSession.
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "ECOSessionTest"
21
22 #include <android-base/unique_fd.h>
23 #include <android/binder_auto_utils.h>
24 #include <android/binder_parcel.h>
25 #include <cutils/ashmem.h>
26 #include <gtest/gtest.h>
27 #include <math.h>
28 #include <stdlib.h>
29 #include <sys/mman.h>
30 #include <utils/Log.h>
31 #include <utils/Timers.h>
32
33 #include "FakeECOServiceInfoListener.h"
34 #include "FakeECOServiceStatsProvider.h"
35 #include "eco/ECOSession.h"
36 #include "eco/ECOUtils.h"
37
38 namespace android {
39 namespace media {
40 namespace eco {
41
42 using ::ndk::ScopedAStatus;
43
44 static constexpr uint32_t kTestWidth = 1280;
45 static constexpr uint32_t kTestHeight = 720;
46 static constexpr bool kIsCameraRecording = true;
47 static constexpr int32_t kTargetBitrateBps = 22000000;
48 static constexpr int32_t kKeyFrameIntervalFrames = 30;
49 static constexpr float kFrameRate = 30.0f;
50
51 // A helpful class to help create ECOSession and manage ECOSession.
52 class EcoSessionTest : public ::testing::Test {
53 public:
EcoSessionTest()54 EcoSessionTest() { ALOGD("EcoSessionTest created"); }
55
createSession(int32_t width,int32_t height,bool isCameraRecording)56 std::shared_ptr<ECOSession> createSession(int32_t width, int32_t height,
57 bool isCameraRecording) {
58 mSession = ECOSession::createECOSession(width, height, isCameraRecording);
59 if (mSession == nullptr) return nullptr;
60 return mSession;
61 }
62
63 private:
64 std::shared_ptr<ECOSession> mSession = nullptr;
65 };
66
TEST_F(EcoSessionTest,TestConstructorWithInvalidParameters)67 TEST_F(EcoSessionTest, TestConstructorWithInvalidParameters) {
68 // Expects failure as ECOService1.0 will only support up to 720P and camera recording case.
69 EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, true /* isCameraRecording */) ==
70 nullptr);
71
72 // Expects failure as ECOService1.0 will only support up to 720P and camera recording case.
73 EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, false /* isCameraRecording */) ==
74 nullptr);
75
76 EXPECT_TRUE(createSession(1920 /* width */, -1 /* height */, true /* isCameraRecording */) ==
77 nullptr);
78
79 EXPECT_TRUE(createSession(-1 /* width */, 1080 /* height */, true /* isCameraRecording */) ==
80 nullptr);
81 }
82
TEST_F(EcoSessionTest,TestConstructorWithValidParameters)83 TEST_F(EcoSessionTest, TestConstructorWithValidParameters) {
84 // Expects success with <= 720P and is for camera recording.
85 EXPECT_TRUE(createSession(1280 /* width */, 720 /* height */, true /* isCameraRecording */) !=
86 nullptr);
87
88 // Expects success with <= 720P and is for camera recording.
89 EXPECT_TRUE(createSession(640 /* width */, 480 /* height */, true /* isCameraRecording */) !=
90 nullptr);
91 }
92
TEST_F(EcoSessionTest,TestAddProviderWithoutSpecifyEcoDataType)93 TEST_F(EcoSessionTest, TestAddProviderWithoutSpecifyEcoDataType) {
94 std::shared_ptr<ECOSession> ecoSession =
95 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
96 EXPECT_TRUE(ecoSession);
97
98 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
99 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
100 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
101
102 ECOData providerConfig;
103 bool res;
104 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
105 EXPECT_FALSE(status.isOk());
106 }
107
TEST_F(EcoSessionTest,TestAddProviderWithWrongEcoDataType)108 TEST_F(EcoSessionTest, TestAddProviderWithWrongEcoDataType) {
109 std::shared_ptr<ECOSession> ecoSession =
110 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
111 EXPECT_TRUE(ecoSession);
112
113 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
114 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
115 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
116
117 ECOData providerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
118 systemTime(SYSTEM_TIME_BOOTTIME));
119 bool res;
120 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
121 EXPECT_FALSE(status.isOk());
122 }
123
TEST_F(EcoSessionTest,TestAddNormalProvider)124 TEST_F(EcoSessionTest, TestAddNormalProvider) {
125 std::shared_ptr<ECOSession> ecoSession =
126 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
127 EXPECT_TRUE(ecoSession);
128
129 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
130 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
131 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
132
133 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
134 systemTime(SYSTEM_TIME_BOOTTIME));
135 bool res;
136 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
137 EXPECT_TRUE(status.isOk());
138 }
139
140 // Add two providers and expect failure as ECOService1.0 only supports one provider and one
141 // listener.
TEST_F(EcoSessionTest,TestAddTwoProvider)142 TEST_F(EcoSessionTest, TestAddTwoProvider) {
143 std::shared_ptr<ECOSession> ecoSession =
144 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
145 EXPECT_TRUE(ecoSession);
146
147 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider1 =
148 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
149 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
150
151 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
152 systemTime(SYSTEM_TIME_BOOTTIME));
153 bool res;
154 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
155 EXPECT_TRUE(status.isOk());
156
157 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider2 =
158 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
159 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
160 status = ecoSession->addStatsProvider(fakeProvider2, providerConfig, &res);
161 EXPECT_FALSE(status.isOk());
162 }
163
TEST_F(EcoSessionTest,TestAddListenerWithDifferentHeight)164 TEST_F(EcoSessionTest, TestAddListenerWithDifferentHeight) {
165 std::shared_ptr<ECOSession> ecoSession =
166 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
167 EXPECT_TRUE(ecoSession);
168
169 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
170 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth - 1, kTestHeight,
171 kIsCameraRecording, ecoSession);
172
173 ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
174 systemTime(SYSTEM_TIME_BOOTTIME));
175 bool res;
176 ScopedAStatus status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
177 EXPECT_FALSE(status.isOk());
178 }
179
TEST_F(EcoSessionTest,TestAddListenerWithDifferentWidth)180 TEST_F(EcoSessionTest, TestAddListenerWithDifferentWidth) {
181 std::shared_ptr<ECOSession> ecoSession =
182 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
183 EXPECT_TRUE(ecoSession);
184
185 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
186 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight - 1,
187 kIsCameraRecording, ecoSession);
188
189 ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
190 systemTime(SYSTEM_TIME_BOOTTIME));
191 bool res;
192 ScopedAStatus status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
193 EXPECT_FALSE(status.isOk());
194 }
195
TEST_F(EcoSessionTest,TestAddListenerWithCameraRecordingFalse)196 TEST_F(EcoSessionTest, TestAddListenerWithCameraRecordingFalse) {
197 std::shared_ptr<ECOSession> ecoSession =
198 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
199 EXPECT_TRUE(ecoSession);
200
201 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
202 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
203 !kIsCameraRecording, ecoSession);
204
205 ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
206 systemTime(SYSTEM_TIME_BOOTTIME));
207 bool res;
208 ScopedAStatus status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res);
209 EXPECT_FALSE(status.isOk());
210 }
211
212 // Test the ECOSession with FakeECOServiceStatsProvider and FakeECOServiceInfoListener. Push the
213 // stats to ECOSession through FakeECOServiceStatsProvider and check the info received in
214 // from FakeECOServiceInfoListener ECOSession.
TEST_F(EcoSessionTest,TestSessionWithProviderAndListenerSimpleTest)215 TEST_F(EcoSessionTest, TestSessionWithProviderAndListenerSimpleTest) {
216 // The time that listener needs to wait for the info from ECOService.
217 static constexpr int kServiceWaitTimeMs = 10;
218
219 // Create the session.
220 std::shared_ptr<ECOSession> ecoSession =
221 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
222
223 // Add provider.
224 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
225 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
226 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
227 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
228 systemTime(SYSTEM_TIME_BOOTTIME));
229 providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider");
230 providerConfig.setInt32(KEY_PROVIDER_TYPE,
231 ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER);
232 bool res;
233 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
234
235 // Create listener.
236 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
237 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
238 kIsCameraRecording, ecoSession);
239
240 // Create the listener config.
241 ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
242 systemTime(SYSTEM_TIME_BOOTTIME));
243 listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
244 listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
245
246 // Specify the qp thresholds for receiving notification.
247 listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
248 listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
249
250 status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
251
252 ECOData info;
253 bool getInfo = false;
254
255 // Set the getInfo flag to true and copy the info from fakeListener.
256 fakeListener->setInfoAvailableCallback(
257 [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) {
258 getInfo = true;
259 info = newInfo;
260 });
261
262 // Inject the session stats into the ECOSession through fakeProvider.
263 SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52,
264 kTargetBitrateBps, kKeyFrameIntervalFrames,
265 kFrameRate);
266 fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS));
267
268 // Wait as ECOService may take some time to process.
269 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
270 // Check the Session info matches with the session stats sent by provider.
271 EXPECT_TRUE(getInfo);
272 EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO);
273
274 std::string infoType;
275 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
276 EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION);
277
278 // Check the session info matches the session stats provided by FakeECOServiceStatsProvider.
279 int32_t codecType;
280 EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK);
281 EXPECT_EQ(codecType, CodecTypeAVC);
282
283 int32_t profile;
284 EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK);
285 EXPECT_EQ(profile, AVCProfileHigh);
286
287 int32_t level;
288 EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK);
289 EXPECT_EQ(level, AVCLevel52);
290
291 int32_t bitrate;
292 EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK);
293 EXPECT_EQ(bitrate, kTargetBitrateBps);
294
295 int32_t kfi;
296 EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK);
297 EXPECT_EQ(kfi, kKeyFrameIntervalFrames);
298
299 // =======================================================================================
300 // Inject the frame stats with qp = 30. Expect receiving notification for the first frame.
301 SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */,
302 30 /* avg-qp */, 56 /* frameSize */);
303
304 getInfo = false;
305 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
306 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
307 // Check the Session info matches with the session stats sent by provider.
308 EXPECT_TRUE(getInfo);
309
310 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
311 EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
312
313 int8_t frameType;
314 EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
315 EXPECT_EQ(frameType, FrameTypeI);
316
317 int32_t frameNum;
318 EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
319 EXPECT_EQ(frameNum, 1);
320
321 int64_t framePtsUs;
322 EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
323 EXPECT_EQ(framePtsUs, 0);
324
325 int32_t frameQp;
326 EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
327 EXPECT_EQ(frameQp, 30);
328
329 int32_t frameSize;
330 EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
331 EXPECT_EQ(frameSize, 56);
332
333 // =======================================================================================
334 // Inject the frame stats with qp = 35. Expect not receiving notification as 35 is below
335 // threshold.
336 frameStats = SimpleEncodedFrameData(2 /* seq number */, FrameTypeP, 333333 /* framePtsUs */,
337 35 /* avg-qp */, 56 /* frameSize */);
338 getInfo = false;
339 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
340 // Wait as ECOService may take some time to process.
341 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
342 EXPECT_FALSE(getInfo);
343
344 // =======================================================================================
345 // Inject the frame stats with qp = 41. Expect receiving notification as 41 goes beyond
346 // threshold 40.
347 frameStats = SimpleEncodedFrameData(3 /* seq number */, FrameTypeP, 666666 /* framePtsUs */,
348 41 /* avg-qp */, 56 /* frameSize */);
349 getInfo = false;
350 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
351 // Wait as ECOService may take some time to process.
352 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
353
354 // Check the frame info matches with the frame stats sent by provider.
355 EXPECT_TRUE(getInfo);
356 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
357 EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
358 EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
359 EXPECT_EQ(frameType, FrameTypeP);
360 EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
361 EXPECT_EQ(frameNum, 3);
362 EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
363 EXPECT_EQ(framePtsUs, 666666);
364 EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
365 EXPECT_EQ(frameQp, 41);
366 EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
367 EXPECT_EQ(frameSize, 56);
368
369 // =======================================================================================
370 // Inject the frame stats with qp = 42. Expect not receiving notification as 42 goes beyond
371 // threshold 40 but delta oes not go beyond the mQpChangeThreshold threshold.
372 frameStats = SimpleEncodedFrameData(4 /* seq number */, FrameTypeP, 999999 /* framePtsUs */,
373 42 /* avg-qp */, 56 /* frameSize */);
374 getInfo = false;
375 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
376 // Wait as ECOService may take some time to process.
377 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
378 EXPECT_FALSE(getInfo);
379
380 // =======================================================================================
381 // Inject the frame stats with qp = 10. Expect receiving notification as the detal from
382 // last reported QP is larger than threshold 4.
383 frameStats = SimpleEncodedFrameData(5 /* seq number */, FrameTypeB, 1333332 /* framePtsUs */,
384 49 /* avg-qp */, 56 /* frameSize */);
385 getInfo = false;
386 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
387 // Wait as ECOService may take some time to process.
388 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
389
390 // Check the frame info matches with the frame stats sent by provider.
391 EXPECT_TRUE(getInfo);
392 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
393 EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
394 EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
395 EXPECT_EQ(frameType, FrameTypeB);
396 EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
397 EXPECT_EQ(frameNum, 5);
398 EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
399 EXPECT_EQ(framePtsUs, 1333332);
400 EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
401 EXPECT_EQ(frameQp, 49);
402 EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
403 EXPECT_EQ(frameSize, 56);
404
405 // =======================================================================================
406 // Inject the frame stats with qp = 41. Expect receiving notification as the detal from
407 // last reported QP is larger than threshold 4.
408 frameStats = SimpleEncodedFrameData(6 /* seq number */, FrameTypeB, 1666665 /* framePtsUs */,
409 41 /* avg-qp */, 56 /* frameSize */);
410 getInfo = false;
411 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
412 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
413
414 // Check the frame info matches with the frame stats sent by provider.
415 EXPECT_TRUE(getInfo);
416 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
417 EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME);
418 EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK);
419 EXPECT_EQ(frameType, FrameTypeB);
420 EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK);
421 EXPECT_EQ(frameNum, 6);
422 EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK);
423 EXPECT_EQ(framePtsUs, 1666665);
424 EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK);
425 EXPECT_EQ(frameQp, 41);
426 EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK);
427 EXPECT_EQ(frameSize, 56);
428 }
429
TEST_F(EcoSessionTest,TestRemoveMatchProvider)430 TEST_F(EcoSessionTest, TestRemoveMatchProvider) {
431 std::shared_ptr<ECOSession> ecoSession =
432 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
433 EXPECT_TRUE(ecoSession);
434
435 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider1 =
436 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
437 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
438
439 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
440 systemTime(SYSTEM_TIME_BOOTTIME));
441 bool res;
442 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
443 EXPECT_TRUE(res);
444 EXPECT_TRUE(status.isOk());
445
446 status = ecoSession->removeStatsProvider(fakeProvider1, &res);
447 EXPECT_TRUE(res);
448 EXPECT_TRUE(status.isOk());
449 }
450
TEST_F(EcoSessionTest,TestRemoveMisMatchProvider)451 TEST_F(EcoSessionTest, TestRemoveMisMatchProvider) {
452 std::shared_ptr<ECOSession> ecoSession =
453 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
454 EXPECT_TRUE(ecoSession);
455
456 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider1 =
457 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
458 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
459
460 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
461 systemTime(SYSTEM_TIME_BOOTTIME));
462 bool res;
463 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res);
464 EXPECT_TRUE(res);
465 EXPECT_TRUE(status.isOk());
466
467 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider2 =
468 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
469 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
470
471 status = ecoSession->removeStatsProvider(fakeProvider2, &res);
472 EXPECT_FALSE(res);
473 EXPECT_FALSE(status.isOk());
474 }
475
TEST_F(EcoSessionTest,TestRemoveMatchListener)476 TEST_F(EcoSessionTest, TestRemoveMatchListener) {
477 std::shared_ptr<ECOSession> ecoSession =
478 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
479 EXPECT_TRUE(ecoSession);
480
481 // Create listener.
482 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
483 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
484 kIsCameraRecording, ecoSession);
485
486 // Create the listener config.
487 ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
488 systemTime(SYSTEM_TIME_BOOTTIME));
489 listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
490 listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
491
492 // Specify the qp thresholds for receiving notification.
493 listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
494 listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
495
496 bool res;
497 ScopedAStatus status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
498
499 status = ecoSession->removeInfoListener(fakeListener, &res);
500 EXPECT_TRUE(res);
501 EXPECT_TRUE(status.isOk());
502 }
503
TEST_F(EcoSessionTest,TestRemoveMisMatchListener)504 TEST_F(EcoSessionTest, TestRemoveMisMatchListener) {
505 std::shared_ptr<ECOSession> ecoSession =
506 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
507 EXPECT_TRUE(ecoSession);
508
509 // Create listener.
510 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
511 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
512 kIsCameraRecording, ecoSession);
513
514 // Create the listener config.
515 ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
516 systemTime(SYSTEM_TIME_BOOTTIME));
517 listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
518 listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
519
520 // Specify the qp thresholds for receiving notification.
521 listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
522 listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
523
524 bool res;
525 ScopedAStatus status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
526
527 // Create listener.
528 std::shared_ptr<FakeECOServiceInfoListener> fakeListener2 =
529 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
530 kIsCameraRecording, ecoSession);
531
532 status = ecoSession->removeInfoListener(fakeListener2, &res);
533 EXPECT_FALSE(res);
534 EXPECT_FALSE(status.isOk());
535 }
536
537 // Test the listener connects to the ECOSession after provider sends the session info. Listener
538 // should recieve the session info right after adding itself to the ECOSession.
TEST_F(EcoSessionTest,TestAddListenerAferProviderStarts)539 TEST_F(EcoSessionTest, TestAddListenerAferProviderStarts) {
540 // The time that listener needs to wait for the info from ECOService.
541 static constexpr int kServiceWaitTimeMs = 10;
542
543 // Create the session.
544 std::shared_ptr<ECOSession> ecoSession =
545 createSession(kTestWidth, kTestHeight, kIsCameraRecording);
546
547 // Add provider.
548 std::shared_ptr<FakeECOServiceStatsProvider> fakeProvider =
549 ndk::SharedRefBase::make<FakeECOServiceStatsProvider>(
550 kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
551 ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG,
552 systemTime(SYSTEM_TIME_BOOTTIME));
553 providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider");
554 providerConfig.setInt32(KEY_PROVIDER_TYPE,
555 ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER);
556 bool res;
557 ScopedAStatus status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res);
558
559 // Inject the session stats into the ECOSession through fakeProvider.
560 SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52,
561 kTargetBitrateBps, kKeyFrameIntervalFrames,
562 kFrameRate);
563 fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS));
564
565 // Wait as ECOService may take some time to process.
566 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
567
568 // =======================================================================================
569 // Inject the frame stats with qp = 30. Expect receiving notification for the first frame.
570 SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */,
571 30 /* avg-qp */, 56 /* frameSize */);
572
573 fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS));
574 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
575
576 // =======================================================================================
577 // Create and add the listener to the ECOSession. Expect to receive the session infor right
578 // after addInfoListener.
579 std::shared_ptr<FakeECOServiceInfoListener> fakeListener =
580 ndk::SharedRefBase::make<FakeECOServiceInfoListener>(kTestWidth, kTestHeight,
581 kIsCameraRecording, ecoSession);
582
583 // Create the listener config.
584 ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG,
585 systemTime(SYSTEM_TIME_BOOTTIME));
586 listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener");
587 listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA);
588
589 // Specify the qp thresholds for receiving notification.
590 listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40);
591 listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5);
592
593 ECOData info;
594 bool getInfo = false;
595
596 // Set the getInfo flag to true and copy the info from fakeListener.
597 fakeListener->setInfoAvailableCallback(
598 [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) {
599 getInfo = true;
600 info = newInfo;
601 });
602
603 status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res);
604
605 // Wait as ECOService may take some time to process.
606 std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs));
607
608 // Check the Session info matches with the session stats sent by provider.
609 EXPECT_TRUE(getInfo);
610 EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO);
611
612 std::string infoType;
613 EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK);
614 EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION);
615
616 // Check the session info matches the session stats provided by FakeECOServiceStatsProvider.
617 int32_t codecType;
618 EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK);
619 EXPECT_EQ(codecType, CodecTypeAVC);
620
621 int32_t profile;
622 EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK);
623 EXPECT_EQ(profile, AVCProfileHigh);
624
625 int32_t level;
626 EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK);
627 EXPECT_EQ(level, AVCLevel52);
628
629 int32_t bitrate;
630 EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK);
631 EXPECT_EQ(bitrate, kTargetBitrateBps);
632
633 int32_t kfi;
634 EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK);
635 EXPECT_EQ(kfi, kKeyFrameIntervalFrames);
636 }
637
638 } // namespace eco
639 } // namespace media
640 } // namespace android
641