Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <media/stagefright/FileSource.h>
     18 #include <media/stagefright/MediaDebug.h>
     19 
     20 namespace android {
     21 
     22 FileSource::FileSource(const char *filename)
     23     : mFile(fopen(filename, "rb")),
     24       mOffset(0),
     25       mLength(-1) {
     26 }
     27 
     28 FileSource::FileSource(int fd, int64_t offset, int64_t length)
     29     : mFile(fdopen(fd, "rb")),
     30       mOffset(offset),
     31       mLength(length) {
     32     CHECK(offset >= 0);
     33     CHECK(length >= 0);
     34 }
     35 
     36 FileSource::~FileSource() {
     37     if (mFile != NULL) {
     38         fclose(mFile);
     39         mFile = NULL;
     40     }
     41 }
     42 
     43 status_t FileSource::initCheck() const {
     44     return mFile != NULL ? OK : NO_INIT;
     45 }
     46 
     47 ssize_t FileSource::readAt(off_t offset, void *data, size_t size) {
     48     if (mFile == NULL) {
     49         return NO_INIT;
     50     }
     51 
     52     Mutex::Autolock autoLock(mLock);
     53 
     54     if (mLength >= 0) {
     55         if (offset >= mLength) {
     56             return 0;  // read beyond EOF.
     57         }
     58         int64_t numAvailable = mLength - offset;
     59         if ((int64_t)size > numAvailable) {
     60             size = numAvailable;
     61         }
     62     }
     63 
     64     int err = fseeko(mFile, offset + mOffset, SEEK_SET);
     65     if (err < 0) {
     66         LOGE("seek to %lld failed", offset + mOffset);
     67         return UNKNOWN_ERROR;
     68     }
     69 
     70     return fread(data, 1, size, mFile);
     71 }
     72 
     73 status_t FileSource::getSize(off_t *size) {
     74     if (mFile == NULL) {
     75         return NO_INIT;
     76     }
     77 
     78     if (mLength >= 0) {
     79         *size = mLength;
     80 
     81         return OK;
     82     }
     83 
     84     fseek(mFile, 0, SEEK_END);
     85     *size = ftello(mFile);
     86 
     87     return OK;
     88 }
     89 
     90 }  // namespace android
     91