RepeaterSource.cpp revision 96fc6cc65ca93009a759a3a874b82a35771b9714
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)
16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mSource(source),
17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRateHz(rateHz),
18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mBuffer(NULL),
19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mResult(OK),
20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mStartTimeUs(-1ll),
21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mFrameCount(0) {
22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
23d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
24d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberRepeaterSource::~RepeaterSource() {
25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    stop();
26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::start(MetaData *params) {
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mSource->start(params);
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mBuffer = NULL;
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mResult = OK;
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mStartTimeUs = -1ll;
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mFrameCount = 0;
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLooper = new ALooper;
41e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    mLooper->setName("repeater_looper");
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLooper->start();
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mReflector = new AHandlerReflector<RepeaterSource>(this);
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLooper->registerHandler(mReflector);
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    postRead();
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::stop() {
5396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("stopping");
5496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mLooper != NULL) {
56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLooper->stop();
57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLooper.clear();
58d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
59d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mReflector.clear();
60d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
61d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    if (mBuffer != NULL) {
6396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mBuffer);
6496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mBuffer->release();
6596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mBuffer = NULL;
6696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    }
6796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
6896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    status_t err = mSource->stop();
6996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
7096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("stopped");
7196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
7296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    return err;
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<MetaData> RepeaterSource::getFormat() {
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mSource->getFormat();
77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
78d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
79d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t RepeaterSource::read(
80d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int64_t seekTimeUs;
82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ReadOptions::SeekMode seekMode;
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode));
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int64_t bufferTimeUs = -1ll;
86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mStartTimeUs < 0ll) {
88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        Mutex::Autolock autoLock(mLock);
89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        while (mBuffer == NULL && mResult == OK) {
90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mCondition.wait(mLock);
91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mStartTimeUs = ALooper::GetNowUs();
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferTimeUs = mStartTimeUs;
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t delayUs = bufferTimeUs - nowUs;
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (delayUs > 0ll) {
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            usleep(delayUs);
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    Mutex::Autolock autoLock(mLock);
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mResult != OK) {
108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK(mBuffer == NULL);
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return mResult;
110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mBuffer->add_ref();
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    *buffer = mBuffer;
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ++mFrameCount;
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid RepeaterSource::postRead() {
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatRead, mReflector->id()))->post();
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatRead:
128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaBuffer *buffer;
130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = mSource->read(&buffer);
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
13296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGV("read mbuf %p", buffer);
13396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            Mutex::Autolock autoLock(mLock);
135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (mBuffer != NULL) {
136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mBuffer->release();
137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mBuffer = NULL;
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mBuffer = buffer;
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mResult = err;
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mCondition.broadcast();
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err == OK) {
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                postRead();
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
156