Snap for 6586393 from 1fb7d06712 to rvc-release

Change-Id: I8433e9cb8553a2e9b0a5a475e01d5b64adb8effa
This commit is contained in:
android-build-team Robot 2020-06-13 01:02:30 +00:00
commit 75f657465c
19 changed files with 441 additions and 249 deletions

View 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>

View file

@ -17,13 +17,13 @@ cc_test {
"android.hardware.keymaster@4.0", "android.hardware.keymaster@4.0",
"libbinder", "libbinder",
"libcrypto", "libcrypto",
"libkeymaster_portable",
"libsoft_attestation_cert",
"libpuresoftkeymasterdevice",
"android.hardware.keymaster-ndk_platform", "android.hardware.keymaster-ndk_platform",
], ],
static_libs: [ static_libs: [
"libcppbor", "libcppbor",
"libkeymaster_portable",
"libsoft_attestation_cert",
"libpuresoftkeymasterdevice",
"android.hardware.identity-support-lib", "android.hardware.identity-support-lib",
"android.hardware.identity-cpp", "android.hardware.identity-cpp",
"android.hardware.keymaster-cpp", "android.hardware.keymaster-cpp",

View file

@ -49,7 +49,6 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
} }
EXPECT_EQ(CardState::ABSENT, cardStatus.cardState); EXPECT_EQ(CardState::ABSENT, cardStatus.cardState);
} }
#endif
/* Test setSimCardPower power up */ /* Test setSimCardPower power up */
serial = GetRandomSerialNumber(); serial = GetRandomSerialNumber();
@ -60,6 +59,7 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_1->rspInfo.error, ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_1->rspInfo.error,
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE})); RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE}));
#endif
/** /**
* If the sim card status for the testing environment is PRESENT, * If the sim card status for the testing environment is PRESENT,

View file

@ -48,8 +48,6 @@ Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
return Result::INVALID_STATE; return Result::INVALID_STATE;
} }
mFrontendSourceFile = mFrontend->getSourceFile();
mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId); mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId);
return Result::SUCCESS; return Result::SUCCESS;
@ -62,8 +60,6 @@ Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
uint32_t filterId; uint32_t filterId;
filterId = ++mLastUsedFilterId; filterId = ++mLastUsedFilterId;
mUsedFilterIds.insert(filterId);
if (cb == nullptr) { if (cb == nullptr) {
ALOGW("[Demux] callback can't be null"); ALOGW("[Demux] callback can't be null");
_hidl_cb(Result::INVALID_ARGUMENT, new Filter()); _hidl_cb(Result::INVALID_ARGUMENT, new Filter());
@ -82,8 +78,13 @@ Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
mPcrFilterIds.insert(filterId); mPcrFilterIds.insert(filterId);
} }
bool result = true; bool result = true;
if (mDvr != nullptr && mDvr->getType() == DvrType::PLAYBACK) { if (!filter->isRecordFilter()) {
result = mDvr->addPlaybackFilter(filter); // 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); _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() { Return<Result> Demux::close() {
ALOGV("%s", __FUNCTION__); 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; mLastUsedFilterId = -1;
return Result::SUCCESS; return Result::SUCCESS;
@ -170,15 +177,38 @@ Return<void> Demux::openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCall
return Void(); 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()) { for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
_hidl_cb(Result::UNKNOWN_ERROR, mDvr); if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) {
return Void(); 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) { Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
@ -198,8 +228,10 @@ Return<Result> Demux::disconnectCiCam() {
Result Demux::removeFilter(uint32_t filterId) { Result Demux::removeFilter(uint32_t filterId) {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
// resetFilterRecords(filterId); if (mDvrPlayback != nullptr) {
mUsedFilterIds.erase(filterId); mDvrPlayback->removePlaybackFilter(filterId);
}
mPlaybackFilterIds.erase(filterId);
mRecordFilterIds.erase(filterId); mRecordFilterIds.erase(filterId);
mFilters.erase(filterId); mFilters.erase(filterId);
@ -212,7 +244,7 @@ void Demux::startBroadcastTsFilter(vector<uint8_t> data) {
if (DEBUG_DEMUX) { if (DEBUG_DEMUX) {
ALOGW("[Demux] start ts filter pid: %d", pid); 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()) { if (pid == mFilters[*it]->getTpid()) {
mFilters[*it]->updateFilterOutput(data); mFilters[*it]->updateFilterOutput(data);
} }
@ -233,7 +265,7 @@ bool Demux::startBroadcastFilterDispatcher() {
set<uint32_t>::iterator it; set<uint32_t>::iterator it;
// Handle the output data per filter type // 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) { if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) {
return false; return false;
} }
@ -280,58 +312,27 @@ void* Demux::__threadLoopFrontend(void* user) {
void Demux::frontendInputThreadLoop() { void Demux::frontendInputThreadLoop() {
std::lock_guard<std::mutex> lock(mFrontendInputThreadLock); std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
mFrontendInputThreadRunning = true; 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) { while (mFrontendInputThreadRunning) {
// move the stream pointer for packet size * 6 every read until the end uint32_t efState = 0;
while (mKeepFetchingDataFromFrontend) { status_t status = mDvrPlayback->getDvrEventFlag()->wait(
for (int i = 0; i < writePacketAmount; i++) { static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
inputData.read(buffer, packetSize); true /* retry on spurious wake */);
if (!inputData) { if (status != OK) {
mKeepFetchingDataFromFrontend = false; ALOGD("[Demux] wait for data ready on the playback FMQ");
mFrontendInputThreadRunning = false; continue;
break; }
} // Our current implementation filter the data and write it into the filter FMQ immediately
// filter and dispatch filter output // after the DATA_READY from the VTS/framework
vector<uint8_t> byteBuffer; if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
byteBuffer.resize(packetSize); !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
for (int index = 0; index < byteBuffer.size(); index++) { ALOGE("[Demux] playback data failed to be filtered. Ending thread");
byteBuffer[index] = static_cast<uint8_t>(buffer[index]); break;
}
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);
} }
} }
mFrontendInputThreadRunning = false;
ALOGW("[Demux] Frontend Input thread end."); ALOGW("[Demux] Frontend Input thread end.");
delete[] buffer;
inputData.close();
} }
void Demux::stopFrontendInput() { void Demux::stopFrontendInput() {
@ -346,18 +347,19 @@ void Demux::setIsRecording(bool isRecording) {
} }
bool Demux::attachRecordFilter(int filterId) { bool Demux::attachRecordFilter(int filterId) {
if (mFilters[filterId] == nullptr || mDvr == nullptr) { if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
!mFilters[filterId]->isRecordFilter()) {
return false; return false;
} }
mRecordFilterIds.insert(filterId); mRecordFilterIds.insert(filterId);
mFilters[filterId]->attachFilterToRecord(mDvr); mFilters[filterId]->attachFilterToRecord(mDvrRecord);
return true; return true;
} }
bool Demux::detachRecordFilter(int filterId) { bool Demux::detachRecordFilter(int filterId) {
if (mFilters[filterId] == nullptr || mDvr == nullptr) { if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) {
return false; return false;
} }

View file

@ -91,13 +91,23 @@ class Demux : public IDemux {
void setIsRecording(bool isRecording); void setIsRecording(bool isRecording);
void startFrontendInputLoop(); 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: private:
// Tuner service // Tuner service
sp<Tuner> mTunerService; sp<Tuner> mTunerService;
// Frontend source // Frontend source
sp<Frontend> mFrontend; sp<Frontend> mFrontend;
string mFrontendSourceFile;
// A struct that passes the arguments to a newly created filter thread // A struct that passes the arguments to a newly created filter thread
struct ThreadArgs { struct ThreadArgs {
@ -117,16 +127,6 @@ class Demux : public IDemux {
*/ */
void deleteEventFlag(); void deleteEventFlag();
bool readDataFromMQ(); 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 mDemuxId;
uint32_t mCiCamId; uint32_t mCiCamId;
@ -137,17 +137,17 @@ class Demux : public IDemux {
*/ */
uint32_t mLastUsedFilterId = -1; 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. * 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. * Record all the attached record filter Ids.
* Any removed filter id should be removed from this set. * Any removed filter id should be removed from this set.
*/ */
set<uint32_t> mRecordFilterIds; set<uint32_t> mRecordFilterIds;
/** /**
* A list of created FilterMQ ptrs. * A list of created Filter sp.
* The array number is the filter ID. * The array number is the filter ID.
*/ */
std::map<uint32_t, sp<Filter>> mFilters; std::map<uint32_t, sp<Filter>> mFilters;
@ -160,7 +160,8 @@ class Demux : public IDemux {
/** /**
* Local reference to the opened DVR object. * Local reference to the opened DVR object.
*/ */
sp<Dvr> mDvr; sp<Dvr> mDvrPlayback;
sp<Dvr> mDvrRecord;
// Thread handlers // Thread handlers
pthread_t mFrontendInputThread; pthread_t mFrontendInputThread;

View file

@ -70,8 +70,7 @@ Return<Result> Dvr::attachFilter(const sp<IFilter>& filter) {
return status; return status;
} }
// check if the attached filter is a record filter // TODO check if the attached filter is a record filter
mFilters[filterId] = filter;
if (!mDemux->attachRecordFilter(filterId)) { if (!mDemux->attachRecordFilter(filterId)) {
return Result::INVALID_ARGUMENT; return Result::INVALID_ARGUMENT;
} }
@ -94,19 +93,8 @@ Return<Result> Dvr::detachFilter(const sp<IFilter>& filter) {
return status; return status;
} }
std::map<uint32_t, sp<IFilter>>::iterator it; if (!mDemux->detachRecordFilter(filterId)) {
return Result::INVALID_ARGUMENT;
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;
} }
return Result::SUCCESS; return Result::SUCCESS;
@ -183,6 +171,10 @@ bool Dvr::createDvrMQ() {
return true; return true;
} }
EventFlag* Dvr::getDvrEventFlag() {
return mDvrEventFlag;
}
void* Dvr::__threadLoopPlayback(void* user) { void* Dvr::__threadLoopPlayback(void* user) {
Dvr* const self = static_cast<Dvr*>(user); Dvr* const self = static_cast<Dvr*>(user);
self->playbackThreadLoop(); self->playbackThreadLoop();
@ -205,8 +197,9 @@ void Dvr::playbackThreadLoop() {
} }
// Our current implementation filter the data and write it into the filter FMQ immediately // Our current implementation filter the data and write it into the filter FMQ immediately
// after the DATA_READY from the VTS/framework // after the DATA_READY from the VTS/framework
if (!readPlaybackFMQ() || !startFilterDispatcher()) { if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) ||
ALOGD("[Dvr] playback data failed to be filtered. Ending thread"); !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) {
ALOGE("[Dvr] playback data failed to be filtered. Ending thread");
break; break;
} }
@ -245,7 +238,7 @@ PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_
return mPlaybackStatus; return mPlaybackStatus;
} }
bool Dvr::readPlaybackFMQ() { bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) {
// Read playback data from the input FMQ // Read playback data from the input FMQ
int size = mDvrMQ->availableToRead(); int size = mDvrMQ->availableToRead();
int playbackPacketSize = mDvrSettings.playback().packetSize; int playbackPacketSize = mDvrSettings.playback().packetSize;
@ -256,7 +249,15 @@ bool Dvr::readPlaybackFMQ() {
if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) { if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) {
return false; return false;
} }
startTpidFilter(dataOutputBuffer); if (isVirtualFrontend) {
if (isRecording) {
mDemux->sendFrontendInputToRecord(dataOutputBuffer);
} else {
mDemux->startBroadcastTsFilter(dataOutputBuffer);
}
} else {
startTpidFilter(dataOutputBuffer);
}
} }
return true; 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; std::map<uint32_t, sp<IFilter>>::iterator it;
// Handle the output data per filter type // Handle the output data per filter type
for (it = mFilters.begin(); it != mFilters.end(); it++) { for (it = mFilters.begin(); it != mFilters.end(); it++) {
@ -329,27 +338,15 @@ RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t av
return mRecordStatus; return mRecordStatus;
} }
bool Dvr::addPlaybackFilter(sp<IFilter> filter) { bool Dvr::addPlaybackFilter(uint32_t filterId, 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;
}
mFilters[filterId] = filter; mFilters[filterId] = filter;
return true; return true;
} }
DvrType Dvr::getType() { bool Dvr::removePlaybackFilter(uint32_t filterId) {
return mType; mFilters.erase(filterId);
return true;
} }
} // namespace implementation } // namespace implementation
} // namespace V1_0 } // namespace V1_0
} // namespace tuner } // namespace tuner

View file

@ -81,8 +81,11 @@ class Dvr : public IDvr {
bool createDvrMQ(); bool createDvrMQ();
void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer); void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer);
bool writeRecordFMQ(const std::vector<uint8_t>& data); bool writeRecordFMQ(const std::vector<uint8_t>& data);
DvrType getType(); bool addPlaybackFilter(uint32_t filterId, sp<IFilter> filter);
bool addPlaybackFilter(sp<IFilter> filter); bool removePlaybackFilter(uint32_t filterId);
bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording);
bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording);
EventFlag* getDvrEventFlag();
private: private:
// Demux service // Demux service
@ -105,9 +108,7 @@ class Dvr : public IDvr {
* A dispatcher to read and dispatch input data to all the started filters. * A dispatcher to read and dispatch input data to all the started filters.
* Each filter handler handles the data filtering/output writing/filterEvent updating. * Each filter handler handles the data filtering/output writing/filterEvent updating.
*/ */
bool readPlaybackFMQ();
void startTpidFilter(vector<uint8_t> data); void startTpidFilter(vector<uint8_t> data);
bool startFilterDispatcher();
static void* __threadLoopPlayback(void* user); static void* __threadLoopPlayback(void* user);
static void* __threadLoopRecord(void* user); static void* __threadLoopRecord(void* user);
void playbackThreadLoop(); void playbackThreadLoop();
@ -123,7 +124,6 @@ class Dvr : public IDvr {
// Thread handlers // Thread handlers
pthread_t mDvrThread; pthread_t mDvrThread;
pthread_t mBroadcastInputThread;
// FMQ status local records // FMQ status local records
PlaybackStatus mPlaybackStatus; PlaybackStatus mPlaybackStatus;
@ -132,7 +132,6 @@ class Dvr : public IDvr {
* If a specific filter's writing loop is still running * If a specific filter's writing loop is still running
*/ */
bool mDvrThreadRunning; bool mDvrThreadRunning;
bool mBroadcastInputThreadRunning;
bool mKeepFetchingDataFromFrontend; bool mKeepFetchingDataFromFrontend;
/** /**
* Lock to protect writes to the FMQs * Lock to protect writes to the FMQs
@ -143,7 +142,6 @@ class Dvr : public IDvr {
*/ */
std::mutex mPlaybackStatusLock; std::mutex mPlaybackStatusLock;
std::mutex mRecordStatusLock; std::mutex mRecordStatusLock;
std::mutex mBroadcastInputThreadLock;
std::mutex mDvrThreadLock; std::mutex mDvrThreadLock;
const bool DEBUG_DVR = false; const bool DEBUG_DVR = false;
@ -151,7 +149,6 @@ class Dvr : public IDvr {
// Booleans to check if recording is running. // Booleans to check if recording is running.
// Recording is ready when both of the following are set to true. // Recording is ready when both of the following are set to true.
bool mIsRecordStarted = false; bool mIsRecordStarted = false;
bool mIsRecordFilterAttached = false;
}; };
} // namespace implementation } // namespace implementation

View file

@ -47,12 +47,18 @@ Filter::Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize,
if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) { if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) {
mIsPcrFilter = true; mIsPcrFilter = true;
} }
if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) {
mIsRecordFilter = true;
}
break; break;
case DemuxFilterMainType::MMTP: case DemuxFilterMainType::MMTP:
if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
mIsMediaFilter = true; mIsMediaFilter = true;
} }
if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) {
mIsRecordFilter = true;
}
break; break;
case DemuxFilterMainType::IP: case DemuxFilterMainType::IP:
break; break;
@ -535,12 +541,6 @@ Result Filter::startMediaFilterHandler() {
} }
Result Filter::startRecordFilterHandler() { 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); std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
if (mRecordFilterOutput.empty()) { if (mRecordFilterOutput.empty()) {
return Result::SUCCESS; return Result::SUCCESS;
@ -567,7 +567,7 @@ Result Filter::startTemiFilterHandler() {
bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) { bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
// TODO check how many sections has been read // TODO check how many sections has been read
ALOGD("[Filter] section hander"); ALOGD("[Filter] section handler");
std::lock_guard<std::mutex> lock(mFilterEventLock); std::lock_guard<std::mutex> lock(mFilterEventLock);
if (!writeDataToFilterMQ(data)) { if (!writeDataToFilterMQ(data)) {
return false; return false;

View file

@ -91,6 +91,7 @@ class Filter : public IFilter {
void freeAvHandle(); void freeAvHandle();
bool isMediaFilter() { return mIsMediaFilter; }; bool isMediaFilter() { return mIsMediaFilter; };
bool isPcrFilter() { return mIsPcrFilter; }; bool isPcrFilter() { return mIsPcrFilter; };
bool isRecordFilter() { return mIsRecordFilter; };
private: private:
// Tuner service // Tuner service
@ -107,6 +108,7 @@ class Filter : public IFilter {
DemuxFilterType mType; DemuxFilterType mType;
bool mIsMediaFilter = false; bool mIsMediaFilter = false;
bool mIsPcrFilter = false; bool mIsPcrFilter = false;
bool mIsRecordFilter = false;
DemuxFilterSettings mFilterSettings; DemuxFilterSettings mFilterSettings;
uint16_t mTpid; uint16_t mTpid;

View file

@ -66,7 +66,7 @@ Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
mTunerService->frontendStartTune(mId); mTunerService->frontendStartTune(mId);
mCallback->onEvent(FrontendEventType::LOCKED); mCallback->onEvent(FrontendEventType::LOCKED);
mIsLocked = false; mIsLocked = true;
return Result::SUCCESS; return Result::SUCCESS;
} }
@ -268,14 +268,14 @@ FrontendId Frontend::getFrontendId() {
return mId; return mId;
} }
string Frontend::getSourceFile() {
return FRONTEND_STREAM_FILE;
}
bool Frontend::supportsSatellite() { bool Frontend::supportsSatellite() {
return mType == FrontendType::DVBS || mType == FrontendType::ISDBS || return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
mType == FrontendType::ISDBS3; mType == FrontendType::ISDBS3;
} }
bool Frontend::isLocked() {
return mIsLocked;
}
} // namespace implementation } // namespace implementation
} // namespace V1_0 } // namespace V1_0
} // namespace tuner } // namespace tuner

View file

@ -68,6 +68,8 @@ class Frontend : public IFrontend {
string getSourceFile(); string getSourceFile();
bool isLocked();
private: private:
virtual ~Frontend(); virtual ~Frontend();
bool supportsSatellite(); bool supportsSatellite();
@ -77,7 +79,6 @@ class Frontend : public IFrontend {
FrontendId mId = 0; FrontendId mId = 0;
bool mIsLocked = false; bool mIsLocked = false;
const string FRONTEND_STREAM_FILE = "/vendor/etc/segment000000.ts";
std::ifstream mFrontendData; std::ifstream mFrontendData;
}; };

View file

@ -231,6 +231,9 @@ Return<void> Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_
void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
mFrontendToDemux[frontendId] = demuxId; mFrontendToDemux[frontendId] = demuxId;
if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
mDemuxes[demuxId]->startFrontendInputLoop();
}
} }
void Tuner::frontendStopTune(uint32_t frontendId) { void Tuner::frontendStopTune(uint32_t frontendId) {

View file

@ -49,49 +49,73 @@ void DvrCallback::playbackThreadLoop() {
EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) == EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) ==
android::OK); android::OK);
// open the stream and get its length int fd = open(mInputDataFile.c_str(), O_RDONLY | O_LARGEFILE);
std::ifstream inputData(mInputDataFile.c_str(), std::ifstream::binary); int readBytes;
int writeSize = mPlaybackSettings.packetSize * 6; uint32_t regionSize = 0;
char* buffer = new char[writeSize]; uint8_t* buffer;
ALOGW("[vts] playback thread loop start %s!", mInputDataFile.c_str()); ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str());
if (!inputData.is_open()) { if (fd < 0) {
mPlaybackThreadRunning = false; mPlaybackThreadRunning = false;
ALOGW("[vts] Error %s", strerror(errno)); ALOGW("[vts] Error %s", strerror(errno));
} }
while (mPlaybackThreadRunning) { while (mPlaybackThreadRunning) {
// move the stream pointer for packet size * 6 every read until the end
while (mKeepWritingPlaybackFMQ) { while (mKeepWritingPlaybackFMQ) {
inputData.read(buffer, writeSize); int totalWrite = mPlaybackMQ->availableToWrite();
if (!inputData) { if (totalWrite * 4 < mPlaybackMQ->getQuantumCount()) {
int leftSize = inputData.gcount(); // Wait for the HAL implementation to read more data then write.
if (leftSize == 0) { continue;
mPlaybackThreadRunning = false; }
break; MessageQueue<uint8_t, kSynchronizedReadWrite>::MemTransaction memTx;
} if (!mPlaybackMQ->beginWrite(totalWrite, &memTx)) {
inputData.clear(); ALOGW("[vts] Fail to write into Playback fmq.");
inputData.read(buffer, leftSize); mPlaybackThreadRunning = false;
// Write the left over of the input data and quit the thread break;
if (leftSize > 0) { }
EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], leftSize)); auto first = memTx.getFirstRegion();
playbackMQEventFlag->wake( buffer = first.getAddress();
static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY)); 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; mPlaybackThreadRunning = false;
break; 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)); playbackMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
inputData.seekg(writeSize, inputData.cur);
sleep(1);
} }
} }
mPlaybackThreadRunning = false;
ALOGW("[vts] Playback thread end."); ALOGW("[vts] Playback thread end.");
close(fd);
delete[] buffer;
inputData.close();
} }
void DvrCallback::testRecordOutput() { void DvrCallback::testRecordOutput() {
@ -186,32 +210,65 @@ AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) {
EXPECT_TRUE(mDemux) << "Test with openDemux first."; EXPECT_TRUE(mDemux) << "Test with openDemux first.";
// Create dvr callback // 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) { if (type == DvrType::RECORD) {
mDvr = dvr; 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; status = result;
}); });
if (status == Result::SUCCESS) {
mDvrCallback->setDvr(mDvr);
}
return AssertionResult(status == Result::SUCCESS); return AssertionResult(status == Result::SUCCESS);
} }
AssertionResult DvrTests::configDvr(DvrSettings setting) { AssertionResult DvrTests::getDvrRecordMQDescriptor() {
Result status = mDvr->configure(setting);
return AssertionResult(status == Result::SUCCESS);
}
AssertionResult DvrTests::getDvrMQDescriptor() {
Result status; Result status;
EXPECT_TRUE(mDemux) << "Test with openDemux first."; 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) { mDvrRecord->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
mDvrMQDescriptor = dvrMQDesc; mDvrRecordMQDescriptor = dvrMQDesc;
status = result; status = result;
}); });
@ -221,9 +278,9 @@ AssertionResult DvrTests::getDvrMQDescriptor() {
AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) { AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) {
Result status; Result status;
EXPECT_TRUE(mDemux) << "Test with openDemux first."; 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); return AssertionResult(status == Result::SUCCESS);
} }
@ -231,35 +288,61 @@ AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) {
AssertionResult DvrTests::detachFilterToDvr(sp<IFilter> filter) { AssertionResult DvrTests::detachFilterToDvr(sp<IFilter> filter) {
Result status; Result status;
EXPECT_TRUE(mDemux) << "Test with openDemux first."; 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); return AssertionResult(status == Result::SUCCESS);
} }
AssertionResult DvrTests::startDvr() { AssertionResult DvrTests::startDvrPlayback() {
Result status; Result status;
EXPECT_TRUE(mDemux) << "Test with openDemux first."; 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); return AssertionResult(status == Result::SUCCESS);
} }
AssertionResult DvrTests::stopDvr() { AssertionResult DvrTests::stopDvrPlayback() {
Result status; Result status;
EXPECT_TRUE(mDemux) << "Test with openDemux first."; 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); return AssertionResult(status == Result::SUCCESS);
} }
void DvrTests::closeDvr() { void DvrTests::closeDvrPlayback() {
ASSERT_TRUE(mDemux); ASSERT_TRUE(mDemux);
ASSERT_TRUE(mDvr); ASSERT_TRUE(mDvrPlayback);
ASSERT_TRUE(mDvr->close() == Result::SUCCESS); 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);
} }

View file

@ -14,14 +14,15 @@
* limitations under the License. * limitations under the License.
*/ */
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android/hardware/tv/tuner/1.0/IDvr.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/IDvrCallback.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h> #include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <android/hardware/tv/tuner/1.0/types.h> #include <android/hardware/tv/tuner/1.0/types.h>
#include <fcntl.h>
#include <fmq/MessageQueue.h> #include <fmq/MessageQueue.h>
#include <gtest/gtest.h>
#include <hidl/HidlSupport.h>
#include <hidl/Status.h> #include <hidl/Status.h>
#include <utils/Condition.h> #include <utils/Condition.h>
#include <utils/Mutex.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::RecordStatus;
using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_0::Result;
using namespace std;
#define WAIT_TIMEOUT 3000000000 #define WAIT_TIMEOUT 3000000000
class DvrCallback : public IDvrCallback { class DvrCallback : public IDvrCallback {
@ -149,25 +152,31 @@ class DvrTests {
void setDemux(sp<IDemux> demux) { mDemux = demux; } void setDemux(sp<IDemux> demux) { mDemux = demux; }
void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) { void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) {
mDvrCallback->startPlaybackInputThread(dataInputFile, settings, mDvrMQDescriptor); mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings,
mDvrPlaybackMQDescriptor);
}; };
void startRecordOutputThread(RecordSettings settings) { void startRecordOutputThread(RecordSettings settings) {
mDvrCallback->startRecordOutputThread(settings, mDvrMQDescriptor); mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor);
}; };
void stopPlaybackThread() { mDvrCallback->stopPlaybackThread(); } void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); }
void testRecordOutput() { mDvrCallback->testRecordOutput(); } void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); }
void stopRecordThread() { mDvrCallback->stopPlaybackThread(); } void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); }
AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize); AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize);
AssertionResult configDvr(DvrSettings setting); AssertionResult configDvrPlayback(DvrSettings setting);
AssertionResult getDvrMQDescriptor(); AssertionResult configDvrRecord(DvrSettings setting);
AssertionResult getDvrPlaybackMQDescriptor();
AssertionResult getDvrRecordMQDescriptor();
AssertionResult attachFilterToDvr(sp<IFilter> filter); AssertionResult attachFilterToDvr(sp<IFilter> filter);
AssertionResult detachFilterToDvr(sp<IFilter> filter); AssertionResult detachFilterToDvr(sp<IFilter> filter);
AssertionResult stopDvr(); AssertionResult stopDvrPlayback();
AssertionResult startDvr(); AssertionResult startDvrPlayback();
void closeDvr(); AssertionResult stopDvrRecord();
AssertionResult startDvrRecord();
void closeDvrPlayback();
void closeDvrRecord();
protected: protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult failure() { return ::testing::AssertionFailure(); }
@ -175,11 +184,11 @@ class DvrTests {
static AssertionResult success() { return ::testing::AssertionSuccess(); } static AssertionResult success() { return ::testing::AssertionSuccess(); }
sp<ITuner> mService; sp<ITuner> mService;
sp<IDvr> mDvr; sp<IDvr> mDvrPlayback;
sp<IDvr> mDvrRecord;
sp<IDemux> mDemux; sp<IDemux> mDemux;
sp<DvrCallback> mDvrCallback; sp<DvrCallback> mDvrPlaybackCallback;
MQDesc mDvrMQDescriptor; sp<DvrCallback> mDvrRecordCallback;
MQDesc mDvrPlaybackMQDescriptor;
pthread_t mPlaybackshread; MQDesc mDvrRecordMQDescriptor;
bool mPlaybackThreadRunning;
}; };

View file

@ -360,13 +360,28 @@ void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
ASSERT_TRUE(status == Result::SUCCESS); ASSERT_TRUE(status == Result::SUCCESS);
} }
AssertionResult FrontendTests::tuneFrontend(FrontendConfig config) { AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) {
EXPECT_TRUE(mFrontendCallback) EXPECT_TRUE(mFrontendCallback)
<< "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
EXPECT_TRUE(mFrontendInfo.type == config.type) EXPECT_TRUE(mFrontendInfo.type == config.type)
<< "FrontendConfig does not match the frontend info of the given id."; << "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); mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
return AssertionResult(true); return AssertionResult(true);
} }
@ -379,10 +394,14 @@ AssertionResult FrontendTests::setLnb(uint32_t lnbId) {
return AssertionResult(mFrontend->setLnb(lnbId) == Result::SUCCESS); return AssertionResult(mFrontend->setLnb(lnbId) == Result::SUCCESS);
} }
AssertionResult FrontendTests::stopTuneFrontend() { AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) {
EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
Result status; Result status;
status = mFrontend->stopTune(); status = mFrontend->stopTune();
if (mIsSoftwareFe && testWithDemux) {
mDvrTests.stopPlaybackThread();
mDvrTests.closeDvrPlayback();
}
return AssertionResult(status == Result::SUCCESS); return AssertionResult(status == Result::SUCCESS);
} }
@ -415,9 +434,9 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) {
ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(openFrontendById(feId));
ASSERT_TRUE(setFrontendCallback()); ASSERT_TRUE(setFrontendCallback());
ASSERT_TRUE(tuneFrontend(frontendConf)); ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
ASSERT_TRUE(stopTuneFrontend()); ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
ASSERT_TRUE(closeFrontend()); ASSERT_TRUE(closeFrontend());
} }

View file

@ -31,6 +31,7 @@
#include <utils/Mutex.h> #include <utils/Mutex.h>
#include <map> #include <map>
#include "DvrTests.h"
#include "VtsHalTvTunerV1_0TestConfigurations.h" #include "VtsHalTvTunerV1_0TestConfigurations.h"
#define WAIT_TIMEOUT 3000000000 #define WAIT_TIMEOUT 3000000000
@ -100,7 +101,10 @@ class FrontendTests {
public: public:
sp<ITuner> mService; sp<ITuner> mService;
void setService(sp<ITuner> tuner) { mService = tuner; } void setService(sp<ITuner> tuner) {
mService = tuner;
mDvrTests.setService(tuner);
}
AssertionResult getFrontendIds(); AssertionResult getFrontendIds();
AssertionResult getFrontendInfo(uint32_t frontendId); AssertionResult getFrontendInfo(uint32_t frontendId);
@ -108,23 +112,43 @@ class FrontendTests {
AssertionResult setFrontendCallback(); AssertionResult setFrontendCallback();
AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
AssertionResult stopScanFrontend(); AssertionResult stopScanFrontend();
AssertionResult tuneFrontend(FrontendConfig config); AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
AssertionResult setLnb(uint32_t lnbId); AssertionResult setLnb(uint32_t lnbId);
void verifyFrontendStatus(vector<FrontendStatusType> statusTypes, void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
vector<FrontendStatus> expectStatuses); vector<FrontendStatus> expectStatuses);
AssertionResult stopTuneFrontend(); AssertionResult stopTuneFrontend(bool testWithDemux);
AssertionResult closeFrontend(); AssertionResult closeFrontend();
void getFrontendIdByType(FrontendType feType, uint32_t& feId); void getFrontendIdByType(FrontendType feType, uint32_t& feId);
void tuneTest(FrontendConfig frontendConf); void tuneTest(FrontendConfig frontendConf);
void scanTest(FrontendConfig frontend, FrontendScanType type); void scanTest(FrontendConfig frontend, FrontendScanType type);
void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
void setDemux(sp<IDemux> demux) { mDvrTests.setDemux(demux); }
protected: protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult failure() { return ::testing::AssertionFailure(); }
static AssertionResult success() { return ::testing::AssertionSuccess(); } 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; sp<IFrontend> mFrontend;
FrontendInfo mFrontendInfo; FrontendInfo mFrontendInfo;
sp<FrontendCallback> mFrontendCallback; sp<FrontendCallback> mFrontendCallback;
hidl_vec<FrontendId> mFeIds; hidl_vec<FrontendId> mFeIds;
DvrTests mDvrTests;
bool mIsSoftwareFe = false;
}; };

View file

@ -94,6 +94,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
} }
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFrontendTests.setDemux(demux);
mFilterTests.setDemux(demux); mFilterTests.setDemux(demux);
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
@ -101,9 +102,9 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test // tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId));
ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mDemuxTests.closeDemux());
@ -139,21 +140,21 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv
mFilterTests.setDemux(demux); mFilterTests.setDemux(demux);
mDvrTests.setDemux(demux); mDvrTests.setDemux(demux);
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings));
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback()); mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
ASSERT_TRUE(mDvrTests.startDvr()); ASSERT_TRUE(mDvrTests.startDvrPlayback());
ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
mDvrTests.stopPlaybackThread(); mDvrTests.stopPlaybackThread();
ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mDvrTests.stopDvr()); ASSERT_TRUE(mDvrTests.stopDvrPlayback());
ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId));
mDvrTests.closeDvr(); mDvrTests.closeDvrPlayback();
ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mDemuxTests.closeDemux());
} }
@ -176,9 +177,10 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFilterTests.setDemux(demux); mFilterTests.setDemux(demux);
mDvrTests.setDemux(demux); mDvrTests.setDemux(demux);
mFrontendTests.setDvrTests(mDvrTests);
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
@ -187,17 +189,17 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
ASSERT_TRUE(filter != nullptr); ASSERT_TRUE(filter != nullptr);
mDvrTests.startRecordOutputThread(dvrConf.settings.record()); mDvrTests.startRecordOutputThread(dvrConf.settings.record());
ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
ASSERT_TRUE(mDvrTests.startDvr()); ASSERT_TRUE(mDvrTests.startDvrRecord());
ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
mDvrTests.testRecordOutput(); mDvrTests.testRecordOutput();
mDvrTests.stopRecordThread(); mDvrTests.stopRecordThread();
ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mDvrTests.stopDvr()); ASSERT_TRUE(mDvrTests.stopDvrRecord());
ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId));
mDvrTests.closeDvr(); mDvrTests.closeDvrRecord();
ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend()); ASSERT_TRUE(mFrontendTests.closeFrontend());
} }
@ -240,8 +242,8 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
mFilterTests.setDemux(demux); mFilterTests.setDemux(demux);
mDvrTests.setDemux(demux); mDvrTests.setDemux(demux);
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
@ -249,13 +251,13 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
filter = mFilterTests.getFilterById(filterId); filter = mFilterTests.getFilterById(filterId);
ASSERT_TRUE(filter != nullptr); ASSERT_TRUE(filter != nullptr);
ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
ASSERT_TRUE(mDvrTests.startDvr()); ASSERT_TRUE(mDvrTests.startDvrRecord());
ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mDvrTests.stopDvr()); ASSERT_TRUE(mDvrTests.stopDvrRecord());
ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId));
mDvrTests.closeDvr(); mDvrTests.closeDvrRecord();
ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend()); ASSERT_TRUE(mFrontendTests.closeFrontend());
} }
@ -283,6 +285,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> m
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFilterTests.setDemux(demux); mFilterTests.setDemux(demux);
mFrontendTests.setDemux(demux);
for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
@ -306,9 +309,9 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> m
ASSERT_TRUE(mFilterTests.startFilter(*id)); ASSERT_TRUE(mFilterTests.startFilter(*id));
} }
// tune test // tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
for (id = filterIds.begin(); id != filterIds.end(); id++) { for (id = filterIds.begin(); id != filterIds.end(); id++) {
ASSERT_TRUE(mFilterTests.stopFilter(*id)); ASSERT_TRUE(mFilterTests.stopFilter(*id));
} }

View file

@ -16,7 +16,6 @@
#include "DemuxTests.h" #include "DemuxTests.h"
#include "DescramblerTests.h" #include "DescramblerTests.h"
#include "DvrTests.h"
#include "FrontendTests.h" #include "FrontendTests.h"
#include "LnbTests.h" #include "LnbTests.h"
@ -147,6 +146,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam<std::string> {
mDemuxTests.setService(mService); mDemuxTests.setService(mService);
mFilterTests.setService(mService); mFilterTests.setService(mService);
mLnbTests.setService(mService); mLnbTests.setService(mService);
mDvrTests.setService(mService);
} }
protected: protected:
@ -159,6 +159,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam<std::string> {
DemuxTests mDemuxTests; DemuxTests mDemuxTests;
FilterTests mFilterTests; FilterTests mFilterTests;
LnbTests mLnbTests; LnbTests mLnbTests;
DvrTests mDvrTests;
AssertionResult filterDataOutputTest(vector<string> goldenOutputFiles); AssertionResult filterDataOutputTest(vector<string> goldenOutputFiles);
@ -247,6 +248,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> {
mFrontendTests.setService(mService); mFrontendTests.setService(mService);
mDemuxTests.setService(mService); mDemuxTests.setService(mService);
mDvrTests.setService(mService);
mDescramblerTests.setService(mService); mDescramblerTests.setService(mService);
mDescramblerTests.setCasService(mCasService); mDescramblerTests.setCasService(mCasService);
} }
@ -266,5 +268,6 @@ class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> {
DemuxTests mDemuxTests; DemuxTests mDemuxTests;
FilterTests mFilterTests; FilterTests mFilterTests;
DescramblerTests mDescramblerTests; DescramblerTests mDescramblerTests;
DvrTests mDvrTests;
}; };
} // namespace } // namespace

View file

@ -121,6 +121,7 @@ typedef enum {
typedef enum { typedef enum {
DVR_RECORD0, DVR_RECORD0,
DVR_PLAYBACK0, DVR_PLAYBACK0,
DVR_SOFTWARE_FE,
DVR_MAX, DVR_MAX,
} Dvr; } Dvr;
@ -143,6 +144,7 @@ struct TimeFilterConfig {
}; };
struct FrontendConfig { struct FrontendConfig {
bool isSoftwareFe;
FrontendType type; FrontendType type;
FrontendSettings settings; FrontendSettings settings;
vector<FrontendStatusType> tuneStatusTypes; vector<FrontendStatusType> tuneStatusTypes;
@ -213,7 +215,9 @@ inline void initFrontendConfig() {
statuses.push_back(status); statuses.push_back(status);
frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].tuneStatusTypes = types;
frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].expectTuneStatuses = statuses;
frontendArray[DVBT].isSoftwareFe = true;
frontendArray[DVBS].type = FrontendType::DVBS; frontendArray[DVBS].type = FrontendType::DVBS;
frontendArray[DVBS].isSoftwareFe = true;
}; };
/** Configuration array for the frontend scan test */ /** Configuration array for the frontend scan test */
@ -355,9 +359,20 @@ inline void initDvrConfig() {
.packetSize = 188, .packetSize = 188,
}; };
dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK; 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].bufferSize = FMQ_SIZE_4M;
dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); 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 */ /** Configuration array for the descrambler test */