14f1732b8068970b368a89271158ca29daf25650eztenghui/*
24f1732b8068970b368a89271158ca29daf25650eztenghui * Copyright (C) 2013 The Android Open Source Project
34f1732b8068970b368a89271158ca29daf25650eztenghui *
44f1732b8068970b368a89271158ca29daf25650eztenghui * Licensed under the Apache License, Version 2.0 (the "License");
54f1732b8068970b368a89271158ca29daf25650eztenghui * you may not use this file except in compliance with the License.
64f1732b8068970b368a89271158ca29daf25650eztenghui * You may obtain a copy of the License at
74f1732b8068970b368a89271158ca29daf25650eztenghui *
84f1732b8068970b368a89271158ca29daf25650eztenghui *      http://www.apache.org/licenses/LICENSE-2.0
94f1732b8068970b368a89271158ca29daf25650eztenghui *
104f1732b8068970b368a89271158ca29daf25650eztenghui * Unless required by applicable law or agreed to in writing, software
114f1732b8068970b368a89271158ca29daf25650eztenghui * distributed under the License is distributed on an "AS IS" BASIS,
124f1732b8068970b368a89271158ca29daf25650eztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f1732b8068970b368a89271158ca29daf25650eztenghui * See the License for the specific language governing permissions and
144f1732b8068970b368a89271158ca29daf25650eztenghui * limitations under the License.
154f1732b8068970b368a89271158ca29daf25650eztenghui */
164f1732b8068970b368a89271158ca29daf25650eztenghui
174f1732b8068970b368a89271158ca29daf25650eztenghui//#define LOG_NDEBUG 0
184f1732b8068970b368a89271158ca29daf25650eztenghui#define LOG_TAG "MediaAdapter"
194f1732b8068970b368a89271158ca29daf25650eztenghui#include <utils/Log.h>
204f1732b8068970b368a89271158ca29daf25650eztenghui
214f1732b8068970b368a89271158ca29daf25650eztenghui#include <media/stagefright/foundation/ADebug.h>
224f1732b8068970b368a89271158ca29daf25650eztenghui#include <media/stagefright/MediaAdapter.h>
234f1732b8068970b368a89271158ca29daf25650eztenghui#include <media/stagefright/MediaBuffer.h>
244f1732b8068970b368a89271158ca29daf25650eztenghui
254f1732b8068970b368a89271158ca29daf25650eztenghuinamespace android {
264f1732b8068970b368a89271158ca29daf25650eztenghui
274f1732b8068970b368a89271158ca29daf25650eztenghuiMediaAdapter::MediaAdapter(const sp<MetaData> &meta)
284f1732b8068970b368a89271158ca29daf25650eztenghui    : mCurrentMediaBuffer(NULL),
294f1732b8068970b368a89271158ca29daf25650eztenghui      mStarted(false),
304f1732b8068970b368a89271158ca29daf25650eztenghui      mOutputFormat(meta) {
314f1732b8068970b368a89271158ca29daf25650eztenghui}
324f1732b8068970b368a89271158ca29daf25650eztenghui
334f1732b8068970b368a89271158ca29daf25650eztenghuiMediaAdapter::~MediaAdapter() {
344f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
354f1732b8068970b368a89271158ca29daf25650eztenghui    mOutputFormat.clear();
364f1732b8068970b368a89271158ca29daf25650eztenghui    CHECK(mCurrentMediaBuffer == NULL);
374f1732b8068970b368a89271158ca29daf25650eztenghui}
384f1732b8068970b368a89271158ca29daf25650eztenghui
3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaAdapter::start(MetaData * /* params */) {
404f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
414f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
424f1732b8068970b368a89271158ca29daf25650eztenghui        mStarted = true;
434f1732b8068970b368a89271158ca29daf25650eztenghui    }
444f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
454f1732b8068970b368a89271158ca29daf25650eztenghui}
464f1732b8068970b368a89271158ca29daf25650eztenghui
474f1732b8068970b368a89271158ca29daf25650eztenghuistatus_t MediaAdapter::stop() {
482531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang    MediaBuffer *currentBuffer = NULL;
492531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang    {
502531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang        Mutex::Autolock autoLock(mAdapterLock);
512531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang        if (mStarted) {
522531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            mStarted = false;
532531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            // If stop() happens immediately after a pushBuffer(), we should
542531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            // clean up the mCurrentMediaBuffer. But need to release without
552531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            // the lock as signalBufferReturned() will acquire the lock.
562531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            currentBuffer = mCurrentMediaBuffer;
574f1732b8068970b368a89271158ca29daf25650eztenghui            mCurrentMediaBuffer = NULL;
582531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang
592531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            // While read() is still waiting, we should signal it to finish.
602531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang            mBufferReadCond.signal();
614f1732b8068970b368a89271158ca29daf25650eztenghui        }
622531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang    }
632531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang    if (currentBuffer != NULL) {
642531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang        currentBuffer->release();
652531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang        currentBuffer = NULL;
664f1732b8068970b368a89271158ca29daf25650eztenghui    }
674f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
684f1732b8068970b368a89271158ca29daf25650eztenghui}
694f1732b8068970b368a89271158ca29daf25650eztenghui
704f1732b8068970b368a89271158ca29daf25650eztenghuisp<MetaData> MediaAdapter::getFormat() {
714f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
724f1732b8068970b368a89271158ca29daf25650eztenghui    return mOutputFormat;
734f1732b8068970b368a89271158ca29daf25650eztenghui}
744f1732b8068970b368a89271158ca29daf25650eztenghui
751889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kangvoid MediaAdapter::signalBufferReturned(MediaBufferBase *buffer) {
764f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
774f1732b8068970b368a89271158ca29daf25650eztenghui    CHECK(buffer != NULL);
784f1732b8068970b368a89271158ca29daf25650eztenghui    buffer->setObserver(0);
794f1732b8068970b368a89271158ca29daf25650eztenghui    buffer->release();
804f1732b8068970b368a89271158ca29daf25650eztenghui    ALOGV("buffer returned %p", buffer);
814f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReturnedCond.signal();
824f1732b8068970b368a89271158ca29daf25650eztenghui}
834f1732b8068970b368a89271158ca29daf25650eztenghui
844f1732b8068970b368a89271158ca29daf25650eztenghuistatus_t MediaAdapter::read(
851889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang            MediaBufferBase **buffer, const ReadOptions * /* options */) {
864f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
874f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
884f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("Read before even started!");
894f1732b8068970b368a89271158ca29daf25650eztenghui        return ERROR_END_OF_STREAM;
904f1732b8068970b368a89271158ca29daf25650eztenghui    }
914f1732b8068970b368a89271158ca29daf25650eztenghui
924f1732b8068970b368a89271158ca29daf25650eztenghui    while (mCurrentMediaBuffer == NULL && mStarted) {
934f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("waiting @ read()");
944f1732b8068970b368a89271158ca29daf25650eztenghui        mBufferReadCond.wait(mAdapterLock);
954f1732b8068970b368a89271158ca29daf25650eztenghui    }
964f1732b8068970b368a89271158ca29daf25650eztenghui
974f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
984f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("read interrupted after stop");
994f1732b8068970b368a89271158ca29daf25650eztenghui        CHECK(mCurrentMediaBuffer == NULL);
1004f1732b8068970b368a89271158ca29daf25650eztenghui        return ERROR_END_OF_STREAM;
1014f1732b8068970b368a89271158ca29daf25650eztenghui    }
1024f1732b8068970b368a89271158ca29daf25650eztenghui
1034f1732b8068970b368a89271158ca29daf25650eztenghui    CHECK(mCurrentMediaBuffer != NULL);
1044f1732b8068970b368a89271158ca29daf25650eztenghui
1054f1732b8068970b368a89271158ca29daf25650eztenghui    *buffer = mCurrentMediaBuffer;
1064f1732b8068970b368a89271158ca29daf25650eztenghui    mCurrentMediaBuffer = NULL;
1074f1732b8068970b368a89271158ca29daf25650eztenghui
1084f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
1094f1732b8068970b368a89271158ca29daf25650eztenghui}
1104f1732b8068970b368a89271158ca29daf25650eztenghui
1114f1732b8068970b368a89271158ca29daf25650eztenghuistatus_t MediaAdapter::pushBuffer(MediaBuffer *buffer) {
1124f1732b8068970b368a89271158ca29daf25650eztenghui    if (buffer == NULL) {
1134f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGE("pushBuffer get an NULL buffer");
1144f1732b8068970b368a89271158ca29daf25650eztenghui        return -EINVAL;
1154f1732b8068970b368a89271158ca29daf25650eztenghui    }
1164f1732b8068970b368a89271158ca29daf25650eztenghui
1174f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
1184f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
1194f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGE("pushBuffer called before start");
1204f1732b8068970b368a89271158ca29daf25650eztenghui        return INVALID_OPERATION;
1214f1732b8068970b368a89271158ca29daf25650eztenghui    }
1224f1732b8068970b368a89271158ca29daf25650eztenghui    mCurrentMediaBuffer = buffer;
1232531d69cb24ec43cca4070088cfbc75e2e09ab11Chong Zhang    mCurrentMediaBuffer->setObserver(this);
1244f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReadCond.signal();
1254f1732b8068970b368a89271158ca29daf25650eztenghui
1264f1732b8068970b368a89271158ca29daf25650eztenghui    ALOGV("wait for the buffer returned @ pushBuffer! %p", buffer);
1274f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReturnedCond.wait(mAdapterLock);
1284f1732b8068970b368a89271158ca29daf25650eztenghui
1294f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
1304f1732b8068970b368a89271158ca29daf25650eztenghui}
1314f1732b8068970b368a89271158ca29daf25650eztenghui
1324f1732b8068970b368a89271158ca29daf25650eztenghui}  // namespace android
1334f1732b8068970b368a89271158ca29daf25650eztenghui
134