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