From 4a95c710b38f7f3e5955c31996082b453d422c41 Mon Sep 17 00:00:00 2001 From: Lucas Gates Date: Wed, 29 Jun 2022 21:22:37 +0000 Subject: [PATCH] SampleTunerTIS HAL Process TS for SectionEvents Currently, the HAL simply sends raw TS data when SectionEvents are created from a TS file. This CL will have the HAL process the TS packets and construct sections to be sent to the SectionFilter. A slight-modified TS protocol is used that mirrors the current implementation for PES filters. Bug: 237323181 Test: Manually using cuttlefish and the SampleTunerTvInput. SectionEvents should be received without the 4-byte TsHeader or any trailing data. Change-Id: Ief6b9beb8f48bda1b83a0bffb83698ca431b7b12 --- tv/tuner/aidl/default/Filter.cpp | 68 +++++++++++++++++++++++++------- tv/tuner/aidl/default/Filter.h | 4 ++ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp index 1d56303d2c..82e11cf294 100644 --- a/tv/tuner/aidl/default/Filter.cpp +++ b/tv/tuner/aidl/default/Filter.cpp @@ -961,24 +961,64 @@ void Filter::updateRecordOutput(vector& data) { return ::ndk::ScopedAStatus::ok(); } +// Read PSI (Program Specific Information) Sections from TransportStreams +// as defined in ISO/IEC 13818-1 Section 2.4.4 bool Filter::writeSectionsAndCreateEvent(vector& data) { // TODO check how many sections has been read ALOGD("[Filter] section handler"); - if (!writeDataToFilterMQ(data)) { - return false; - } - DemuxFilterSectionEvent secEvent; - secEvent = { - // temp dump meta data - .tableId = 0, - .version = 1, - .sectionNum = 1, - .dataLength = static_cast(data.size()), - }; - { - std::lock_guard lock(mFilterEventsLock); - mFilterEvents.push_back(DemuxFilterEvent::make(secEvent)); + // Transport Stream Packets are 188 bytes long, as defined in the + // Introduction of ISO/IEC 13818-1 + for (int i = 0; i < data.size(); i += 188) { + if (mSectionSizeLeft == 0) { + // Location for sectionSize as defined by Section 2.4.4 + // Note that the first 4 bytes skipped are the TsHeader + mSectionSizeLeft = ((data[i + 5] & 0x0f) << 8) | (data[i + 6] & 0xff); + mSectionSizeLeft += 3; + if (DEBUG_FILTER) { + ALOGD("[Filter] section data length %d", mSectionSizeLeft); + } + } + + // 184 bytes per packet is derived by subtracting the 4 byte length of + // the TsHeader from its 188 byte packet size + uint32_t endPoint = min(184u, mSectionSizeLeft); + // append data and check size + vector::const_iterator first = data.begin() + i + 4; + vector::const_iterator last = data.begin() + i + 4 + endPoint; + mSectionOutput.insert(mSectionOutput.end(), first, last); + // size does not match then continue + mSectionSizeLeft -= endPoint; + if (DEBUG_FILTER) { + ALOGD("[Filter] section data left %d", mSectionSizeLeft); + } + if (mSectionSizeLeft > 0) { + continue; + } + + if (!writeDataToFilterMQ(mSectionOutput)) { + mSectionOutput.clear(); + return false; + } + + DemuxFilterSectionEvent secEvent; + secEvent = { + // temp dump meta data + .tableId = 0, + .version = 1, + .sectionNum = 1, + .dataLength = static_cast(mSectionOutput.size()), + }; + if (DEBUG_FILTER) { + ALOGD("[Filter] assembled section data length %lld", secEvent.dataLength); + } + + { + std::lock_guard lock(mFilterEventsLock); + mFilterEvents.push_back( + DemuxFilterEvent::make(secEvent)); + } + mSectionOutput.clear(); } return true; diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h index c559862956..06c2c26e30 100644 --- a/tv/tuner/aidl/default/Filter.h +++ b/tv/tuner/aidl/default/Filter.h @@ -258,6 +258,10 @@ class Filter : public BnFilter { std::mutex mFilterOutputLock; std::mutex mRecordFilterOutputLock; + // handle single Section filter + uint32_t mSectionSizeLeft = 0; + vector mSectionOutput; + // temp handle single PES filter // TODO handle mulptiple Pes filters int mPesSizeLeft = 0;