OSDN Git Service

Detect live streams
authorRoger Jönsson <roger1.jonsson@sonymobile.com>
Thu, 17 Jan 2013 12:22:31 +0000 (13:22 +0100)
committerAndreas Huber <andih@google.com>
Tue, 5 Feb 2013 18:50:06 +0000 (10:50 -0800)
The information is used to decide on visibility of pause button and
to handle the duration clock correctly.

Change-Id: I286ac992fd171c7fc313e429326d38b6fc80e3fb

media/libstagefright/rtsp/MyHandler.h

index b7183b1..cdd00e4 100644 (file)
@@ -133,7 +133,7 @@ struct MyHandler : public AHandler {
           mTryFakeRTCP(false),
           mReceivedFirstRTCPPacket(false),
           mReceivedFirstRTPPacket(false),
-          mSeekable(false),
+          mSeekable(true),
           mKeepAliveTimeoutUs(kDefaultKeepAliveTimeoutUs),
           mKeepAliveGeneration(0) {
         mNetLooper->setName("rtsp net");
@@ -360,6 +360,39 @@ struct MyHandler : public AHandler {
         return true;
     }
 
+    static bool isLiveStream(const sp<ASessionDescription> &desc) {
+        AString attrLiveStream;
+        if (desc->findAttribute(0, "a=LiveStream", &attrLiveStream)) {
+            ssize_t semicolonPos = attrLiveStream.find(";", 2);
+
+            const char* liveStreamValue;
+            if (semicolonPos < 0) {
+                liveStreamValue = attrLiveStream.c_str();
+            } else {
+                AString valString;
+                valString.setTo(attrLiveStream,
+                        semicolonPos + 1,
+                        attrLiveStream.size() - semicolonPos - 1);
+                liveStreamValue = valString.c_str();
+            }
+
+            uint32_t value = strtoul(liveStreamValue, NULL, 10);
+            if (value == 1) {
+                ALOGV("found live stream");
+                return true;
+            }
+        } else {
+            // It is a live stream if no duration is returned
+            int64_t durationUs;
+            if (!desc->getDurationUs(&durationUs)) {
+                ALOGV("No duration found, assume live stream");
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     virtual void onMessageReceived(const sp<AMessage> &msg) {
         switch (msg->what()) {
             case 'conn':
@@ -457,6 +490,8 @@ struct MyHandler : public AHandler {
                                 }
                             }
 
+                            mSeekable = !isLiveStream(mSessionDesc);
+
                             if (!mBaseURL.startsWith("rtsp://")) {
                                 // Some misbehaving servers specify a relative
                                 // URL in one of the locations above, combine
@@ -518,6 +553,8 @@ struct MyHandler : public AHandler {
                     } else {
                         mBaseURL = mSessionURL;
 
+                        mSeekable = !isLiveStream(mSessionDesc);
+
                         if (mSessionDesc->countTracks() < 2) {
                             // There's no actual tracks in this session.
                             // The first "track" is merely session meta
@@ -783,7 +820,7 @@ struct MyHandler : public AHandler {
                 mNumAccessUnitsReceived = 0;
                 mReceivedFirstRTCPPacket = false;
                 mReceivedFirstRTPPacket = false;
-                mSeekable = false;
+                mSeekable = true;
 
                 sp<AMessage> reply = new AMessage('tear', id());
 
@@ -1143,7 +1180,6 @@ struct MyHandler : public AHandler {
     }
 
     void parsePlayResponse(const sp<ARTSPResponse> &response) {
-        mSeekable = false;
         if (mTracks.size() == 0) {
             ALOGV("parsePlayResponse: late packets ignored.");
             return;
@@ -1218,8 +1254,6 @@ struct MyHandler : public AHandler {
 
             ++n;
         }
-
-        mSeekable = true;
     }
 
     sp<MetaData> getTrackFormat(size_t index, int32_t *timeScale) {