1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0 2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "RepeaterSource" 3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h> 4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "RepeaterSource.h" 6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ALooper.h> 9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaBuffer.h> 11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h> 12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberRepeaterSource::RepeaterSource(const sp<MediaSource> &source, double rateHz) 1677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber : mStarted(false), 1777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mSource(source), 18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRateHz(rateHz), 19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mBuffer(NULL), 20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mResult(OK), 214a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mLastBufferUpdateUs(-1ll), 22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStartTimeUs(-1ll), 23d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFrameCount(0) { 24d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberRepeaterSource::~RepeaterSource() { 2777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber CHECK(!mStarted); 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::start(MetaData *params) { 3177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber CHECK(!mStarted); 3277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mSource->start(params); 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mBuffer = NULL; 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mResult = OK; 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStartTimeUs = -1ll; 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFrameCount = 0; 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLooper = new ALooper; 45e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mLooper->setName("repeater_looper"); 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLooper->start(); 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mReflector = new AHandlerReflector<RepeaterSource>(this); 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLooper->registerHandler(mReflector); 50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber postRead(); 52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mStarted = true; 5477245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 58d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::stop() { 5977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber CHECK(mStarted); 6077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 6196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("stopping"); 6296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mLooper != NULL) { 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLooper->stop(); 65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLooper.clear(); 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mReflector.clear(); 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 7096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mBuffer != NULL) { 7196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("releasing mbuf %p", mBuffer); 7296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mBuffer->release(); 7396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mBuffer = NULL; 7496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 7596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber status_t err = mSource->stop(); 7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("stopped"); 7996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 8077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mStarted = false; 8177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 8296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber return err; 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<MetaData> RepeaterSource::getFormat() { 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mSource->getFormat(); 87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::read( 90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber MediaBuffer **buffer, const ReadOptions *options) { 91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t seekTimeUs; 92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ReadOptions::SeekMode seekMode; 93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode)); 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber for (;;) { 964a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber int64_t bufferTimeUs = -1ll; 97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 984a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mStartTimeUs < 0ll) { 994a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber Mutex::Autolock autoLock(mLock); 1004a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber while ((mLastBufferUpdateUs < 0ll || mBuffer == NULL) 1014a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber && mResult == OK) { 1024a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mCondition.wait(mLock); 1034a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1054a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber ALOGV("now resuming."); 1064a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mStartTimeUs = ALooper::GetNowUs(); 1074a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber bufferTimeUs = mStartTimeUs; 1084a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } else { 1094a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz; 110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1114a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 1124a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber int64_t delayUs = bufferTimeUs - nowUs; 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1144a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (delayUs > 0ll) { 1154a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber usleep(delayUs); 1164a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1194a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber bool stale = false; 120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1214a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber { 1224a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber Mutex::Autolock autoLock(mLock); 1234a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mResult != OK) { 1244a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber CHECK(mBuffer == NULL); 1254a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber return mResult; 1264a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1284a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 1294a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (nowUs - mLastBufferUpdateUs > 1000000ll) { 1304a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mLastBufferUpdateUs = -1ll; 1314a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber stale = true; 1324a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } else { 1334a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mBuffer->add_ref(); 1344a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber *buffer = mBuffer; 1354a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs); 1364a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber ++mFrameCount; 1374a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 1384a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 1394a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 1404a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (!stale) { 1414a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber break; 1424a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 1434a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 1444a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mStartTimeUs = -1ll; 1454a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mFrameCount = 0; 1464a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber ALOGV("now dormant"); 1474a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid RepeaterSource::postRead() { 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (new AMessage(kWhatRead, mReflector->id()))->post(); 154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid RepeaterSource::onMessageReceived(const sp<AMessage> &msg) { 157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRead: 159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber MediaBuffer *buffer; 161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mSource->read(&buffer); 162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 16396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("read mbuf %p", buffer); 16496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Mutex::Autolock autoLock(mLock); 166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mBuffer != NULL) { 167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mBuffer->release(); 168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mBuffer = NULL; 169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mBuffer = buffer; 171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mResult = err; 1724a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mLastBufferUpdateUs = ALooper::GetNowUs(); 173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCondition.broadcast(); 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err == OK) { 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber postRead(); 178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid RepeaterSource::wakeUp() { 1884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber ALOGV("wakeUp"); 1894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber Mutex::Autolock autoLock(mLock); 1904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mLastBufferUpdateUs < 0ll && mBuffer != NULL) { 1914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mLastBufferUpdateUs = ALooper::GetNowUs(); 1924a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mCondition.broadcast(); 1934a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 1944a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber} 1954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 197