Add support for mpeg2 transport streams to the RTSP implementation.

Change-Id: I409d7133a53a71e62523b1acc2b03302fcf824a5
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 4a704e3..5a7a785 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -23,6 +23,7 @@
 #include "AnotherPacketSource.h"
 #include "MyHandler.h"
 
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 
 namespace android {
@@ -159,6 +160,13 @@
 }
 
 sp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
+    if (mTSParser != NULL) {
+        sp<MediaSource> source = mTSParser->getSource(
+                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
+
+        return static_cast<AnotherPacketSource *>(source.get());
+    }
+
     return audio ? mAudioTrack : mVideoTrack;
 }
 
@@ -255,7 +263,12 @@
         {
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
+
+            if (mTSParser == NULL) {
+                CHECK_LT(trackIndex, mTracks.size());
+            } else {
+                CHECK_EQ(trackIndex, 0u);
+            }
 
             sp<ABuffer> accessUnit;
             CHECK(msg->findBuffer("accessUnit", &accessUnit));
@@ -267,6 +280,37 @@
                 break;
             }
 
+            if (mTSParser != NULL) {
+                size_t offset = 0;
+                status_t err = OK;
+                while (offset + 188 <= accessUnit->size()) {
+                    err = mTSParser->feedTSPacket(
+                            accessUnit->data() + offset, 188);
+                    if (err != OK) {
+                        break;
+                    }
+
+                    offset += 188;
+                }
+
+                if (offset < accessUnit->size()) {
+                    err = ERROR_MALFORMED;
+                }
+
+                if (err != OK) {
+                    sp<AnotherPacketSource> source = getSource(false /* audio */);
+                    if (source != NULL) {
+                        source->signalEOS(err);
+                    }
+
+                    source = getSource(true /* audio */);
+                    if (source != NULL) {
+                        source->signalEOS(err);
+                    }
+                }
+                break;
+            }
+
             TrackInfo *info = &mTracks.editItemAt(trackIndex);
 
             sp<AnotherPacketSource> source = info->mSource;
@@ -296,14 +340,28 @@
 
         case MyHandler::kWhatEOS:
         {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
             int32_t finalResult;
             CHECK(msg->findInt32("finalResult", &finalResult));
             CHECK_NE(finalResult, (status_t)OK);
 
+            if (mTSParser != NULL) {
+                sp<AnotherPacketSource> source = getSource(false /* audio */);
+                if (source != NULL) {
+                    source->signalEOS(finalResult);
+                }
+
+                source = getSource(true /* audio */);
+                if (source != NULL) {
+                    source->signalEOS(finalResult);
+                }
+
+                return;
+            }
+
+            size_t trackIndex;
+            CHECK(msg->findSize("trackIndex", &trackIndex));
+            CHECK_LT(trackIndex, mTracks.size());
+
             TrackInfo *info = &mTracks.editItemAt(trackIndex);
             sp<AnotherPacketSource> source = info->mSource;
             if (source != NULL) {
@@ -364,6 +422,14 @@
         const char *mime;
         CHECK(format->findCString(kKeyMIMEType, &mime));
 
+        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
+            // Very special case for MPEG2 Transport Streams.
+            CHECK_EQ(numTracks, 1u);
+
+            mTSParser = new ATSParser;
+            return;
+        }
+
         bool isAudio = !strncasecmp(mime, "audio/", 6);
         bool isVideo = !strncasecmp(mime, "video/", 6);