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:
parent
e6a46c19bc
commit
de9709a03e
1 changed files with 34 additions and 7 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue