diff options
Diffstat (limited to 'media/libstagefright/httplive/LiveDataSource.cpp')
-rw-r--r-- | media/libstagefright/httplive/LiveDataSource.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/media/libstagefright/httplive/LiveDataSource.cpp b/media/libstagefright/httplive/LiveDataSource.cpp new file mode 100644 index 0000000..25e2902 --- /dev/null +++ b/media/libstagefright/httplive/LiveDataSource.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "LiveDataSource" +#include <utils/Log.h> + +#include "LiveDataSource.h" + +#include <media/stagefright/foundation/ABuffer.h> +#include <media/stagefright/foundation/ADebug.h> + +#define SAVE_BACKUP 0 + +namespace android { + +LiveDataSource::LiveDataSource() + : mOffset(0), + mFinalResult(OK), + mBackupFile(NULL) { +#if SAVE_BACKUP + mBackupFile = fopen("/data/misc/backup.ts", "wb"); + CHECK(mBackupFile != NULL); +#endif +} + +LiveDataSource::~LiveDataSource() { + if (mBackupFile != NULL) { + fclose(mBackupFile); + mBackupFile = NULL; + } +} + +status_t LiveDataSource::initCheck() const { + return OK; +} + +size_t LiveDataSource::countQueuedBuffers() { + Mutex::Autolock autoLock(mLock); + + return mBufferQueue.size(); +} + +ssize_t LiveDataSource::readAt(off64_t offset, void *data, size_t size) { + Mutex::Autolock autoLock(mLock); + + if (offset != mOffset) { + LOGE("Attempt at reading non-sequentially from LiveDataSource."); + return -EPIPE; + } + + size_t sizeDone = 0; + + while (sizeDone < size) { + while (mBufferQueue.empty() && mFinalResult == OK) { + mCondition.wait(mLock); + } + + if (mBufferQueue.empty()) { + if (sizeDone > 0) { + mOffset += sizeDone; + return sizeDone; + } + + return mFinalResult; + } + + sp<ABuffer> buffer = *mBufferQueue.begin(); + + size_t copy = size - sizeDone; + + if (copy > buffer->size()) { + copy = buffer->size(); + } + + memcpy((uint8_t *)data + sizeDone, buffer->data(), copy); + + sizeDone += copy; + + buffer->setRange(buffer->offset() + copy, buffer->size() - copy); + + if (buffer->size() == 0) { + mBufferQueue.erase(mBufferQueue.begin()); + } + } + + mOffset += sizeDone; + + return sizeDone; +} + +void LiveDataSource::queueBuffer(const sp<ABuffer> &buffer) { + Mutex::Autolock autoLock(mLock); + + if (mFinalResult != OK) { + return; + } + +#if SAVE_BACKUP + if (mBackupFile != NULL) { + CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mBackupFile), + buffer->size()); + } +#endif + + mBufferQueue.push_back(buffer); + mCondition.broadcast(); +} + +void LiveDataSource::queueEOS(status_t finalResult) { + CHECK_NE(finalResult, (status_t)OK); + + Mutex::Autolock autoLock(mLock); + + mFinalResult = finalResult; + mCondition.broadcast(); +} + +void LiveDataSource::reset() { + Mutex::Autolock autoLock(mLock); + + // XXX FIXME: If we've done a partial read and waiting for more buffers, + // we'll mix old and new data... + + mFinalResult = OK; + mBufferQueue.clear(); +} + +} // namespace android |