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