Snap for 6586393 from 1fb7d06712
to rvc-release
Change-Id: I8433e9cb8553a2e9b0a5a475e01d5b64adb8effa
This commit is contained in:
commit
75f657465c
19 changed files with 441 additions and 249 deletions
33
camera/provider/2.4/vts/functional/AndroidTest.xml
Normal file
33
camera/provider/2.4/vts/functional/AndroidTest.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 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.
|
||||
-->
|
||||
<configuration description="Runs VtsHalCameraProviderV2_4TargetTest.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-native" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="VtsHalCameraProviderV2_4TargetTest->/data/local/tmp/VtsHalCameraProviderV2_4TargetTest" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalCameraProviderV2_4TargetTest" />
|
||||
<option name="native-test-timeout" value="180000"/>
|
||||
</test>
|
||||
</configuration>
|
|
@ -17,13 +17,13 @@ cc_test {
|
|||
"android.hardware.keymaster@4.0",
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libkeymaster_portable",
|
||||
"libsoft_attestation_cert",
|
||||
"libpuresoftkeymasterdevice",
|
||||
"android.hardware.keymaster-ndk_platform",
|
||||
],
|
||||
static_libs: [
|
||||
"libcppbor",
|
||||
"libkeymaster_portable",
|
||||
"libsoft_attestation_cert",
|
||||
"libpuresoftkeymasterdevice",
|
||||
"android.hardware.identity-support-lib",
|
||||
"android.hardware.identity-cpp",
|
||||
"android.hardware.keymaster-cpp",
|
||||
|
|
|
@ -49,7 +49,6 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
|
|||
}
|
||||
EXPECT_EQ(CardState::ABSENT, cardStatus.cardState);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test setSimCardPower power up */
|
||||
serial = GetRandomSerialNumber();
|
||||
|
@ -60,6 +59,7 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
|
|||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_1->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
|
||||
RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE}));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If the sim card status for the testing environment is PRESENT,
|
||||
|
|
|
@ -48,8 +48,6 @@ Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
|
|||
return Result::INVALID_STATE;
|
||||
}
|
||||
|
||||
mFrontendSourceFile = mFrontend->getSourceFile();
|
||||
|
||||
mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId);
|
||||
|
||||
return Result::SUCCESS;
|
||||
|
@ -62,8 +60,6 @@ Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
|
|||
uint32_t filterId;
|
||||
filterId = ++mLastUsedFilterId;
|
||||
|
||||
mUsedFilterIds.insert(filterId);
|
||||
|
||||
if (cb == nullptr) {
|
||||
ALOGW("[Demux] callback can't be null");
|
||||
_hidl_cb(Result::INVALID_ARGUMENT, new Filter());
|
||||
|
@ -82,8 +78,13 @@ Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
|
|||
mPcrFilterIds.insert(filterId);
|
||||
}
|
||||
bool result = true;
|
||||
if (mDvr != nullptr && mDvr->getType() == DvrType::PLAYBACK) {
|
||||
result = mDvr->addPlaybackFilter(filter);
|
||||
if (!filter->isRecordFilter()) {
|
||||
// Only save non-record filters for now. Record filters are saved when the
|
||||
// IDvr.attacheFilter is called.
|
||||
mPlaybackFilterIds.insert(filterId);
|
||||
if (mDvrPlayback != nullptr) {
|
||||
result = mDvrPlayback->addPlaybackFilter(filterId, filter);
|
||||
}
|
||||
}
|
||||
|
||||
_hidl_cb(result ? Result::SUCCESS : Result::INVALID_ARGUMENT, filter);
|
||||
|
@ -154,7 +155,13 @@ Return<void> Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_
|
|||
Return<Result> Demux::close() {
|
||||
ALOGV("%s", __FUNCTION__);
|
||||
|
||||
mUsedFilterIds.clear();
|
||||
set<uint32_t>::iterator it;
|
||||
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
|
||||
mDvrPlayback->removePlaybackFilter(*it);
|
||||
}
|
||||
mPlaybackFilterIds.clear();
|
||||
mRecordFilterIds.clear();
|
||||
mFilters.clear();
|
||||
mLastUsedFilterId = -1;
|
||||
|
||||
return Result::SUCCESS;
|
||||
|
@ -170,15 +177,38 @@ Return<void> Demux::openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCall
|
|||
return Void();
|
||||
}
|
||||
|
||||
mDvr = new Dvr(type, bufferSize, cb, this);
|
||||
set<uint32_t>::iterator it;
|
||||
switch (type) {
|
||||
case DvrType::PLAYBACK:
|
||||
mDvrPlayback = new Dvr(type, bufferSize, cb, this);
|
||||
if (!mDvrPlayback->createDvrMQ()) {
|
||||
_hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
|
||||
return Void();
|
||||
}
|
||||
|
||||
if (!mDvr->createDvrMQ()) {
|
||||
_hidl_cb(Result::UNKNOWN_ERROR, mDvr);
|
||||
return Void();
|
||||
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
|
||||
if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) {
|
||||
ALOGE("[Demux] Can't get filter info for DVR playback");
|
||||
_hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
|
||||
return Void();
|
||||
}
|
||||
}
|
||||
|
||||
_hidl_cb(Result::SUCCESS, mDvrPlayback);
|
||||
return Void();
|
||||
case DvrType::RECORD:
|
||||
mDvrRecord = new Dvr(type, bufferSize, cb, this);
|
||||
if (!mDvrRecord->createDvrMQ()) {
|
||||
_hidl_cb(Result::UNKNOWN_ERROR, mDvrRecord);
|
||||
return Void();
|
||||
}
|
||||
|
||||
_hidl_cb(Result::SUCCESS, mDvrRecord);
|
||||
return Void();
|
||||
default:
|
||||
_hidl_cb(Result::INVALID_ARGUMENT, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
_hidl_cb(Result::SUCCESS, mDvr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
|
||||
|
@ -198,8 +228,10 @@ Return<Result> Demux::disconnectCiCam() {
|
|||
Result Demux::removeFilter(uint32_t filterId) {
|
||||
ALOGV("%s", __FUNCTION__);
|
||||
|
||||
// resetFilterRecords(filterId);
|
||||
mUsedFilterIds.erase(filterId);
|
||||
if (mDvrPlayback != nullptr) {
|
||||
mDvrPlayback->removePlaybackFilter(filterId);
|
||||
}
|
||||
mPlaybackFilterIds.erase(filterId);
|
||||
mRecordFilterIds.erase(filterId);
|
||||
mFilters.erase(filterId);
|
||||
|
||||
|
@ -212,7 +244,7 @@ void Demux::startBroadcastTsFilter(vector<uint8_t> data) {
|
|||
if (DEBUG_DEMUX) {
|
||||
ALOGW("[Demux] start ts filter pid: %d", pid);
|
||||
}
|
||||
for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
|
||||
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
|
||||
if (pid == mFilters[*it]->getTpid()) {
|
||||
mFilters[*it]->updateFilterOutput(data);
|
||||
}
|
||||
|
@ -233,7 +265,7 @@ bool Demux::startBroadcastFilterDispatcher() {
|
|||
set<uint32_t>::iterator it;
|
||||
|
||||
// Handle the output data per filter type
|
||||
for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
|
||||
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
|
||||
if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
@ -280,58 +312,27 @@ void* Demux::__threadLoopFrontend(void* user) {
|
|||
void Demux::frontendInputThreadLoop() {
|
||||
std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
|
||||
mFrontendInputThreadRunning = true;
|
||||
mKeepFetchingDataFromFrontend = true;
|
||||
|
||||
// open the stream and get its length
|
||||
std::ifstream inputData(mFrontendSourceFile, std::ifstream::binary);
|
||||
// TODO take the packet size from the frontend setting
|
||||
int packetSize = 188;
|
||||
int writePacketAmount = 6;
|
||||
char* buffer = new char[packetSize];
|
||||
ALOGW("[Demux] Frontend input thread loop start %s", mFrontendSourceFile.c_str());
|
||||
if (!inputData.is_open()) {
|
||||
mFrontendInputThreadRunning = false;
|
||||
ALOGW("[Demux] Error %s", strerror(errno));
|
||||
}
|
||||
|
||||
while (mFrontendInputThreadRunning) {
|
||||
// move the stream pointer for packet size * 6 every read until the end
|
||||
while (mKeepFetchingDataFromFrontend) {
|
||||
for (int i = 0; i < writePacketAmount; i++) {
|
||||
inputData.read(buffer, packetSize);
|
||||
if (!inputData) {
|
||||
mKeepFetchingDataFromFrontend = false;
|
||||
mFrontendInputThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
// filter and dispatch filter output
|
||||
vector<uint8_t> byteBuffer;
|
||||
byteBuffer.resize(packetSize);
|
||||
for (int index = 0; index < byteBuffer.size(); index++) {
|
||||
byteBuffer[index] = static_cast<uint8_t>(buffer[index]);
|
||||
}
|
||||
if (mIsRecording) {
|
||||
// Feed the data into the Dvr recording input
|
||||
sendFrontendInputToRecord(byteBuffer);
|
||||
} else {
|
||||
// Feed the data into the broadcast demux filter
|
||||
startBroadcastTsFilter(byteBuffer);
|
||||
}
|
||||
}
|
||||
if (mIsRecording) {
|
||||
// Dispatch the data into the broadcasting filters.
|
||||
startRecordFilterDispatcher();
|
||||
} else {
|
||||
// Dispatch the data into the broadcasting filters.
|
||||
startBroadcastFilterDispatcher();
|
||||
}
|
||||
usleep(100);
|
||||
uint32_t efState = 0;
|
||||
status_t status = mDvrPlayback->getDvrEventFlag()->wait(
|
||||
static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
|
||||
true /* retry on spurious wake */);
|
||||
if (status != OK) {
|
||||
ALOGD("[Demux] wait for data ready on the playback FMQ");
|
||||
continue;
|
||||
}
|
||||
// Our current implementation filter the data and write it into the filter FMQ immediately
|
||||
// after the DATA_READY from the VTS/framework
|
||||
if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
|
||||
!mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
|
||||
ALOGE("[Demux] playback data failed to be filtered. Ending thread");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mFrontendInputThreadRunning = false;
|
||||
ALOGW("[Demux] Frontend Input thread end.");
|
||||
delete[] buffer;
|
||||
inputData.close();
|
||||
}
|
||||
|
||||
void Demux::stopFrontendInput() {
|
||||
|
@ -346,18 +347,19 @@ void Demux::setIsRecording(bool isRecording) {
|
|||
}
|
||||
|
||||
bool Demux::attachRecordFilter(int filterId) {
|
||||
if (mFilters[filterId] == nullptr || mDvr == nullptr) {
|
||||
if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
|
||||
!mFilters[filterId]->isRecordFilter()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRecordFilterIds.insert(filterId);
|
||||
mFilters[filterId]->attachFilterToRecord(mDvr);
|
||||
mFilters[filterId]->attachFilterToRecord(mDvrRecord);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Demux::detachRecordFilter(int filterId) {
|
||||
if (mFilters[filterId] == nullptr || mDvr == nullptr) {
|
||||
if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,13 +91,23 @@ class Demux : public IDemux {
|
|||
void setIsRecording(bool isRecording);
|
||||
void startFrontendInputLoop();
|
||||
|
||||
/**
|
||||
* A dispatcher to read and dispatch input data to all the started filters.
|
||||
* Each filter handler handles the data filtering/output writing/filterEvent updating.
|
||||
* Note that recording filters are not included.
|
||||
*/
|
||||
bool startBroadcastFilterDispatcher();
|
||||
void startBroadcastTsFilter(vector<uint8_t> data);
|
||||
|
||||
void sendFrontendInputToRecord(vector<uint8_t> data);
|
||||
bool startRecordFilterDispatcher();
|
||||
|
||||
private:
|
||||
// Tuner service
|
||||
sp<Tuner> mTunerService;
|
||||
|
||||
// Frontend source
|
||||
sp<Frontend> mFrontend;
|
||||
string mFrontendSourceFile;
|
||||
|
||||
// A struct that passes the arguments to a newly created filter thread
|
||||
struct ThreadArgs {
|
||||
|
@ -117,16 +127,6 @@ class Demux : public IDemux {
|
|||
*/
|
||||
void deleteEventFlag();
|
||||
bool readDataFromMQ();
|
||||
/**
|
||||
* A dispatcher to read and dispatch input data to all the started filters.
|
||||
* Each filter handler handles the data filtering/output writing/filterEvent updating.
|
||||
* Note that recording filters are not included.
|
||||
*/
|
||||
bool startBroadcastFilterDispatcher();
|
||||
void startBroadcastTsFilter(vector<uint8_t> data);
|
||||
|
||||
void sendFrontendInputToRecord(vector<uint8_t> data);
|
||||
bool startRecordFilterDispatcher();
|
||||
|
||||
uint32_t mDemuxId;
|
||||
uint32_t mCiCamId;
|
||||
|
@ -137,17 +137,17 @@ class Demux : public IDemux {
|
|||
*/
|
||||
uint32_t mLastUsedFilterId = -1;
|
||||
/**
|
||||
* Record all the used filter Ids.
|
||||
* Record all the used playback filter Ids.
|
||||
* Any removed filter id should be removed from this set.
|
||||
*/
|
||||
set<uint32_t> mUsedFilterIds;
|
||||
set<uint32_t> mPlaybackFilterIds;
|
||||
/**
|
||||
* Record all the attached record filter Ids.
|
||||
* Any removed filter id should be removed from this set.
|
||||
*/
|
||||
set<uint32_t> mRecordFilterIds;
|
||||
/**
|
||||
* A list of created FilterMQ ptrs.
|
||||
* A list of created Filter sp.
|
||||
* The array number is the filter ID.
|
||||
*/
|
||||
std::map<uint32_t, sp<Filter>> mFilters;
|
||||
|
@ -160,7 +160,8 @@ class Demux : public IDemux {
|
|||
/**
|
||||
* Local reference to the opened DVR object.
|
||||
*/
|
||||
sp<Dvr> mDvr;
|
||||
sp<Dvr> mDvrPlayback;
|
||||
sp<Dvr> mDvrRecord;
|
||||
|
||||
// Thread handlers
|
||||
pthread_t mFrontendInputThread;
|
||||
|
|
|
@ -70,8 +70,7 @@ Return<Result> Dvr::attachFilter(const sp<IFilter>& filter) {
|
|||
return status;
|
||||
}
|
||||
|
||||
// check if the attached filter is a record filter
|
||||
mFilters[filterId] = filter;
|
||||
// TODO check if the attached filter is a record filter
|
||||
if (!mDemux->attachRecordFilter(filterId)) {
|
||||
return Result::INVALID_ARGUMENT;
|
||||
}
|
||||
|
@ -94,19 +93,8 @@ Return<Result> Dvr::detachFilter(const sp<IFilter>& filter) {
|
|||
return status;
|
||||
}
|
||||
|
||||
std::map<uint32_t, sp<IFilter>>::iterator it;
|
||||
|
||||
it = mFilters.find(filterId);
|
||||
if (it != mFilters.end()) {
|
||||
mFilters.erase(filterId);
|
||||
if (!mDemux->detachRecordFilter(filterId)) {
|
||||
return Result::INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
// If all the filters are detached, record can't be started
|
||||
if (mFilters.empty()) {
|
||||
mIsRecordFilterAttached = false;
|
||||
if (!mDemux->detachRecordFilter(filterId)) {
|
||||
return Result::INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return Result::SUCCESS;
|
||||
|
@ -183,6 +171,10 @@ bool Dvr::createDvrMQ() {
|
|||
return true;
|
||||
}
|
||||
|
||||
EventFlag* Dvr::getDvrEventFlag() {
|
||||
return mDvrEventFlag;
|
||||
}
|
||||
|
||||
void* Dvr::__threadLoopPlayback(void* user) {
|
||||
Dvr* const self = static_cast<Dvr*>(user);
|
||||
self->playbackThreadLoop();
|
||||
|
@ -205,8 +197,9 @@ void Dvr::playbackThreadLoop() {
|
|||
}
|
||||
// Our current implementation filter the data and write it into the filter FMQ immediately
|
||||
// after the DATA_READY from the VTS/framework
|
||||
if (!readPlaybackFMQ() || !startFilterDispatcher()) {
|
||||
ALOGD("[Dvr] playback data failed to be filtered. Ending thread");
|
||||
if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) ||
|
||||
!startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) {
|
||||
ALOGE("[Dvr] playback data failed to be filtered. Ending thread");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -245,7 +238,7 @@ PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_
|
|||
return mPlaybackStatus;
|
||||
}
|
||||
|
||||
bool Dvr::readPlaybackFMQ() {
|
||||
bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) {
|
||||
// Read playback data from the input FMQ
|
||||
int size = mDvrMQ->availableToRead();
|
||||
int playbackPacketSize = mDvrSettings.playback().packetSize;
|
||||
|
@ -256,7 +249,15 @@ bool Dvr::readPlaybackFMQ() {
|
|||
if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) {
|
||||
return false;
|
||||
}
|
||||
startTpidFilter(dataOutputBuffer);
|
||||
if (isVirtualFrontend) {
|
||||
if (isRecording) {
|
||||
mDemux->sendFrontendInputToRecord(dataOutputBuffer);
|
||||
} else {
|
||||
mDemux->startBroadcastTsFilter(dataOutputBuffer);
|
||||
}
|
||||
} else {
|
||||
startTpidFilter(dataOutputBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -275,7 +276,15 @@ void Dvr::startTpidFilter(vector<uint8_t> data) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Dvr::startFilterDispatcher() {
|
||||
bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) {
|
||||
if (isVirtualFrontend) {
|
||||
if (isRecording) {
|
||||
return mDemux->startRecordFilterDispatcher();
|
||||
} else {
|
||||
return mDemux->startBroadcastFilterDispatcher();
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, sp<IFilter>>::iterator it;
|
||||
// Handle the output data per filter type
|
||||
for (it = mFilters.begin(); it != mFilters.end(); it++) {
|
||||
|
@ -329,27 +338,15 @@ RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t av
|
|||
return mRecordStatus;
|
||||
}
|
||||
|
||||
bool Dvr::addPlaybackFilter(sp<IFilter> filter) {
|
||||
uint32_t filterId;
|
||||
Result status;
|
||||
|
||||
filter->getId([&](Result result, uint32_t id) {
|
||||
filterId = id;
|
||||
status = result;
|
||||
});
|
||||
|
||||
if (status != Result::SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Dvr::addPlaybackFilter(uint32_t filterId, sp<IFilter> filter) {
|
||||
mFilters[filterId] = filter;
|
||||
return true;
|
||||
}
|
||||
|
||||
DvrType Dvr::getType() {
|
||||
return mType;
|
||||
bool Dvr::removePlaybackFilter(uint32_t filterId) {
|
||||
mFilters.erase(filterId);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace tuner
|
||||
|
|
|
@ -81,8 +81,11 @@ class Dvr : public IDvr {
|
|||
bool createDvrMQ();
|
||||
void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer);
|
||||
bool writeRecordFMQ(const std::vector<uint8_t>& data);
|
||||
DvrType getType();
|
||||
bool addPlaybackFilter(sp<IFilter> filter);
|
||||
bool addPlaybackFilter(uint32_t filterId, sp<IFilter> filter);
|
||||
bool removePlaybackFilter(uint32_t filterId);
|
||||
bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording);
|
||||
bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording);
|
||||
EventFlag* getDvrEventFlag();
|
||||
|
||||
private:
|
||||
// Demux service
|
||||
|
@ -105,9 +108,7 @@ class Dvr : public IDvr {
|
|||
* A dispatcher to read and dispatch input data to all the started filters.
|
||||
* Each filter handler handles the data filtering/output writing/filterEvent updating.
|
||||
*/
|
||||
bool readPlaybackFMQ();
|
||||
void startTpidFilter(vector<uint8_t> data);
|
||||
bool startFilterDispatcher();
|
||||
static void* __threadLoopPlayback(void* user);
|
||||
static void* __threadLoopRecord(void* user);
|
||||
void playbackThreadLoop();
|
||||
|
@ -123,7 +124,6 @@ class Dvr : public IDvr {
|
|||
|
||||
// Thread handlers
|
||||
pthread_t mDvrThread;
|
||||
pthread_t mBroadcastInputThread;
|
||||
|
||||
// FMQ status local records
|
||||
PlaybackStatus mPlaybackStatus;
|
||||
|
@ -132,7 +132,6 @@ class Dvr : public IDvr {
|
|||
* If a specific filter's writing loop is still running
|
||||
*/
|
||||
bool mDvrThreadRunning;
|
||||
bool mBroadcastInputThreadRunning;
|
||||
bool mKeepFetchingDataFromFrontend;
|
||||
/**
|
||||
* Lock to protect writes to the FMQs
|
||||
|
@ -143,7 +142,6 @@ class Dvr : public IDvr {
|
|||
*/
|
||||
std::mutex mPlaybackStatusLock;
|
||||
std::mutex mRecordStatusLock;
|
||||
std::mutex mBroadcastInputThreadLock;
|
||||
std::mutex mDvrThreadLock;
|
||||
|
||||
const bool DEBUG_DVR = false;
|
||||
|
@ -151,7 +149,6 @@ class Dvr : public IDvr {
|
|||
// Booleans to check if recording is running.
|
||||
// Recording is ready when both of the following are set to true.
|
||||
bool mIsRecordStarted = false;
|
||||
bool mIsRecordFilterAttached = false;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
|
|
|
@ -47,12 +47,18 @@ Filter::Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize,
|
|||
if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) {
|
||||
mIsPcrFilter = true;
|
||||
}
|
||||
if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) {
|
||||
mIsRecordFilter = true;
|
||||
}
|
||||
break;
|
||||
case DemuxFilterMainType::MMTP:
|
||||
if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
|
||||
mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
|
||||
mIsMediaFilter = true;
|
||||
}
|
||||
if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) {
|
||||
mIsRecordFilter = true;
|
||||
}
|
||||
break;
|
||||
case DemuxFilterMainType::IP:
|
||||
break;
|
||||
|
@ -535,12 +541,6 @@ Result Filter::startMediaFilterHandler() {
|
|||
}
|
||||
|
||||
Result Filter::startRecordFilterHandler() {
|
||||
/*DemuxFilterTsRecordEvent tsRecordEvent;
|
||||
tsRecordEvent.pid.tPid(0);
|
||||
tsRecordEvent.indexMask.tsIndexMask(0x01);
|
||||
mFilterEvent.events.resize(1);
|
||||
mFilterEvent.events[0].tsRecord(tsRecordEvent);
|
||||
*/
|
||||
std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
|
||||
if (mRecordFilterOutput.empty()) {
|
||||
return Result::SUCCESS;
|
||||
|
@ -567,7 +567,7 @@ Result Filter::startTemiFilterHandler() {
|
|||
|
||||
bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
|
||||
// TODO check how many sections has been read
|
||||
ALOGD("[Filter] section hander");
|
||||
ALOGD("[Filter] section handler");
|
||||
std::lock_guard<std::mutex> lock(mFilterEventLock);
|
||||
if (!writeDataToFilterMQ(data)) {
|
||||
return false;
|
||||
|
|
|
@ -91,6 +91,7 @@ class Filter : public IFilter {
|
|||
void freeAvHandle();
|
||||
bool isMediaFilter() { return mIsMediaFilter; };
|
||||
bool isPcrFilter() { return mIsPcrFilter; };
|
||||
bool isRecordFilter() { return mIsRecordFilter; };
|
||||
|
||||
private:
|
||||
// Tuner service
|
||||
|
@ -107,6 +108,7 @@ class Filter : public IFilter {
|
|||
DemuxFilterType mType;
|
||||
bool mIsMediaFilter = false;
|
||||
bool mIsPcrFilter = false;
|
||||
bool mIsRecordFilter = false;
|
||||
DemuxFilterSettings mFilterSettings;
|
||||
|
||||
uint16_t mTpid;
|
||||
|
|
|
@ -66,7 +66,7 @@ Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
|
|||
|
||||
mTunerService->frontendStartTune(mId);
|
||||
mCallback->onEvent(FrontendEventType::LOCKED);
|
||||
mIsLocked = false;
|
||||
mIsLocked = true;
|
||||
return Result::SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -268,14 +268,14 @@ FrontendId Frontend::getFrontendId() {
|
|||
return mId;
|
||||
}
|
||||
|
||||
string Frontend::getSourceFile() {
|
||||
return FRONTEND_STREAM_FILE;
|
||||
}
|
||||
|
||||
bool Frontend::supportsSatellite() {
|
||||
return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
|
||||
mType == FrontendType::ISDBS3;
|
||||
}
|
||||
|
||||
bool Frontend::isLocked() {
|
||||
return mIsLocked;
|
||||
}
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace tuner
|
||||
|
|
|
@ -68,6 +68,8 @@ class Frontend : public IFrontend {
|
|||
|
||||
string getSourceFile();
|
||||
|
||||
bool isLocked();
|
||||
|
||||
private:
|
||||
virtual ~Frontend();
|
||||
bool supportsSatellite();
|
||||
|
@ -77,7 +79,6 @@ class Frontend : public IFrontend {
|
|||
FrontendId mId = 0;
|
||||
bool mIsLocked = false;
|
||||
|
||||
const string FRONTEND_STREAM_FILE = "/vendor/etc/segment000000.ts";
|
||||
std::ifstream mFrontendData;
|
||||
};
|
||||
|
||||
|
|
|
@ -231,6 +231,9 @@ Return<void> Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_
|
|||
|
||||
void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
|
||||
mFrontendToDemux[frontendId] = demuxId;
|
||||
if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
|
||||
mDemuxes[demuxId]->startFrontendInputLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void Tuner::frontendStopTune(uint32_t frontendId) {
|
||||
|
|
|
@ -49,49 +49,73 @@ void DvrCallback::playbackThreadLoop() {
|
|||
EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) ==
|
||||
android::OK);
|
||||
|
||||
// open the stream and get its length
|
||||
std::ifstream inputData(mInputDataFile.c_str(), std::ifstream::binary);
|
||||
int writeSize = mPlaybackSettings.packetSize * 6;
|
||||
char* buffer = new char[writeSize];
|
||||
ALOGW("[vts] playback thread loop start %s!", mInputDataFile.c_str());
|
||||
if (!inputData.is_open()) {
|
||||
int fd = open(mInputDataFile.c_str(), O_RDONLY | O_LARGEFILE);
|
||||
int readBytes;
|
||||
uint32_t regionSize = 0;
|
||||
uint8_t* buffer;
|
||||
ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str());
|
||||
if (fd < 0) {
|
||||
mPlaybackThreadRunning = false;
|
||||
ALOGW("[vts] Error %s", strerror(errno));
|
||||
}
|
||||
|
||||
while (mPlaybackThreadRunning) {
|
||||
// move the stream pointer for packet size * 6 every read until the end
|
||||
while (mKeepWritingPlaybackFMQ) {
|
||||
inputData.read(buffer, writeSize);
|
||||
if (!inputData) {
|
||||
int leftSize = inputData.gcount();
|
||||
if (leftSize == 0) {
|
||||
mPlaybackThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
inputData.clear();
|
||||
inputData.read(buffer, leftSize);
|
||||
// Write the left over of the input data and quit the thread
|
||||
if (leftSize > 0) {
|
||||
EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], leftSize));
|
||||
playbackMQEventFlag->wake(
|
||||
static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
|
||||
}
|
||||
int totalWrite = mPlaybackMQ->availableToWrite();
|
||||
if (totalWrite * 4 < mPlaybackMQ->getQuantumCount()) {
|
||||
// Wait for the HAL implementation to read more data then write.
|
||||
continue;
|
||||
}
|
||||
MessageQueue<uint8_t, kSynchronizedReadWrite>::MemTransaction memTx;
|
||||
if (!mPlaybackMQ->beginWrite(totalWrite, &memTx)) {
|
||||
ALOGW("[vts] Fail to write into Playback fmq.");
|
||||
mPlaybackThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
auto first = memTx.getFirstRegion();
|
||||
buffer = first.getAddress();
|
||||
regionSize = first.getLength();
|
||||
|
||||
if (regionSize > 0) {
|
||||
readBytes = read(fd, buffer, regionSize);
|
||||
if (readBytes <= 0) {
|
||||
if (readBytes < 0) {
|
||||
ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str());
|
||||
} else {
|
||||
ALOGW("[vts] playback input EOF.");
|
||||
}
|
||||
mPlaybackThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (regionSize == 0 || (readBytes == regionSize && regionSize < totalWrite)) {
|
||||
auto second = memTx.getSecondRegion();
|
||||
buffer = second.getAddress();
|
||||
regionSize = second.getLength();
|
||||
int ret = read(fd, buffer, regionSize);
|
||||
if (ret <= 0) {
|
||||
if (ret < 0) {
|
||||
ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str());
|
||||
} else {
|
||||
ALOGW("[vts] playback input EOF.");
|
||||
}
|
||||
mPlaybackThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
readBytes += ret;
|
||||
}
|
||||
if (!mPlaybackMQ->commitWrite(readBytes)) {
|
||||
ALOGW("[vts] Failed to commit write playback fmq.");
|
||||
mPlaybackThreadRunning = false;
|
||||
break;
|
||||
}
|
||||
// Write input FMQ and notify the Tuner Implementation
|
||||
EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], writeSize));
|
||||
playbackMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
|
||||
inputData.seekg(writeSize, inputData.cur);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
mPlaybackThreadRunning = false;
|
||||
ALOGW("[vts] Playback thread end.");
|
||||
|
||||
delete[] buffer;
|
||||
inputData.close();
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void DvrCallback::testRecordOutput() {
|
||||
|
@ -186,32 +210,65 @@ AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) {
|
|||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
|
||||
// Create dvr callback
|
||||
mDvrCallback = new DvrCallback();
|
||||
if (type == DvrType::PLAYBACK) {
|
||||
mDvrPlaybackCallback = new DvrCallback();
|
||||
mDemux->openDvr(type, bufferSize, mDvrPlaybackCallback,
|
||||
[&](Result result, const sp<IDvr>& dvr) {
|
||||
mDvrPlayback = dvr;
|
||||
status = result;
|
||||
});
|
||||
if (status == Result::SUCCESS) {
|
||||
mDvrPlaybackCallback->setDvr(mDvrPlayback);
|
||||
}
|
||||
}
|
||||
|
||||
mDemux->openDvr(type, bufferSize, mDvrCallback, [&](Result result, const sp<IDvr>& dvr) {
|
||||
mDvr = dvr;
|
||||
if (type == DvrType::RECORD) {
|
||||
mDvrRecordCallback = new DvrCallback();
|
||||
mDemux->openDvr(type, bufferSize, mDvrRecordCallback,
|
||||
[&](Result result, const sp<IDvr>& dvr) {
|
||||
mDvrRecord = dvr;
|
||||
status = result;
|
||||
});
|
||||
if (status == Result::SUCCESS) {
|
||||
mDvrRecordCallback->setDvr(mDvrRecord);
|
||||
}
|
||||
}
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::configDvrPlayback(DvrSettings setting) {
|
||||
Result status = mDvrPlayback->configure(setting);
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::configDvrRecord(DvrSettings setting) {
|
||||
Result status = mDvrRecord->configure(setting);
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::getDvrPlaybackMQDescriptor() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
|
||||
|
||||
mDvrPlayback->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
|
||||
mDvrPlaybackMQDescriptor = dvrMQDesc;
|
||||
status = result;
|
||||
});
|
||||
|
||||
if (status == Result::SUCCESS) {
|
||||
mDvrCallback->setDvr(mDvr);
|
||||
}
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::configDvr(DvrSettings setting) {
|
||||
Result status = mDvr->configure(setting);
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::getDvrMQDescriptor() {
|
||||
AssertionResult DvrTests::getDvrRecordMQDescriptor() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
|
||||
EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
|
||||
|
||||
mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
|
||||
mDvrMQDescriptor = dvrMQDesc;
|
||||
mDvrRecord->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
|
||||
mDvrRecordMQDescriptor = dvrMQDesc;
|
||||
status = result;
|
||||
});
|
||||
|
||||
|
@ -221,9 +278,9 @@ AssertionResult DvrTests::getDvrMQDescriptor() {
|
|||
AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
|
||||
EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
|
||||
|
||||
status = mDvr->attachFilter(filter);
|
||||
status = mDvrRecord->attachFilter(filter);
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
@ -231,35 +288,61 @@ AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) {
|
|||
AssertionResult DvrTests::detachFilterToDvr(sp<IFilter> filter) {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
|
||||
EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
|
||||
|
||||
status = mDvr->detachFilter(filter);
|
||||
status = mDvrRecord->detachFilter(filter);
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::startDvr() {
|
||||
AssertionResult DvrTests::startDvrPlayback() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
|
||||
EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
|
||||
|
||||
status = mDvr->start();
|
||||
status = mDvrPlayback->start();
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::stopDvr() {
|
||||
AssertionResult DvrTests::stopDvrPlayback() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
|
||||
EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
|
||||
|
||||
status = mDvr->stop();
|
||||
status = mDvrPlayback->stop();
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
void DvrTests::closeDvr() {
|
||||
void DvrTests::closeDvrPlayback() {
|
||||
ASSERT_TRUE(mDemux);
|
||||
ASSERT_TRUE(mDvr);
|
||||
ASSERT_TRUE(mDvr->close() == Result::SUCCESS);
|
||||
ASSERT_TRUE(mDvrPlayback);
|
||||
ASSERT_TRUE(mDvrPlayback->close() == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::startDvrRecord() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
|
||||
|
||||
status = mDvrRecord->start();
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult DvrTests::stopDvrRecord() {
|
||||
Result status;
|
||||
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
|
||||
EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
|
||||
|
||||
status = mDvrRecord->stop();
|
||||
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
void DvrTests::closeDvrRecord() {
|
||||
ASSERT_TRUE(mDemux);
|
||||
ASSERT_TRUE(mDvrRecord);
|
||||
ASSERT_TRUE(mDvrRecord->close() == Result::SUCCESS);
|
||||
}
|
||||
|
|
|
@ -14,14 +14,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <VtsHalHidlTargetTestEnvBase.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/tv/tuner/1.0/IDvr.h>
|
||||
#include <android/hardware/tv/tuner/1.0/IDvrCallback.h>
|
||||
#include <android/hardware/tv/tuner/1.0/ITuner.h>
|
||||
#include <android/hardware/tv/tuner/1.0/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <fmq/MessageQueue.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/Mutex.h>
|
||||
|
@ -52,6 +53,8 @@ using android::hardware::tv::tuner::V1_0::RecordSettings;
|
|||
using android::hardware::tv::tuner::V1_0::RecordStatus;
|
||||
using android::hardware::tv::tuner::V1_0::Result;
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WAIT_TIMEOUT 3000000000
|
||||
|
||||
class DvrCallback : public IDvrCallback {
|
||||
|
@ -149,25 +152,31 @@ class DvrTests {
|
|||
void setDemux(sp<IDemux> demux) { mDemux = demux; }
|
||||
|
||||
void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) {
|
||||
mDvrCallback->startPlaybackInputThread(dataInputFile, settings, mDvrMQDescriptor);
|
||||
mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings,
|
||||
mDvrPlaybackMQDescriptor);
|
||||
};
|
||||
|
||||
void startRecordOutputThread(RecordSettings settings) {
|
||||
mDvrCallback->startRecordOutputThread(settings, mDvrMQDescriptor);
|
||||
mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor);
|
||||
};
|
||||
|
||||
void stopPlaybackThread() { mDvrCallback->stopPlaybackThread(); }
|
||||
void testRecordOutput() { mDvrCallback->testRecordOutput(); }
|
||||
void stopRecordThread() { mDvrCallback->stopPlaybackThread(); }
|
||||
void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); }
|
||||
void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); }
|
||||
void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); }
|
||||
|
||||
AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize);
|
||||
AssertionResult configDvr(DvrSettings setting);
|
||||
AssertionResult getDvrMQDescriptor();
|
||||
AssertionResult configDvrPlayback(DvrSettings setting);
|
||||
AssertionResult configDvrRecord(DvrSettings setting);
|
||||
AssertionResult getDvrPlaybackMQDescriptor();
|
||||
AssertionResult getDvrRecordMQDescriptor();
|
||||
AssertionResult attachFilterToDvr(sp<IFilter> filter);
|
||||
AssertionResult detachFilterToDvr(sp<IFilter> filter);
|
||||
AssertionResult stopDvr();
|
||||
AssertionResult startDvr();
|
||||
void closeDvr();
|
||||
AssertionResult stopDvrPlayback();
|
||||
AssertionResult startDvrPlayback();
|
||||
AssertionResult stopDvrRecord();
|
||||
AssertionResult startDvrRecord();
|
||||
void closeDvrPlayback();
|
||||
void closeDvrRecord();
|
||||
|
||||
protected:
|
||||
static AssertionResult failure() { return ::testing::AssertionFailure(); }
|
||||
|
@ -175,11 +184,11 @@ class DvrTests {
|
|||
static AssertionResult success() { return ::testing::AssertionSuccess(); }
|
||||
|
||||
sp<ITuner> mService;
|
||||
sp<IDvr> mDvr;
|
||||
sp<IDvr> mDvrPlayback;
|
||||
sp<IDvr> mDvrRecord;
|
||||
sp<IDemux> mDemux;
|
||||
sp<DvrCallback> mDvrCallback;
|
||||
MQDesc mDvrMQDescriptor;
|
||||
|
||||
pthread_t mPlaybackshread;
|
||||
bool mPlaybackThreadRunning;
|
||||
sp<DvrCallback> mDvrPlaybackCallback;
|
||||
sp<DvrCallback> mDvrRecordCallback;
|
||||
MQDesc mDvrPlaybackMQDescriptor;
|
||||
MQDesc mDvrRecordMQDescriptor;
|
||||
};
|
||||
|
|
|
@ -360,13 +360,28 @@ void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
|
|||
ASSERT_TRUE(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult FrontendTests::tuneFrontend(FrontendConfig config) {
|
||||
AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) {
|
||||
EXPECT_TRUE(mFrontendCallback)
|
||||
<< "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
|
||||
|
||||
EXPECT_TRUE(mFrontendInfo.type == config.type)
|
||||
<< "FrontendConfig does not match the frontend info of the given id.";
|
||||
|
||||
mIsSoftwareFe = config.isSoftwareFe;
|
||||
bool result = true;
|
||||
if (mIsSoftwareFe && testWithDemux) {
|
||||
DvrConfig dvrConfig;
|
||||
getSoftwareFrontendPlaybackConfig(dvrConfig);
|
||||
result &= mDvrTests.openDvrInDemux(dvrConfig.type, dvrConfig.bufferSize) == success();
|
||||
result &= mDvrTests.configDvrPlayback(dvrConfig.settings) == success();
|
||||
result &= mDvrTests.getDvrPlaybackMQDescriptor() == success();
|
||||
mDvrTests.startPlaybackInputThread(dvrConfig.playbackInputFile,
|
||||
dvrConfig.settings.playback());
|
||||
if (!result) {
|
||||
ALOGW("[vts] Software frontend dvr configure failed.");
|
||||
return failure();
|
||||
}
|
||||
}
|
||||
mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
|
||||
return AssertionResult(true);
|
||||
}
|
||||
|
@ -379,10 +394,14 @@ AssertionResult FrontendTests::setLnb(uint32_t lnbId) {
|
|||
return AssertionResult(mFrontend->setLnb(lnbId) == Result::SUCCESS);
|
||||
}
|
||||
|
||||
AssertionResult FrontendTests::stopTuneFrontend() {
|
||||
AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) {
|
||||
EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
|
||||
Result status;
|
||||
status = mFrontend->stopTune();
|
||||
if (mIsSoftwareFe && testWithDemux) {
|
||||
mDvrTests.stopPlaybackThread();
|
||||
mDvrTests.closeDvrPlayback();
|
||||
}
|
||||
return AssertionResult(status == Result::SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -415,9 +434,9 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) {
|
|||
ASSERT_TRUE(feId != INVALID_ID);
|
||||
ASSERT_TRUE(openFrontendById(feId));
|
||||
ASSERT_TRUE(setFrontendCallback());
|
||||
ASSERT_TRUE(tuneFrontend(frontendConf));
|
||||
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
|
||||
verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
|
||||
ASSERT_TRUE(stopTuneFrontend());
|
||||
ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
|
||||
ASSERT_TRUE(closeFrontend());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <utils/Mutex.h>
|
||||
#include <map>
|
||||
|
||||
#include "DvrTests.h"
|
||||
#include "VtsHalTvTunerV1_0TestConfigurations.h"
|
||||
|
||||
#define WAIT_TIMEOUT 3000000000
|
||||
|
@ -100,7 +101,10 @@ class FrontendTests {
|
|||
public:
|
||||
sp<ITuner> mService;
|
||||
|
||||
void setService(sp<ITuner> tuner) { mService = tuner; }
|
||||
void setService(sp<ITuner> tuner) {
|
||||
mService = tuner;
|
||||
mDvrTests.setService(tuner);
|
||||
}
|
||||
|
||||
AssertionResult getFrontendIds();
|
||||
AssertionResult getFrontendInfo(uint32_t frontendId);
|
||||
|
@ -108,23 +112,43 @@ class FrontendTests {
|
|||
AssertionResult setFrontendCallback();
|
||||
AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
|
||||
AssertionResult stopScanFrontend();
|
||||
AssertionResult tuneFrontend(FrontendConfig config);
|
||||
AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
|
||||
AssertionResult setLnb(uint32_t lnbId);
|
||||
void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
|
||||
vector<FrontendStatus> expectStatuses);
|
||||
AssertionResult stopTuneFrontend();
|
||||
AssertionResult stopTuneFrontend(bool testWithDemux);
|
||||
AssertionResult closeFrontend();
|
||||
|
||||
void getFrontendIdByType(FrontendType feType, uint32_t& feId);
|
||||
void tuneTest(FrontendConfig frontendConf);
|
||||
void scanTest(FrontendConfig frontend, FrontendScanType type);
|
||||
|
||||
void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
|
||||
void setDemux(sp<IDemux> demux) { mDvrTests.setDemux(demux); }
|
||||
|
||||
protected:
|
||||
static AssertionResult failure() { return ::testing::AssertionFailure(); }
|
||||
static AssertionResult success() { return ::testing::AssertionSuccess(); }
|
||||
|
||||
void getSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) {
|
||||
PlaybackSettings playbackSettings{
|
||||
.statusMask = 0xf,
|
||||
.lowThreshold = 0x1000,
|
||||
.highThreshold = 0x07fff,
|
||||
.dataFormat = DataFormat::TS,
|
||||
.packetSize = 188,
|
||||
};
|
||||
dvrConfig.type = DvrType::PLAYBACK;
|
||||
dvrConfig.playbackInputFile = "/data/local/tmp/segment000000.ts";
|
||||
dvrConfig.bufferSize = FMQ_SIZE_4M;
|
||||
dvrConfig.settings.playback(playbackSettings);
|
||||
}
|
||||
|
||||
sp<IFrontend> mFrontend;
|
||||
FrontendInfo mFrontendInfo;
|
||||
sp<FrontendCallback> mFrontendCallback;
|
||||
hidl_vec<FrontendId> mFeIds;
|
||||
|
||||
DvrTests mDvrTests;
|
||||
bool mIsSoftwareFe = false;
|
||||
};
|
||||
|
|
|
@ -94,6 +94,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
|
|||
}
|
||||
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
|
||||
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
|
||||
mFrontendTests.setDemux(demux);
|
||||
mFilterTests.setDemux(demux);
|
||||
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
|
||||
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
|
||||
|
@ -101,9 +102,9 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
|
|||
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
|
||||
ASSERT_TRUE(mFilterTests.startFilter(filterId));
|
||||
// tune test
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf));
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
|
||||
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend());
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
|
||||
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
|
||||
ASSERT_TRUE(mDemuxTests.closeDemux());
|
||||
|
@ -139,21 +140,21 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv
|
|||
mFilterTests.setDemux(demux);
|
||||
mDvrTests.setDemux(demux);
|
||||
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
|
||||
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor());
|
||||
ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
|
||||
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
|
||||
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
|
||||
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
|
||||
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
|
||||
mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
|
||||
ASSERT_TRUE(mDvrTests.startDvr());
|
||||
ASSERT_TRUE(mDvrTests.startDvrPlayback());
|
||||
ASSERT_TRUE(mFilterTests.startFilter(filterId));
|
||||
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
|
||||
mDvrTests.stopPlaybackThread();
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
|
||||
ASSERT_TRUE(mDvrTests.stopDvr());
|
||||
ASSERT_TRUE(mDvrTests.stopDvrPlayback());
|
||||
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
|
||||
mDvrTests.closeDvr();
|
||||
mDvrTests.closeDvrPlayback();
|
||||
ASSERT_TRUE(mDemuxTests.closeDemux());
|
||||
}
|
||||
|
||||
|
@ -176,9 +177,10 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
|
|||
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
|
||||
mFilterTests.setDemux(demux);
|
||||
mDvrTests.setDemux(demux);
|
||||
mFrontendTests.setDvrTests(mDvrTests);
|
||||
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
|
||||
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor());
|
||||
ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
|
||||
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
|
||||
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
|
||||
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
|
||||
|
@ -187,17 +189,17 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
|
|||
ASSERT_TRUE(filter != nullptr);
|
||||
mDvrTests.startRecordOutputThread(dvrConf.settings.record());
|
||||
ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
|
||||
ASSERT_TRUE(mDvrTests.startDvr());
|
||||
ASSERT_TRUE(mDvrTests.startDvrRecord());
|
||||
ASSERT_TRUE(mFilterTests.startFilter(filterId));
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf));
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
|
||||
mDvrTests.testRecordOutput();
|
||||
mDvrTests.stopRecordThread();
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend());
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
|
||||
ASSERT_TRUE(mDvrTests.stopDvr());
|
||||
ASSERT_TRUE(mDvrTests.stopDvrRecord());
|
||||
ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
|
||||
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
|
||||
mDvrTests.closeDvr();
|
||||
mDvrTests.closeDvrRecord();
|
||||
ASSERT_TRUE(mDemuxTests.closeDemux());
|
||||
ASSERT_TRUE(mFrontendTests.closeFrontend());
|
||||
}
|
||||
|
@ -240,8 +242,8 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
|
|||
mFilterTests.setDemux(demux);
|
||||
mDvrTests.setDemux(demux);
|
||||
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
|
||||
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor());
|
||||
ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
|
||||
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
|
||||
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
|
||||
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
|
||||
|
@ -249,13 +251,13 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
|
|||
filter = mFilterTests.getFilterById(filterId);
|
||||
ASSERT_TRUE(filter != nullptr);
|
||||
ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
|
||||
ASSERT_TRUE(mDvrTests.startDvr());
|
||||
ASSERT_TRUE(mDvrTests.startDvrRecord());
|
||||
ASSERT_TRUE(mFilterTests.startFilter(filterId));
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
|
||||
ASSERT_TRUE(mDvrTests.stopDvr());
|
||||
ASSERT_TRUE(mDvrTests.stopDvrRecord());
|
||||
ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
|
||||
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
|
||||
mDvrTests.closeDvr();
|
||||
mDvrTests.closeDvrRecord();
|
||||
ASSERT_TRUE(mDemuxTests.closeDemux());
|
||||
ASSERT_TRUE(mFrontendTests.closeFrontend());
|
||||
}
|
||||
|
@ -283,6 +285,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> m
|
|||
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
|
||||
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
|
||||
mFilterTests.setDemux(demux);
|
||||
mFrontendTests.setDemux(demux);
|
||||
for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
|
||||
ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize));
|
||||
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
|
||||
|
@ -306,9 +309,9 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> m
|
|||
ASSERT_TRUE(mFilterTests.startFilter(*id));
|
||||
}
|
||||
// tune test
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf));
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
|
||||
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend());
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
|
||||
for (id = filterIds.begin(); id != filterIds.end(); id++) {
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(*id));
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "DemuxTests.h"
|
||||
#include "DescramblerTests.h"
|
||||
#include "DvrTests.h"
|
||||
#include "FrontendTests.h"
|
||||
#include "LnbTests.h"
|
||||
|
||||
|
@ -147,6 +146,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam<std::string> {
|
|||
mDemuxTests.setService(mService);
|
||||
mFilterTests.setService(mService);
|
||||
mLnbTests.setService(mService);
|
||||
mDvrTests.setService(mService);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -159,6 +159,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam<std::string> {
|
|||
DemuxTests mDemuxTests;
|
||||
FilterTests mFilterTests;
|
||||
LnbTests mLnbTests;
|
||||
DvrTests mDvrTests;
|
||||
|
||||
AssertionResult filterDataOutputTest(vector<string> goldenOutputFiles);
|
||||
|
||||
|
@ -247,6 +248,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> {
|
|||
|
||||
mFrontendTests.setService(mService);
|
||||
mDemuxTests.setService(mService);
|
||||
mDvrTests.setService(mService);
|
||||
mDescramblerTests.setService(mService);
|
||||
mDescramblerTests.setCasService(mCasService);
|
||||
}
|
||||
|
@ -266,5 +268,6 @@ class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> {
|
|||
DemuxTests mDemuxTests;
|
||||
FilterTests mFilterTests;
|
||||
DescramblerTests mDescramblerTests;
|
||||
DvrTests mDvrTests;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -121,6 +121,7 @@ typedef enum {
|
|||
typedef enum {
|
||||
DVR_RECORD0,
|
||||
DVR_PLAYBACK0,
|
||||
DVR_SOFTWARE_FE,
|
||||
DVR_MAX,
|
||||
} Dvr;
|
||||
|
||||
|
@ -143,6 +144,7 @@ struct TimeFilterConfig {
|
|||
};
|
||||
|
||||
struct FrontendConfig {
|
||||
bool isSoftwareFe;
|
||||
FrontendType type;
|
||||
FrontendSettings settings;
|
||||
vector<FrontendStatusType> tuneStatusTypes;
|
||||
|
@ -213,7 +215,9 @@ inline void initFrontendConfig() {
|
|||
statuses.push_back(status);
|
||||
frontendArray[DVBT].tuneStatusTypes = types;
|
||||
frontendArray[DVBT].expectTuneStatuses = statuses;
|
||||
frontendArray[DVBT].isSoftwareFe = true;
|
||||
frontendArray[DVBS].type = FrontendType::DVBS;
|
||||
frontendArray[DVBS].isSoftwareFe = true;
|
||||
};
|
||||
|
||||
/** Configuration array for the frontend scan test */
|
||||
|
@ -355,9 +359,20 @@ inline void initDvrConfig() {
|
|||
.packetSize = 188,
|
||||
};
|
||||
dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK;
|
||||
dvrArray[DVR_PLAYBACK0].playbackInputFile = "/vendor/etc/segment000000.ts";
|
||||
dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts";
|
||||
dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M;
|
||||
dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings);
|
||||
PlaybackSettings softwareFePlaybackSettings{
|
||||
.statusMask = 0xf,
|
||||
.lowThreshold = 0x1000,
|
||||
.highThreshold = 0x07fff,
|
||||
.dataFormat = DataFormat::TS,
|
||||
.packetSize = 188,
|
||||
};
|
||||
dvrArray[DVR_SOFTWARE_FE].type = DvrType::PLAYBACK;
|
||||
dvrArray[DVR_SOFTWARE_FE].playbackInputFile = "/data/local/tmp/segment000000.ts";
|
||||
dvrArray[DVR_SOFTWARE_FE].bufferSize = FMQ_SIZE_4M;
|
||||
dvrArray[DVR_SOFTWARE_FE].settings.playback(softwareFePlaybackSettings);
|
||||
};
|
||||
|
||||
/** Configuration array for the descrambler test */
|
||||
|
|
Loading…
Reference in a new issue