RepeaterSource.cpp revision e1957358f11031a554c57d4fb46988dd6044acc1
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "RepeaterSource"
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "RepeaterSource.h"
68451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
78451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include <media/stagefright/foundation/ADebug.h>
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/stagefright/foundation/ALooper.h>
98451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include <media/stagefright/foundation/AMessage.h>
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/stagefright/MediaBuffer.h>
118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include <media/stagefright/MetaData.h>
128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesnamespace android {
148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRepeaterSource::RepeaterSource(const sp<MediaSource> &source, double rateHz)
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mSource(source),
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mRateHz(rateHz),
18f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn      mBuffer(NULL),
19f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn      mResult(OK),
20f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn      mStartTimeUs(-1ll),
21f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn      mFrameCount(0) {
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRepeaterSource::~RepeaterSource() {
25ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    stop();
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t RepeaterSource::start(MetaData *params) {
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = mSource->start(params);
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != OK) {
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    mBuffer = NULL;
36f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    mResult = OK;
370c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    mStartTimeUs = -1ll;
380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    mFrameCount = 0;
395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    mLooper = new ALooper;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLooper->setName("repeater_looper");
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLooper->start();
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mReflector = new AHandlerReflector<RepeaterSource>(this);
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLooper->registerHandler(mReflector);
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    postRead();
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return OK;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t RepeaterSource::stop() {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mLooper != NULL) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLooper->stop();
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLooper.clear();
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReflector.clear();
583d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed    }
59c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio
60c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio    return mSource->stop();
613d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed}
623d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<MetaData> RepeaterSource::getFormat() {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mSource->getFormat();
650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt}
660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltstatus_t RepeaterSource::read(
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MediaBuffer **buffer, const ReadOptions *options) {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int64_t seekTimeUs;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ReadOptions::SeekMode seekMode;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode));
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int64_t bufferTimeUs = -1ll;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
753d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed    if (mStartTimeUs < 0ll) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock autoLock(mLock);
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mBuffer == NULL && mResult == OK) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCondition.wait(mLock);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStartTimeUs = ALooper::GetNowUs();
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bufferTimeUs = mStartTimeUs;
838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    } else {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
863d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed        int64_t nowUs = ALooper::GetNowUs();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int64_t delayUs = bufferTimeUs - nowUs;
888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (delayUs > 0ll) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            usleep(delayUs);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex::Autolock autoLock(mLock);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mResult != OK) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CHECK(mBuffer == NULL);
978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        return mResult;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mBuffer->add_ref();
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *buffer = mBuffer;
1028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);
103f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
104f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    ++mFrameCount;
105f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
106f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    return OK;
107f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn}
108f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
109f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornvoid RepeaterSource::postRead() {
110f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    (new AMessage(kWhatRead, mReflector->id()))->post();
111f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn}
112f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
113f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornvoid RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
114f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    switch (msg->what()) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case kWhatRead:
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MediaBuffer *buffer;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status_t err = mSource->read(&buffer);
1198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Mutex::Autolock autoLock(mLock);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mBuffer != NULL) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBuffer->release();
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBuffer = NULL;
1248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBuffer = buffer;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResult = err;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCondition.broadcast();
1298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err == OK) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                postRead();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TRESPASS();
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes}
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}  // namespace android
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project