Add startId in Filter Event to work with filter reconfiguration

Test: atest VtsHalTvTunerV1_1TargetTest
Bug: 172593389
Change-Id: I77e45366b737068aa0aa20c2b384f2e3160c7398
This commit is contained in:
Amy Zhang
2020-11-11 20:01:07 -08:00
parent 52d9d086fd
commit ff82d7ca94
9 changed files with 94 additions and 6 deletions

View File

@@ -26,6 +26,8 @@ import @1.0::Result;
* To access the v1.1 IFilter APIs, the implementation can cast the IFilter
* interface returned from the @1.0::IDemux openFilter into a v1.1 IFiler
* using V1_1::IFilter::castFrom(V1_0::IFilter).
*
* Note that reconfiguring Filter must happen after the Filter is stopped.
*/
interface IFilter extends @1.0::IFilter {
/**

View File

@@ -25,7 +25,8 @@ interface IFilterCallback extends @1.0::IFilterCallback {
* Notify the client that a new filter event happened.
*
* @param filterEvent a v1_0 filter event.
* @param filterEventExt a v1_1 extended filter event.
* @param filterEventExt a v1_1 extended filter event. Send an empty filterEvent along with
* startId or scramblingStatus filterEventExt
*/
oneway onFilterEvent_1_1(DemuxFilterEvent filterEvent, DemuxFilterEventExt filterEventExt);
};

View File

@@ -131,6 +131,7 @@ Return<Result> Filter::configure(const DemuxFilterSettings& settings) {
break;
}
mConfigured = true;
return Result::SUCCESS;
}
@@ -145,8 +146,6 @@ Return<Result> Filter::stop() {
mFilterThreadRunning = false;
std::lock_guard<std::mutex> lock(mFilterThreadLock);
return Result::SUCCESS;
}
@@ -321,8 +320,17 @@ void Filter::filterThreadLoop() {
usleep(1000 * 1000);
continue;
}
// After successfully write, send a callback and wait for the read to be done
if (mCallback_1_1 != nullptr) {
if (mConfigured) {
DemuxFilterEvent emptyEvent;
V1_1::DemuxFilterEventExt startEvent;
startEvent.events.resize(1);
startEvent.events[0].startId(mStartId++);
mCallback_1_1->onFilterEvent_1_1(emptyEvent, startEvent);
mConfigured = false;
}
mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt);
mFilterEventExt.events.resize(0);
} else if (mCallback != nullptr) {

View File

@@ -235,6 +235,9 @@ class Filter : public V1_1::IFilter {
// Scrambling status to be monitored
uint32_t mStatuses = 0;
bool mConfigured = false;
int mStartId = 0;
};
} // namespace implementation

View File

@@ -161,6 +161,14 @@ struct DemuxFilterEventExt {
DemuxFilterMmtpRecordEventExt mmtpRecord;
ScramblingStatus scramblingStatus;
/**
* An unique ID to mark the start point of receiving the valid filter events after
* reconfiguring the filter. It must be sent at least once in the first event after the
* filter is restarted. 0 is reserved for the newly opened filter's first start, which is
* optional for HAL to send.
*/
uint32_t startId;
};
/**

View File

@@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() {
ALOGW("[vts] pass and stop");
}
void FilterCallback::testStartIdAfterReconfigure() {
android::Mutex::Autolock autoLock(mMsgLock);
while (!mStartIdReceived) {
if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
EXPECT_TRUE(false) << "does not receive start id within timeout";
return;
}
}
mStartIdReceived = false;
ALOGW("[vts] pass and stop");
}
void FilterCallback::readFilterEventData() {
ALOGW("[vts] reading filter event");
// todo separate filter handlers
@@ -71,6 +83,10 @@ void FilterCallback::readFilterEventData() {
case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus:
mScramblingStatusEvent++;
break;
case DemuxFilterEventExt::Event::hidl_discriminator::startId:
ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId());
mStartIdReceived = true;
break;
default:
break;
}
@@ -90,8 +106,8 @@ bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) {
}
int av_fd = handle.getNativeHandle()->data[0];
uint8_t* buffer =
static_cast<uint8_t*>(mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0));
uint8_t* buffer = static_cast<uint8_t*>(
mmap(NULL, length + offset, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0));
if (buffer == MAP_FAILED) {
ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
return false;
@@ -271,3 +287,9 @@ AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_
}
return AssertionResult(status == Result::SUCCESS);
}
AssertionResult FilterTests::startIdTest(uint64_t filterId) {
EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
mFilterCallbacks[filterId]->testStartIdAfterReconfigure();
return AssertionResult(true);
}

View File

@@ -118,6 +118,7 @@ class FilterCallback : public IFilterCallback {
void testFilterDataOutput();
void testFilterScramblingEvent();
void testStartIdAfterReconfigure();
void readFilterEventData();
bool dumpAvData(DemuxFilterMediaEvent event);
@@ -138,6 +139,7 @@ class FilterCallback : public IFilterCallback {
int mPidFilterOutputCount = 0;
int mScramblingStatusEvent = 0;
bool mStartIdReceived = false;
};
class FilterTests {
@@ -160,6 +162,7 @@ class FilterTests {
AssertionResult startFilter(uint64_t filterId);
AssertionResult stopFilter(uint64_t filterId);
AssertionResult closeFilter(uint64_t filterId);
AssertionResult startIdTest(uint64_t filterId);
FilterEventType getFilterEventType(DemuxFilterType type) {
FilterEventType eventType = FilterEventType::UNDEFINED;

View File

@@ -57,6 +57,39 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
ASSERT_TRUE(mFrontendTests.closeFrontend());
}
void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf,
FilterConfig filterReconf,
FrontendConfig frontendConf) {
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
uint64_t filterId;
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
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_64bit(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.startIdTest(filterId));
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend());
}
void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
FrontendConfig frontendConf) {
uint32_t feId;
@@ -146,6 +179,13 @@ TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) {
configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]);
}
TEST_P(TunerFilterHidlTest, ReonfigFilterToReceiveStartId) {
description("Recofigure and restart a filter to test start id.");
// TODO use parameterized tests
reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1],
frontendArray[DVBT]);
}
TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
description("Feed ts data from frontend to recording and test with ts record filter");
recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);

View File

@@ -58,7 +58,8 @@ class TunerFilterHidlTest : public testing::TestWithParam<std::string> {
}
void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf);
void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf,
FrontendConfig frontendConf);
sp<ITuner> mService;
FrontendTests mFrontendTests;
DemuxTests mDemuxTests;