DataSource.h revision d49dbd6b625cddb82f3f7bbeac62d48ef338ef0f
183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber/*
283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Copyright (C) 2009 The Android Open Source Project
383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber *
483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * you may not use this file except in compliance with the License.
683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * You may obtain a copy of the License at
783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber *
883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber *
1083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Unless required by applicable law or agreed to in writing, software
1183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * See the License for the specific language governing permissions and
1483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * limitations under the License.
1583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber */
1683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
1783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#ifndef DATA_SOURCE_H_
1883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
1983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#define DATA_SOURCE_H_
2083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
2183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <sys/types.h>
2283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <media/stagefright/MediaErrors.h>
2483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/Errors.h>
2583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/KeyedVector.h>
2683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/List.h>
2783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/RefBase.h>
2883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/threads.h>
2983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <drm/DrmManagerClient.h>
3083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
3183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Hubernamespace android {
3283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
3383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstruct AMessage;
3483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstruct AString;
3583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberclass  IDataSource;
3683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstruct IMediaHTTPService;
3783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberclass String8;
3883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstruct HTTPBase;
3983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
4083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberclass DataSource : public RefBase {
4183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberpublic:
4283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    enum Flags {
4383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        kWantsPrefetching      = 1,
4483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        kStreamedFromLocalHost = 2,
4583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        kIsCachingDataSource   = 4,
4683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        kIsHTTPBasedSource     = 8,
4783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        kIsLocalFileSource     = 16,
4883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    };
4983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
5083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    static sp<DataSource> CreateFromURI(
5183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            const sp<IMediaHTTPService> &httpService,
5283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            const char *uri,
5383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            const KeyedVector<String8, String8> *headers = NULL,
5483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            String8 *contentType = NULL,
5583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            HTTPBase *httpSource = NULL);
5683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
5783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
5883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);
5983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
6083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
6183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    DataSource() {}
6283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
6383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual status_t initCheck() const = 0;
6483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
6583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // Returns the number of bytes read, or -1 on failure. It's not an error if
6683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // this returns zero; it just means the given offset is equal to, or
6783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // beyond, the end of the source.
6883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
6983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
7083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // Convenience methods:
7183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    bool getUInt16(off64_t offset, uint16_t *x);
7283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
7383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    bool getUInt32(off64_t offset, uint32_t *x);
7483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    bool getUInt64(off64_t offset, uint64_t *x);
7583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
7683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // Reads in "count" entries of type T into vector *x.
7783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // Returns true if "count" entries can be read.
7883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // If fewer than "count" entries can be read, return false. In this case,
7983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // the output vector *x will still have those entries that were read. Call
8083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // x->size() to obtain the number of entries read.
8183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // The optional parameter chunkSize specifies how many entries should be
8283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // read from the data source at one time into a temporary buffer. Increasing
8383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // chunkSize can improve the performance at the cost of extra memory usage.
8483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // The default value for chunkSize is set to read at least 4k bytes at a
8583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // time, depending on sizeof(T).
8683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    template <typename T>
8783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    bool getVector(off64_t offset, Vector<T>* x, size_t count,
8883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber                   size_t chunkSize = (4095 / sizeof(T)) + 1);
8983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
9083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // May return ERROR_UNSUPPORTED.
9183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual status_t getSize(off64_t *size);
9283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
9383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual uint32_t flags() {
9483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return 0;
9583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
9683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
9783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual String8 toString() {
9883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return String8("<unspecified>");
9983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
10083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
10183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual status_t reconnectAtOffset(off64_t /*offset*/) {
10283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return ERROR_UNSUPPORTED;
10383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
10483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
10583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    ////////////////////////////////////////////////////////////////////////////
10683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
10783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // for DRM
10883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
10983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return NULL;
11083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
11183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual void getDrmInfo(sp<DecryptHandle> &/*handle*/, DrmManagerClient ** /*client*/) {};
11283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
11383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual String8 getUri() {
11483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return String8();
11583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
11683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
11783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual String8 getMIMEType() const;
11883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
11983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual void close() {};
12083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
12183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // creates an IDataSource wrapper to the DataSource.
12283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual sp<IDataSource> asIDataSource();
12383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
12483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // returns a pointer to IDataSource if it is wrapped.
12583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual sp<IDataSource> getIDataSource() const;
12683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
12783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberprotected:
12883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    virtual ~DataSource() {}
12983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
13083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberprivate:
13183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    DataSource(const DataSource &);
13283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    DataSource &operator=(const DataSource &);
13383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber};
13483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
13583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Hubertemplate <typename T>
13683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberbool DataSource::getVector(off64_t offset, Vector<T>* x, size_t count,
13783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber                           size_t chunkSize)
13883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber{
13983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    x->clear();
14083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    if (chunkSize == 0) {
14183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return false;
14283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
14383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    if (count == 0) {
14483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return true;
14583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
14683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
14783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    T tmp[chunkSize];
14883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    ssize_t numBytesRead;
14983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    size_t numBytesPerChunk = chunkSize * sizeof(T);
15083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    size_t i;
15183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
15283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    for (i = 0; i + chunkSize < count; i += chunkSize) {
15383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        // This loops is executed when more than chunkSize records need to be
15483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        // read.
15583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
15683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
15783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            return false;
1582720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        }
1592720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        if (numBytesRead < numBytesPerChunk) {
1602720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            // This case is triggered when the stream ends before the whole
1612720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            // chunk is read.
16283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
16383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber            return false;
16483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        }
16583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        x->appendArray(tmp, chunkSize);
16683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        offset += numBytesPerChunk;
16783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
16883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
16983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // There are (count - i) more records to read.
17083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // Right now, (count - i) <= chunkSize.
17183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    // We do the same thing as above, but with chunkSize replaced by count - i.
17283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
17383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    if (numBytesRead == -1) {
17483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber        return false;
17583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    }
17683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
17783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber    return x->size() == count;
17883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber}
17983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
18083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber}  // namespace android
18183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber
1822720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen#endif  // DATA_SOURCE_H_
1832720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen