Merge "TunerHAL Handle PES Header in MediaFilterHandler"
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 3b9ca43..ade265c 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -853,11 +853,17 @@
     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 @@
     }
 
     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 @@
             }
         }
 
-        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;