OSDN Git Service

Properly advertise the content length of the HTTP stream if available.
authorAndreas Huber <andih@google.com>
Tue, 2 Feb 2010 18:38:40 +0000 (10:38 -0800)
committerAndreas Huber <andih@google.com>
Tue, 2 Feb 2010 18:38:40 +0000 (10:38 -0800)
related-to-bug: 2312941

include/media/stagefright/CachingDataSource.h
include/media/stagefright/HTTPDataSource.h
media/libstagefright/CachingDataSource.cpp
media/libstagefright/HTTPDataSource.cpp

index 30b7ad9..42d50e5 100644 (file)
@@ -33,6 +33,8 @@ public:
 
     virtual ssize_t readAt(off_t offset, void *data, size_t size);
 
+    virtual status_t getSize(off_t *size);
+
     virtual uint32_t flags();
 
 protected:
index 895cda3..25a90bf 100644 (file)
@@ -39,6 +39,8 @@ public:
 
     virtual ssize_t readAt(off_t offset, void *data, size_t size);
 
+    virtual status_t getSize(off_t *size);
+
     virtual uint32_t flags() {
         return kWantsPrefetching;
     }
@@ -63,8 +65,15 @@ private:
     off_t mBufferOffset;
     bool mFirstRequest;
 
+    bool mContentLengthValid;
+    unsigned long long mContentLength;
+
     status_t mInitCheck;
 
+    void init(
+            const char *_host, int port, const char *_path,
+            const KeyedVector<String8, String8> *headers);
+
     ssize_t sendRangeRequest(size_t offset);
     void initHeaders(const KeyedVector<String8, String8> *overrides);
 
index 8d04ead..1ca463e 100644 (file)
@@ -65,6 +65,10 @@ status_t CachingDataSource::initCheck() const {
     return mSource->initCheck();
 }
 
+status_t CachingDataSource::getSize(off_t *size) {
+    return mSource->getSize(size);
+}
+
 uint32_t CachingDataSource::flags() {
     return mSource->flags();
 }
index e1ddfef..bb3b43c 100644 (file)
@@ -94,19 +94,9 @@ static bool PerformRedirectIfNecessary(
 }
 
 HTTPDataSource::HTTPDataSource(
-        const char *uri, const KeyedVector<String8, String8> *headers)
-    : mHttp(new HTTPStream),
-      mHost(NULL),
-      mPort(0),
-      mPath(NULL),
-      mBuffer(malloc(kBufferSize)),
-      mBufferLength(0),
-      mBufferOffset(0),
-      mFirstRequest(true) {
+        const char *uri, const KeyedVector<String8, String8> *headers) {
     CHECK(!strncasecmp("http://", uri, 7));
 
-    initHeaders(headers);
-
     string host;
     string path;
     int port;
@@ -133,33 +123,28 @@ HTTPDataSource::HTTPDataSource(
         host = string(host, 0, colon - host.c_str());
     }
 
-    do {
-        LOGI("Connecting to host '%s', port %d, path '%s'",
-             host.c_str(), port, path.c_str());
-
-        mInitCheck = mHttp->connect(host.c_str(), port);
-
-        if (mInitCheck != OK) {
-            return;
-        }
-    } while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port));
-
-    mHost = strdup(host.c_str());
-    mPort = port;
-    mPath = strdup(path.c_str());
+    init(host.c_str(), port, path.c_str(), headers);
 }
 
 HTTPDataSource::HTTPDataSource(
         const char *_host, int port, const char *_path,
-        const KeyedVector<String8, String8> *headers)
-    : mHttp(new HTTPStream),
-      mHost(NULL),
-      mPort(0),
-      mPath(NULL),
-      mBuffer(malloc(kBufferSize)),
-      mBufferLength(0),
-      mBufferOffset(0),
-      mFirstRequest(true) {
+        const KeyedVector<String8, String8> *headers) {
+    init(_host, port, _path, headers);
+}
+
+void HTTPDataSource::init(
+        const char *_host, int port, const char *_path,
+        const KeyedVector<String8, String8> *headers) {
+    mHttp = new HTTPStream;
+    mHost = NULL;
+    mPort = 0;
+    mPath = NULL,
+    mBuffer = malloc(kBufferSize);
+    mBufferLength = 0;
+    mBufferOffset = 0;
+    mFirstRequest = true;
+    mContentLengthValid = false;
+
     initHeaders(headers);
 
     string host = _host;
@@ -176,6 +161,13 @@ HTTPDataSource::HTTPDataSource(
         }
     } while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port));
 
+    string value;
+    if (mHttp->find_header_value("Content-Length", &value)) {
+        char *end;
+        mContentLength = strtoull(value.c_str(), &end, 10);
+        mContentLengthValid = true;
+    }
+
     mHost = strdup(host.c_str());
     mPort = port;
     mPath = strdup(path.c_str());
@@ -185,6 +177,22 @@ status_t HTTPDataSource::initCheck() const {
     return mInitCheck;
 }
 
+status_t HTTPDataSource::getSize(off_t *size) {
+    *size = 0;
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (!mContentLengthValid) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    *size = mContentLength;
+
+    return OK;
+}
+
 HTTPDataSource::~HTTPDataSource() {
     mHttp->disconnect();
 
@@ -272,7 +280,7 @@ ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
     }
 
     ssize_t contentLength = 0;
-    if (mFirstRequest || offset != mBufferOffset + mBufferLength) {
+    if (mFirstRequest || offset != (off_t)(mBufferOffset + mBufferLength)) {
         if (!mFirstRequest) {
             LOGV("new range offset=%ld (old=%ld)",
                  offset, mBufferOffset + mBufferLength);