/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Unit Test for ECOSession. //#define LOG_NDEBUG 0 #define LOG_TAG "ECOSessionTest" #include #include #include #include #include #include #include #include #include #include "FakeECOServiceInfoListener.h" #include "FakeECOServiceStatsProvider.h" #include "eco/ECOSession.h" #include "eco/ECOUtils.h" namespace android { namespace media { namespace eco { using android::sp; using ::android::binder::Status; static constexpr uint32_t kTestWidth = 1280; static constexpr uint32_t kTestHeight = 720; static constexpr bool kIsCameraRecording = true; static constexpr int32_t kTargetBitrateBps = 22000000; static constexpr int32_t kKeyFrameIntervalFrames = 30; static constexpr float kFrameRate = 30.0f; // A helpful class to help create ECOSession and manage ECOSession. class EcoSessionTest : public ::testing::Test { public: EcoSessionTest() { ALOGD("EcoSessionTest created"); } sp createSession(int32_t width, int32_t height, bool isCameraRecording) { mSession = ECOSession::createECOSession(width, height, isCameraRecording); if (mSession == nullptr) return nullptr; return mSession; } private: sp mSession = nullptr; }; TEST_F(EcoSessionTest, TestConstructorWithInvalidParameters) { // Expects failure as ECOService1.0 will only support up to 720P and camera recording case. EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, true /* isCameraRecording */) == nullptr); // Expects failure as ECOService1.0 will only support up to 720P and camera recording case. EXPECT_TRUE(createSession(1920 /* width */, 1080 /* height */, false /* isCameraRecording */) == nullptr); EXPECT_TRUE(createSession(1920 /* width */, -1 /* height */, true /* isCameraRecording */) == nullptr); EXPECT_TRUE(createSession(-1 /* width */, 1080 /* height */, true /* isCameraRecording */) == nullptr); } TEST_F(EcoSessionTest, TestConstructorWithValidParameters) { // Expects success with <= 720P and is for camera recording. EXPECT_TRUE(createSession(1280 /* width */, 720 /* height */, true /* isCameraRecording */) != nullptr); // Expects success with <= 720P and is for camera recording. EXPECT_TRUE(createSession(640 /* width */, 480 /* height */, true /* isCameraRecording */) != nullptr); } TEST_F(EcoSessionTest, TestAddProviderWithoutSpecifyEcoDataType) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig; bool res; Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestAddProviderWithWrongEcoDataType) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestAddNormalProvider) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res); EXPECT_TRUE(status.isOk()); } // Add two providers and expect failure as ECOService1.0 only supports one provider and one // listener. TEST_F(EcoSessionTest, TestAddTwoProvider) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider1 = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res); EXPECT_TRUE(status.isOk()); sp fakeProvider2 = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); status = ecoSession->addStatsProvider(fakeProvider2, providerConfig, &res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestAddListenerWithDifferentHeight) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeListener = new FakeECOServiceInfoListener( kTestWidth - 1, kTestHeight, kIsCameraRecording, ecoSession); ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestAddListenerWithDifferentWidth) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeListener = new FakeECOServiceInfoListener( kTestWidth, kTestHeight - 1, kIsCameraRecording, ecoSession); ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestAddListenerWithCameraRecordingFalse) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeListener = new FakeECOServiceInfoListener( kTestWidth, kTestHeight, !kIsCameraRecording, ecoSession); ECOData ListenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addInfoListener(fakeListener, ListenerConfig, &res); EXPECT_FALSE(status.isOk()); } // Test the ECOSession with FakeECOServiceStatsProvider and FakeECOServiceInfoListener. Push the // stats to ECOSession through FakeECOServiceStatsProvider and check the info received in // from FakeECOServiceInfoListener ECOSession. TEST_F(EcoSessionTest, TestSessionWithProviderAndListenerSimpleTest) { // The time that listener needs to wait for the info from ECOService. static constexpr int kServiceWaitTimeMs = 10; // Create the session. sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); // Add provider. sp fakeProvider = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider"); providerConfig.setInt32(KEY_PROVIDER_TYPE, ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER); bool res; Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res); // Create listener. sp fakeListener = new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession); // Create the listener config. ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener"); listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA); // Specify the qp thresholds for receiving notification. listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40); listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5); status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res); ECOData info; bool getInfo = false; // Set the getInfo flag to true and copy the info from fakeListener. fakeListener->setInfoAvailableCallback( [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) { getInfo = true; info = newInfo; }); // Inject the session stats into the ECOSession through fakeProvider. SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52, kTargetBitrateBps, kKeyFrameIntervalFrames, kFrameRate); fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the Session info matches with the session stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO); std::string infoType; EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION); // Check the session info matches the session stats provided by FakeECOServiceStatsProvider. int32_t codecType; EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK); EXPECT_EQ(codecType, CodecTypeAVC); int32_t profile; EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK); EXPECT_EQ(profile, AVCProfileHigh); int32_t level; EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK); EXPECT_EQ(level, AVCLevel52); int32_t bitrate; EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK); EXPECT_EQ(bitrate, kTargetBitrateBps); int32_t kfi; EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK); EXPECT_EQ(kfi, kKeyFrameIntervalFrames); // ======================================================================================= // Inject the frame stats with qp = 30. Expect receiving notification for the first frame. SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */, 30 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the Session info matches with the session stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME); int8_t frameType; EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK); EXPECT_EQ(frameType, FrameTypeI); int32_t frameNum; EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK); EXPECT_EQ(frameNum, 1); int64_t framePtsUs; EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK); EXPECT_EQ(framePtsUs, 0); int32_t frameQp; EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK); EXPECT_EQ(frameQp, 30); int32_t frameSize; EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK); EXPECT_EQ(frameSize, 56); // ======================================================================================= // Inject the frame stats with qp = 35. Expect not receiving notification as 35 is below // threshold. frameStats = SimpleEncodedFrameData(2 /* seq number */, FrameTypeP, 333333 /* framePtsUs */, 35 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); EXPECT_FALSE(getInfo); // ======================================================================================= // Inject the frame stats with qp = 41. Expect receiving notification as 41 goes beyond // threshold 40. frameStats = SimpleEncodedFrameData(3 /* seq number */, FrameTypeP, 666666 /* framePtsUs */, 41 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the frame info matches with the frame stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME); EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK); EXPECT_EQ(frameType, FrameTypeP); EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK); EXPECT_EQ(frameNum, 3); EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK); EXPECT_EQ(framePtsUs, 666666); EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK); EXPECT_EQ(frameQp, 41); EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK); EXPECT_EQ(frameSize, 56); // ======================================================================================= // Inject the frame stats with qp = 42. Expect not receiving notification as 42 goes beyond // threshold 40 but delta oes not go beyond the mQpChangeThreshold threshold. frameStats = SimpleEncodedFrameData(4 /* seq number */, FrameTypeP, 999999 /* framePtsUs */, 42 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); EXPECT_FALSE(getInfo); // ======================================================================================= // Inject the frame stats with qp = 10. Expect receiving notification as the detal from // last reported QP is larger than threshold 4. frameStats = SimpleEncodedFrameData(5 /* seq number */, FrameTypeB, 1333332 /* framePtsUs */, 49 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the frame info matches with the frame stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME); EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK); EXPECT_EQ(frameType, FrameTypeB); EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK); EXPECT_EQ(frameNum, 5); EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK); EXPECT_EQ(framePtsUs, 1333332); EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK); EXPECT_EQ(frameQp, 49); EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK); EXPECT_EQ(frameSize, 56); // ======================================================================================= // Inject the frame stats with qp = 41. Expect receiving notification as the detal from // last reported QP is larger than threshold 4. frameStats = SimpleEncodedFrameData(6 /* seq number */, FrameTypeB, 1666665 /* framePtsUs */, 41 /* avg-qp */, 56 /* frameSize */); getInfo = false; fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the frame info matches with the frame stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_FRAME); EXPECT_TRUE(info.findInt8(FRAME_TYPE, &frameType) == ECODataStatus::OK); EXPECT_EQ(frameType, FrameTypeB); EXPECT_TRUE(info.findInt32(FRAME_NUM, &frameNum) == ECODataStatus::OK); EXPECT_EQ(frameNum, 6); EXPECT_TRUE(info.findInt64(FRAME_PTS_US, &framePtsUs) == ECODataStatus::OK); EXPECT_EQ(framePtsUs, 1666665); EXPECT_TRUE(info.findInt32(FRAME_AVG_QP, &frameQp) == ECODataStatus::OK); EXPECT_EQ(frameQp, 41); EXPECT_TRUE(info.findInt32(FRAME_SIZE_BYTES, &frameSize) == ECODataStatus::OK); EXPECT_EQ(frameSize, 56); } TEST_F(EcoSessionTest, TestRemoveMatchProvider) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider1 = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res); EXPECT_TRUE(res); EXPECT_TRUE(status.isOk()); status = ecoSession->removeStatsProvider(fakeProvider1, &res); EXPECT_TRUE(res); EXPECT_TRUE(status.isOk()); } TEST_F(EcoSessionTest, TestRemoveMisMatchProvider) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); sp fakeProvider1 = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); bool res; Status status = ecoSession->addStatsProvider(fakeProvider1, providerConfig, &res); EXPECT_TRUE(res); EXPECT_TRUE(status.isOk()); sp fakeProvider2 = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); status = ecoSession->removeStatsProvider(fakeProvider2, &res); EXPECT_FALSE(res); EXPECT_FALSE(status.isOk()); } TEST_F(EcoSessionTest, TestRemoveMatchListener) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); // Create listener. sp fakeListener = new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession); // Create the listener config. ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener"); listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA); // Specify the qp thresholds for receiving notification. listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40); listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5); bool res; Status status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res); status = ecoSession->removeInfoListener(fakeListener, &res); EXPECT_TRUE(res); EXPECT_TRUE(status.isOk()); } TEST_F(EcoSessionTest, TestRemoveMisMatchListener) { sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); EXPECT_TRUE(ecoSession); // Create listener. sp fakeListener = new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession); // Create the listener config. ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener"); listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA); // Specify the qp thresholds for receiving notification. listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40); listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5); bool res; Status status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res); // Create listener. sp fakeListener2 = new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession); status = ecoSession->removeInfoListener(fakeListener2, &res); EXPECT_FALSE(res); EXPECT_FALSE(status.isOk()); } // Test the listener connects to the ECOSession after provider sends the session info. Listener // should recieve the session info right after adding itself to the ECOSession. TEST_F(EcoSessionTest, TestAddListenerAferProviderStarts) { // The time that listener needs to wait for the info from ECOService. static constexpr int kServiceWaitTimeMs = 10; // Create the session. sp ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording); // Add provider. sp fakeProvider = new FakeECOServiceStatsProvider( kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession); ECOData providerConfig(ECOData::DATA_TYPE_STATS_PROVIDER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); providerConfig.setString(KEY_PROVIDER_NAME, "FakeECOServiceStatsProvider"); providerConfig.setInt32(KEY_PROVIDER_TYPE, ECOServiceStatsProvider::STATS_PROVIDER_TYPE_VIDEO_ENCODER); bool res; Status status = ecoSession->addStatsProvider(fakeProvider, providerConfig, &res); // Inject the session stats into the ECOSession through fakeProvider. SimpleEncoderConfig sessionEncoderConfig("google-avc", CodecTypeAVC, AVCProfileHigh, AVCLevel52, kTargetBitrateBps, kKeyFrameIntervalFrames, kFrameRate); fakeProvider->injectSessionStats(sessionEncoderConfig.toEcoData(ECOData::DATA_TYPE_STATS)); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // ======================================================================================= // Inject the frame stats with qp = 30. Expect receiving notification for the first frame. SimpleEncodedFrameData frameStats(1 /* seq number */, FrameTypeI, 0 /* framePtsUs */, 30 /* avg-qp */, 56 /* frameSize */); fakeProvider->injectFrameStats(frameStats.toEcoData(ECOData::DATA_TYPE_STATS)); std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // ======================================================================================= // Create and add the listener to the ECOSession. Expect to receive the session infor right // after addInfoListener. sp fakeListener = new FakeECOServiceInfoListener(kTestWidth, kTestHeight, kIsCameraRecording, ecoSession); // Create the listener config. ECOData listenerConfig(ECOData::DATA_TYPE_INFO_LISTENER_CONFIG, systemTime(SYSTEM_TIME_BOOTTIME)); listenerConfig.setString(KEY_LISTENER_NAME, "FakeECOServiceInfoListener"); listenerConfig.setInt32(KEY_LISTENER_TYPE, ECOServiceInfoListener::INFO_LISTENER_TYPE_CAMERA); // Specify the qp thresholds for receiving notification. listenerConfig.setInt32(KEY_LISTENER_QP_BLOCKINESS_THRESHOLD, 40); listenerConfig.setInt32(KEY_LISTENER_QP_CHANGE_THRESHOLD, 5); ECOData info; bool getInfo = false; // Set the getInfo flag to true and copy the info from fakeListener. fakeListener->setInfoAvailableCallback( [&info, &getInfo](const ::android::media::eco::ECOData& newInfo) { getInfo = true; info = newInfo; }); status = ecoSession->addInfoListener(fakeListener, listenerConfig, &res); // Wait as ECOService may take some time to process. std::this_thread::sleep_for(std::chrono::milliseconds(kServiceWaitTimeMs)); // Check the Session info matches with the session stats sent by provider. EXPECT_TRUE(getInfo); EXPECT_TRUE(info.getDataType() == ECOData::DATA_TYPE_INFO); std::string infoType; EXPECT_TRUE(info.findString(KEY_INFO_TYPE, &infoType) == ECODataStatus::OK); EXPECT_EQ(infoType, VALUE_INFO_TYPE_SESSION); // Check the session info matches the session stats provided by FakeECOServiceStatsProvider. int32_t codecType; EXPECT_TRUE(info.findInt32(ENCODER_TYPE, &codecType) == ECODataStatus::OK); EXPECT_EQ(codecType, CodecTypeAVC); int32_t profile; EXPECT_TRUE(info.findInt32(ENCODER_PROFILE, &profile) == ECODataStatus::OK); EXPECT_EQ(profile, AVCProfileHigh); int32_t level; EXPECT_TRUE(info.findInt32(ENCODER_LEVEL, &level) == ECODataStatus::OK); EXPECT_EQ(level, AVCLevel52); int32_t bitrate; EXPECT_TRUE(info.findInt32(ENCODER_TARGET_BITRATE_BPS, &bitrate) == ECODataStatus::OK); EXPECT_EQ(bitrate, kTargetBitrateBps); int32_t kfi; EXPECT_TRUE(info.findInt32(ENCODER_KFI_FRAMES, &kfi) == ECODataStatus::OK); EXPECT_EQ(kfi, kKeyFrameIntervalFrames); } } // namespace eco } // namespace media } // namespace android