diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp index 568ab0776f..7a1c3d92bd 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 80faee78b4..b638f0c3e7 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 uint32_t mPesSizeLeft = 0;