Add new features to tuner HAL.

*) Add DTS info to DemuxFilterMediaEvent.
*) Allow to ignore download Id in DemuxFilterDownloadSettings and put
download id into DemuxFilterDownloadEvent.
*) Support dumpsys.
*) Change section data size 64 bits.
*) Support FrontendStatus streamIdList.

Bug: 183583908
Bug: 183024067
Bug: 184017033
Bug: 203181023
Bug: 171540818
Test: atest VtsHalTvTunerTargetTest
Test: atest android.media.tv.tuner.cts
Test: dumpsys android.hardware.tv.tuner.ITuner/default
Change-Id: I7478d008fc50da6700c551ae398dca15f8b350be
This commit is contained in:
Hongguang
2021-11-23 10:29:15 -08:00
committed by Hongguang Chen
parent 8590b861e6
commit 2ecfc3989d
25 changed files with 169 additions and 7 deletions

View File

@@ -36,6 +36,7 @@ package android.hardware.tv.tuner;
@VintfStability
parcelable DemuxFilterDownloadEvent {
int itemId;
int downloadId;
int mpuSequenceNumber;
int itemFragmentIndex;
int lastItemFragmentIndex;

View File

@@ -35,5 +35,6 @@ package android.hardware.tv.tuner;
/* @hide */
@VintfStability
parcelable DemuxFilterDownloadSettings {
boolean useDownloadId;
int downloadId;
}

View File

@@ -38,6 +38,8 @@ parcelable DemuxFilterMediaEvent {
int streamId;
boolean isPtsPresent;
long pts;
boolean isDtsPresent;
long dts;
long dataLength;
long offset;
android.hardware.common.NativeHandle avMemory;

View File

@@ -38,5 +38,5 @@ parcelable DemuxFilterSectionEvent {
int tableId;
int version;
int sectionNum;
int dataLength;
long dataLength;
}

View File

@@ -74,4 +74,5 @@ union FrontendStatus {
boolean isShortFrames;
android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
int[] streamIdList;
}

View File

@@ -74,4 +74,5 @@ enum FrontendStatusType {
IS_SHORT_FRAMES = 36,
ISDBT_MODE = 37,
ISDBT_PARTIAL_RECEPTION_FLAG = 38,
STREAM_ID_LIST = 39,
}

View File

@@ -27,6 +27,11 @@ parcelable DemuxFilterDownloadEvent {
*/
int itemId;
/**
* Uniquely identify data content within the same Package ID (PID).
*/
int downloadId;
/**
* MPU sequence number of filtered data (only for MMTP)
*/

View File

@@ -22,6 +22,11 @@ package android.hardware.tv.tuner;
*/
@VintfStability
parcelable DemuxFilterDownloadSettings {
/**
* Whether download ID should be used.
*/
boolean useDownloadId;
/**
* Download ID (also known as the carousel ID) is carried in the PMT in
* ISO/IEC 13818-1 for the service containing the object carousel.

View File

@@ -39,6 +39,16 @@ parcelable DemuxFilterMediaEvent {
*/
long pts;
/**
* true if DTS is present in the PES header.
*/
boolean isDtsPresent;
/**
* Decode TimeStamp for audio or video frame.
*/
long dts;
/**
* Data size in bytes of audio or video frame
*/

View File

@@ -40,5 +40,5 @@ parcelable DemuxFilterSectionEvent {
/**
* Data size in bytes of filtered data
*/
int dataLength;
long dataLength;
}

View File

@@ -202,4 +202,10 @@ union FrontendStatus {
* ISDB-T Partial Reception Flag.
*/
FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
/**
* Stream ID list included in a transponder.
*/
int[] streamIdList;
}

View File

@@ -218,4 +218,9 @@ enum FrontendStatusType {
* ISDB-T Partial Reception Flag.
*/
ISDBT_PARTIAL_RECEPTION_FLAG,
/**
* Stream ID list included in a transponder.
*/
STREAM_ID_LIST,
}

View File

@@ -410,6 +410,37 @@ bool Demux::isRecording() {
return mIsRecording;
}
binder_status_t Demux::dump(int fd, const char** args, uint32_t numArgs) {
dprintf(fd, " Demux %d:\n", mDemuxId);
dprintf(fd, " mIsRecording %d\n", mIsRecording);
{
dprintf(fd, " Filters:\n");
map<int64_t, std::shared_ptr<Filter>>::iterator it;
for (it = mFilters.begin(); it != mFilters.end(); it++) {
it->second->dump(fd, args, numArgs);
}
}
{
dprintf(fd, " TimeFilter:\n");
if (mTimeFilter != nullptr) {
mTimeFilter->dump(fd, args, numArgs);
}
}
{
dprintf(fd, " DvrPlayback:\n");
if (mDvrPlayback != nullptr) {
mDvrPlayback->dump(fd, args, numArgs);
}
}
{
dprintf(fd, " DvrRecord:\n");
if (mDvrRecord != nullptr) {
mDvrRecord->dump(fd, args, numArgs);
}
}
return STATUS_OK;
}
bool Demux::attachRecordFilter(int64_t filterId) {
if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
!mFilters[filterId]->isRecordFilter()) {

View File

@@ -71,6 +71,8 @@ class Demux : public BnDemux {
::ndk::ScopedAStatus connectCiCam(int32_t in_ciCamId) override;
::ndk::ScopedAStatus disconnectCiCam() override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
// Functions interacts with Tuner Service
void stopFrontendInput();
::ndk::ScopedAStatus removeFilter(int64_t filterId);

View File

@@ -177,6 +177,13 @@ EventFlag* Dvr::getDvrEventFlag() {
return mDvrEventFlag;
}
binder_status_t Dvr::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
dprintf(fd, " Dvr:\n");
dprintf(fd, " mType: %hhd\n", mType);
dprintf(fd, " mDvrThreadRunning: %d\n", (bool)mDvrThreadRunning);
return STATUS_OK;
}
void Dvr::playbackThreadLoop() {
ALOGD("[Dvr] playback threadLoop start.");

View File

@@ -71,6 +71,8 @@ class Dvr : public BnDvr {
::ndk::ScopedAStatus flush() override;
::ndk::ScopedAStatus close() override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
/**
* To create a DvrMQ and its Event Flag.
*

View File

@@ -22,6 +22,7 @@
#include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <aidlcommonsupport/NativeHandle.h>
#include <inttypes.h>
#include <utils/Log.h>
#include "Filter.h"
@@ -655,6 +656,17 @@ void Filter::freeSharedAvHandle() {
mSharedAvMemHandle = nullptr;
}
binder_status_t Filter::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
dprintf(fd, " Filter %" PRIu64 ":\n", mFilterId);
dprintf(fd, " Main type: %d\n", mType.mainType);
dprintf(fd, " mIsMediaFilter: %d\n", mIsMediaFilter);
dprintf(fd, " mIsPcrFilter: %d\n", mIsPcrFilter);
dprintf(fd, " mIsRecordFilter: %d\n", mIsRecordFilter);
dprintf(fd, " mIsUsingFMQ: %d\n", mIsUsingFMQ);
dprintf(fd, " mFilterThreadRunning: %d\n", (bool)mFilterThreadRunning);
return STATUS_OK;
}
void Filter::maySendFilterStatusCallback() {
if (!mIsUsingFMQ) {
return;
@@ -1148,6 +1160,7 @@ void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
DemuxFilterMediaEvent mediaEvent;
mediaEvent.streamId = 1;
mediaEvent.isPtsPresent = true;
mediaEvent.isDtsPresent = false;
mediaEvent.dataLength = 3;
mediaEvent.offset = 4;
mediaEvent.isSecureMemory = true;
@@ -1238,6 +1251,7 @@ void Filter::createPesEvent(vector<DemuxFilterEvent>& events) {
void Filter::createDownloadEvent(vector<DemuxFilterEvent>& events) {
DemuxFilterDownloadEvent download;
download.itemId = 1;
download.downloadId = 1;
download.mpuSequenceNumber = 2;
download.itemFragmentIndex = 3;
download.lastItemFragmentIndex = 4;

View File

@@ -126,6 +126,8 @@ class Filter : public BnFilter {
::ndk::ScopedAStatus setDataSource(const std::shared_ptr<IFilter>& in_filter) override;
::ndk::ScopedAStatus setDelayHint(const FilterDelayHint& in_hint) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
/**
* To create a FilterMQ and its Event Flag.
*

View File

@@ -676,6 +676,11 @@ Frontend::~Frontend() {}
FrontendIsdbtPartialReceptionFlag::AUTO);
break;
}
case FrontendStatusType::STREAM_ID_LIST: {
vector<int32_t> streamIds = {0, 1};
status.set<FrontendStatus::streamIdList>(streamIds);
break;
}
default: {
continue;
}
@@ -718,6 +723,14 @@ Frontend::~Frontend() {}
return ::ndk::ScopedAStatus::ok();
}
binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
dprintf(fd, " Frontend %d\n", mId);
dprintf(fd, " mType: %d\n", mType);
dprintf(fd, " mIsLocked: %d\n", mIsLocked);
dprintf(fd, " mCiCamId: %d\n", mCiCamId);
return STATUS_OK;
}
FrontendType Frontend::getFrontendType() {
return mType;
}

View File

@@ -50,6 +50,8 @@ class Frontend : public BnFrontend {
::ndk::ScopedAStatus linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) override;
::ndk::ScopedAStatus unlinkCiCam(int32_t in_ciCamId) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
FrontendType getFrontendType();
int32_t getFrontendId();
string getSourceFile();

View File

@@ -83,6 +83,12 @@ TimeFilter::~TimeFilter() {}
return ::ndk::ScopedAStatus::ok();
}
binder_status_t TimeFilter::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
dprintf(fd, " TimeFilter:\n");
dprintf(fd, " mTimeStamp: %" PRIu64 "\n", mTimeStamp);
return STATUS_OK;
}
} // namespace tuner
} // namespace tv
} // namespace hardware

View File

@@ -44,8 +44,10 @@ class TimeFilter : public BnTimeFilter {
::ndk::ScopedAStatus getSourceTime(int64_t* _aidl_return) override;
::ndk::ScopedAStatus close() override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
private:
std::shared_ptr<Demux> mDemux;
::std::shared_ptr<Demux> mDemux;
uint64_t mTimeStamp = INVALID_TIME_STAMP;
time_t mBeginTime;
};

View File

@@ -55,9 +55,13 @@ void Tuner::init() {
capsIsdbs.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
mFrontendCaps[0] = capsIsdbs;
statusCaps = {
FrontendStatusType::DEMOD_LOCK, FrontendStatusType::SNR,
FrontendStatusType::FEC, FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
FrontendStatusType::DEMOD_LOCK,
FrontendStatusType::SNR,
FrontendStatusType::FEC,
FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS,
FrontendStatusType::ROLL_OFF,
FrontendStatusType::STREAM_ID_LIST,
};
mFrontendStatusCaps[0] = statusCaps;
@@ -169,7 +173,7 @@ void Tuner::init() {
statusCaps = {
FrontendStatusType::DEMOD_LOCK, FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
FrontendStatusType::IS_SHORT_FRAMES,
FrontendStatusType::IS_SHORT_FRAMES, FrontendStatusType::STREAM_ID_LIST,
};
mFrontendStatusCaps[8] = statusCaps;
@@ -313,6 +317,33 @@ std::shared_ptr<Frontend> Tuner::getFrontendById(int32_t frontendId) {
return ::ndk::ScopedAStatus::ok();
}
binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
ALOGV("%s", __FUNCTION__);
{
dprintf(fd, "Frontends:\n");
for (int i = 0; i < mFrontendSize; i++) {
mFrontends[i]->dump(fd, args, numArgs);
for (int j = 0; j < mFrontendStatusCaps[i].size(); j++) {
dprintf(fd, " statusCap: %d\n", mFrontendStatusCaps[i][j]);
}
}
}
{
dprintf(fd, "Demuxs:\n");
map<int32_t, std::shared_ptr<Demux>>::iterator it;
for (it = mDemuxes.begin(); it != mDemuxes.end(); it++) {
it->second->dump(fd, args, numArgs);
}
}
{
dprintf(fd, "Lnbs:\n");
for (int i = 0; i < mLnbs.size(); i++) {
mLnbs[i]->dump(fd, args, numArgs);
}
}
return STATUS_OK;
}
void Tuner::setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId) {
mFrontendToDemux[frontendId] = demuxId;
if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
@@ -332,6 +363,10 @@ void Tuner::removeDemux(int32_t demuxId) {
}
void Tuner::removeFrontend(int32_t frontendId) {
map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
if (it != mFrontendToDemux.end()) {
mDemuxes.erase(it->second);
}
mFrontendToDemux.erase(frontendId);
}

View File

@@ -57,6 +57,8 @@ class Tuner : public BnTuner {
std::vector<int32_t>* out_lnbId,
std::shared_ptr<ILnb>* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
std::shared_ptr<Frontend> getFrontendById(int32_t frontendId);
void setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId);
void frontendStartTune(int32_t frontendId);

View File

@@ -398,6 +398,13 @@ void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
break;
}
case FrontendStatusType::STREAM_ID_LIST: {
ASSERT_TRUE(std::equal(
realStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin(),
realStatuses[i].get<FrontendStatus::Tag::streamIdList>().end(),
expectStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin()));
break;
}
default: {
continue;
}