FileSource.cpp revision c7fc37a3dab9bd1f96713649f351b5990e6316ff
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/FileSource.h>
180c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h>
19c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <sys/types.h>
20c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <unistd.h>
2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::FileSource(const char *filename)
2503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    : mFile(fopen(filename, "rb")),
264e6572967da698d568a44d18797b751ec8ae5401Andreas Huber      mFd(mFile == NULL ? -1 : fileno(mFile)),
2703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber      mOffset(0),
28dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mLength(-1),
29dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDecryptHandle(NULL),
30dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmManagerClient(NULL),
31dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBufOffset(0),
32dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBufSize(0),
33dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBuf(NULL){
3403475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber}
3503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber
3603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas HuberFileSource::FileSource(int fd, int64_t offset, int64_t length)
3703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    : mFile(fdopen(fd, "rb")),
38dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFd(fd),
3903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber      mOffset(offset),
40dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mLength(length),
41dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDecryptHandle(NULL),
42dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmManagerClient(NULL),
43dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBufOffset(0),
44dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBufSize(0),
45dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDrmBuf(NULL){
4603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    CHECK(offset >= 0);
4703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    CHECK(length >= 0);
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::~FileSource() {
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mFile != NULL) {
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        fclose(mFile);
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mFile = NULL;
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
55dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
56dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDrmBuf != NULL) {
57dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete[] mDrmBuf;
58dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmBuf = NULL;
59dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huberstatus_t FileSource::initCheck() const {
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mFile != NULL ? OK : NO_INIT;
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
66c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
673d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber    if (mFile == NULL) {
683d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber        return NO_INIT;
693d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber    }
703d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7303475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    if (mLength >= 0) {
7403475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        if (offset >= mLength) {
7503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber            return 0;  // read beyond EOF.
7603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        }
7703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        int64_t numAvailable = mLength - offset;
7803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        if ((int64_t)size > numAvailable) {
7903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber            size = numAvailable;
8003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        }
8103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    }
8203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber
83dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
84dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            == mDecryptHandle->decryptApiType) {
85dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return readAtDRM(offset, data, size);
86dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang   } else {
87c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
88c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        if (result == -1) {
89dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            LOGE("seek to %lld failed", offset + mOffset);
90dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return UNKNOWN_ERROR;
91dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
93c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        return ::read(mFd, data, size);
94dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
9503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber}
9603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber
97c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t FileSource::getSize(off64_t *size) {
983d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber    if (mFile == NULL) {
993d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber        return NO_INIT;
1003d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber    }
1013d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber
10203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    if (mLength >= 0) {
10303475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        *size = mLength;
10403475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber
10503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber        return OK;
10603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    }
10703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber
108c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    *size = lseek64(mFd, 0, SEEK_END);
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber    return OK;
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
113dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria WangDecryptHandle* FileSource::DrmInitialization(DrmManagerClient* client) {
114b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (client == NULL) {
115b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        return NULL;
116b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
117dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mDrmManagerClient = client;
118b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle == NULL) {
120dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDecryptHandle = mDrmManagerClient->openDecryptSession(
121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                mFd, mOffset, mLength);
122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
123dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
124dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle == NULL) {
125dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmManagerClient = NULL;
126dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
127dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
128dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mDecryptHandle;
129dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
130dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
131dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangvoid FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
132dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *handle = mDecryptHandle;
133dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
134dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *client = mDrmManagerClient;
135dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
137c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAtDRM(off64_t offset, void *data, size_t size) {
138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size_t DRM_CACHE_SIZE = 1024;
139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDrmBuf == NULL) {
140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
143dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset
144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            && (offset + mOffset + size) <= (mDrmBufOffset + mDrmBufSize)) {
145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        /* Use buffered data */
146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size);
147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return size;
148dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    } else if (size <= DRM_CACHE_SIZE) {
149dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        /* Buffer new data */
150dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmBufOffset =  offset + mOffset;
151dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf,
152dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                DRM_CACHE_SIZE, offset + mOffset);
153dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDrmBufSize > 0) {
154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            int64_t dataRead = 0;
155dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dataRead = size > mDrmBufSize ? mDrmBufSize : size;
156dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            memcpy(data, (void*)mDrmBuf, dataRead);
157dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return dataRead;
158dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
159dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return mDrmBufSize;
160dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
161dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    } else {
162dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        /* Too big chunk to cache. Call DRM directly */
163dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset);
164dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
165dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
167