You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
609 lines
27 KiB
609 lines
27 KiB
/*
|
|
* 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 <android-base/unique_fd.h>
|
|
#include <binder/Parcel.h>
|
|
#include <binder/Parcelable.h>
|
|
#include <cutils/ashmem.h>
|
|
#include <gtest/gtest.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <sys/mman.h>
|
|
#include <utils/Log.h>
|
|
|
|
#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<ECOSession> createSession(int32_t width, int32_t height, bool isCameraRecording) {
|
|
mSession = ECOSession::createECOSession(width, height, isCameraRecording);
|
|
if (mSession == nullptr) return nullptr;
|
|
return mSession;
|
|
}
|
|
|
|
private:
|
|
sp<ECOSession> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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<FakeECOServiceStatsProvider> fakeProvider2 = new FakeECOServiceStatsProvider(
|
|
kTestWidth, kTestHeight, kIsCameraRecording, kFrameRate, ecoSession);
|
|
status = ecoSession->addStatsProvider(fakeProvider2, providerConfig, &res);
|
|
EXPECT_FALSE(status.isOk());
|
|
}
|
|
|
|
TEST_F(EcoSessionTest, TestAddListenerWithDifferentHeight) {
|
|
sp<ECOSession> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
|
|
// Add provider.
|
|
sp<FakeECOServiceStatsProvider> 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<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
sp<FakeECOServiceStatsProvider> 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<FakeECOServiceStatsProvider> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
// Create listener.
|
|
sp<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
EXPECT_TRUE(ecoSession);
|
|
|
|
// Create listener.
|
|
sp<FakeECOServiceInfoListener> 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<FakeECOServiceInfoListener> 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> ecoSession = createSession(kTestWidth, kTestHeight, kIsCameraRecording);
|
|
|
|
// Add provider.
|
|
sp<FakeECOServiceStatsProvider> 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<FakeECOServiceInfoListener> 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
|