TunerHAL Handle PES Header in MediaFilterHandler

As according to the ISO/IEC 13818-1 specification, media
data in TransportStreams comes in PES packets which are
made up of TS packets. Currently, the MediaFilterHandler
strips out TS Headers, but leaves the PES headers in with
the Media data. This CL has the MediaFilterHandler process
and remove the PES Header from the Media data, while saving
the Presentation Time Stamp if it exists.

Bug: 238889790
Test: Manually using Cuttlefish and SampleTunerTIS to
receive events. Also tested on the VTS.

Change-Id: Idd4fe06f15f5420afd0c473128d8b30f5ca779c6
This commit is contained in:
Lucas Gates 2022-07-13 00:35:47 +00:00
parent e6a46c19bc
commit de9709a03e

View file

@ -853,11 +853,17 @@ void Filter::updateRecordOutput(vector<int8_t>& data) {
return ::ndk::ScopedAStatus::ok();
}
// Read PES (Packetized Elementary Stream) Packets from TransportStreams
// as defined in ISO/IEC 13818-1 Section 2.4.3.6. Create MediaEvents
// containing only their data without TS or PES headers.
::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
if (mFilterOutput.empty()) {
return ::ndk::ScopedAStatus::ok();
}
// mPts being set before our MediaFilterHandler begins indicates that all
// metadata has already been handled. We can therefore create an event
// with the existing data. This method is used when processing ES files.
::ndk::ScopedAStatus result;
if (mPts) {
result = createMediaFilterEventWithIon(mFilterOutput);
@ -868,17 +874,38 @@ void Filter::updateRecordOutput(vector<int8_t>& data) {
}
for (int i = 0; i < mFilterOutput.size(); i += 188) {
// Every packet has a 4 Byte TS Header preceding it
uint32_t headerSize = 4;
if (mPesSizeLeft == 0) {
uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
mFilterOutput[i + 6];
// Packet Start Code Prefix is defined as the first 3 bytes of
// the PES Header and should always have the value 0x000001
uint32_t prefix = (static_cast<uint8_t>(mFilterOutput[i + 4]) << 16) |
(static_cast<uint8_t>(mFilterOutput[i + 5]) << 8) |
static_cast<uint8_t>(mFilterOutput[i + 6]);
if (DEBUG_FILTER) {
ALOGD("[Filter] prefix %d", prefix);
}
if (prefix == 0x000001) {
// TODO handle mulptiple Pes filters
// TODO handle multiple Pes filters
// Location of PES fields from ISO/IEC 13818-1 Section 2.4.3.6
mPesSizeLeft = (static_cast<uint8_t>(mFilterOutput[i + 8]) << 8) |
static_cast<uint8_t>(mFilterOutput[i + 9]);
mPesSizeLeft += 6;
bool hasPts = static_cast<uint8_t>(mFilterOutput[i + 11]) & 0x80;
uint8_t optionalFieldsLength = static_cast<uint8_t>(mFilterOutput[i + 12]);
headerSize += 9 + optionalFieldsLength;
if (hasPts) {
// Pts is a 33-bit field which is stored across 5 bytes, with
// bits in between as reserved fields which must be ignored
mPts = 0;
mPts |= (static_cast<uint8_t>(mFilterOutput[i + 13]) & 0x0e) << 29;
mPts |= (static_cast<uint8_t>(mFilterOutput[i + 14]) & 0xff) << 22;
mPts |= (static_cast<uint8_t>(mFilterOutput[i + 15]) & 0xfe) << 14;
mPts |= (static_cast<uint8_t>(mFilterOutput[i + 16]) & 0xff) << 7;
mPts |= (static_cast<uint8_t>(mFilterOutput[i + 17]) & 0xfe) >> 1;
}
if (DEBUG_FILTER) {
ALOGD("[Filter] pes data length %d", mPesSizeLeft);
}
@ -887,10 +914,10 @@ void Filter::updateRecordOutput(vector<int8_t>& data) {
}
}
uint32_t endPoint = min(184u, mPesSizeLeft);
uint32_t endPoint = min(188u - headerSize, mPesSizeLeft);
// append data and check size
vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + headerSize;
vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + headerSize + endPoint;
mPesOutput.insert(mPesOutput.end(), first, last);
// size does not match then continue
mPesSizeLeft -= endPoint;