summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/httplive/LiveDataSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/httplive/LiveDataSource.cpp')
-rw-r--r--media/libstagefright/httplive/LiveDataSource.cpp142
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