RepeaterSource.cpp revision e1957358f11031a554c57d4fb46988dd6044acc1
1//#define LOG_NDEBUG 0 2#define LOG_TAG "RepeaterSource" 3#include <utils/Log.h> 4 5#include "RepeaterSource.h" 6 7#include <media/stagefright/foundation/ADebug.h> 8#include <media/stagefright/foundation/ALooper.h> 9#include <media/stagefright/foundation/AMessage.h> 10#include <media/stagefright/MediaBuffer.h> 11#include <media/stagefright/MetaData.h> 12 13namespace android { 14 15RepeaterSource::RepeaterSource(const sp<MediaSource> &source, double rateHz) 16 : mSource(source), 17 mRateHz(rateHz), 18 mBuffer(NULL), 19 mResult(OK), 20 mStartTimeUs(-1ll), 21 mFrameCount(0) { 22} 23 24RepeaterSource::~RepeaterSource() { 25 stop(); 26} 27 28status_t RepeaterSource::start(MetaData *params) { 29 status_t err = mSource->start(params); 30 31 if (err != OK) { 32 return err; 33 } 34 35 mBuffer = NULL; 36 mResult = OK; 37 mStartTimeUs = -1ll; 38 mFrameCount = 0; 39 40 mLooper = new ALooper; 41 mLooper->setName("repeater_looper"); 42 mLooper->start(); 43 44 mReflector = new AHandlerReflector<RepeaterSource>(this); 45 mLooper->registerHandler(mReflector); 46 47 postRead(); 48 49 return OK; 50} 51 52status_t RepeaterSource::stop() { 53 if (mLooper != NULL) { 54 mLooper->stop(); 55 mLooper.clear(); 56 57 mReflector.clear(); 58 } 59 60 return mSource->stop(); 61} 62 63sp<MetaData> RepeaterSource::getFormat() { 64 return mSource->getFormat(); 65} 66 67status_t RepeaterSource::read( 68 MediaBuffer **buffer, const ReadOptions *options) { 69 int64_t seekTimeUs; 70 ReadOptions::SeekMode seekMode; 71 CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode)); 72 73 int64_t bufferTimeUs = -1ll; 74 75 if (mStartTimeUs < 0ll) { 76 Mutex::Autolock autoLock(mLock); 77 while (mBuffer == NULL && mResult == OK) { 78 mCondition.wait(mLock); 79 } 80 81 mStartTimeUs = ALooper::GetNowUs(); 82 bufferTimeUs = mStartTimeUs; 83 } else { 84 bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz; 85 86 int64_t nowUs = ALooper::GetNowUs(); 87 int64_t delayUs = bufferTimeUs - nowUs; 88 89 if (delayUs > 0ll) { 90 usleep(delayUs); 91 } 92 } 93 94 Mutex::Autolock autoLock(mLock); 95 if (mResult != OK) { 96 CHECK(mBuffer == NULL); 97 return mResult; 98 } 99 100 mBuffer->add_ref(); 101 *buffer = mBuffer; 102 (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs); 103 104 ++mFrameCount; 105 106 return OK; 107} 108 109void RepeaterSource::postRead() { 110 (new AMessage(kWhatRead, mReflector->id()))->post(); 111} 112 113void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) { 114 switch (msg->what()) { 115 case kWhatRead: 116 { 117 MediaBuffer *buffer; 118 status_t err = mSource->read(&buffer); 119 120 Mutex::Autolock autoLock(mLock); 121 if (mBuffer != NULL) { 122 mBuffer->release(); 123 mBuffer = NULL; 124 } 125 mBuffer = buffer; 126 mResult = err; 127 128 mCondition.broadcast(); 129 130 if (err == OK) { 131 postRead(); 132 } 133 break; 134 } 135 136 default: 137 TRESPASS(); 138 } 139} 140 141} // namespace android 142