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() {
484f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
494f1732b8068970b368a89271158ca29daf25650eztenghui    if (mStarted) {
504f1732b8068970b368a89271158ca29daf25650eztenghui        mStarted = false;
514f1732b8068970b368a89271158ca29daf25650eztenghui        // If stop() happens immediately after a pushBuffer(), we should
524f1732b8068970b368a89271158ca29daf25650eztenghui        // clean up the mCurrentMediaBuffer
534f1732b8068970b368a89271158ca29daf25650eztenghui        if (mCurrentMediaBuffer != NULL) {
544f1732b8068970b368a89271158ca29daf25650eztenghui            mCurrentMediaBuffer->release();
554f1732b8068970b368a89271158ca29daf25650eztenghui            mCurrentMediaBuffer = NULL;
564f1732b8068970b368a89271158ca29daf25650eztenghui        }
574f1732b8068970b368a89271158ca29daf25650eztenghui        // While read() is still waiting, we should signal it to finish.
584f1732b8068970b368a89271158ca29daf25650eztenghui        mBufferReadCond.signal();
594f1732b8068970b368a89271158ca29daf25650eztenghui    }
604f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
614f1732b8068970b368a89271158ca29daf25650eztenghui}
624f1732b8068970b368a89271158ca29daf25650eztenghui
634f1732b8068970b368a89271158ca29daf25650eztenghuisp<MetaData> MediaAdapter::getFormat() {
644f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
654f1732b8068970b368a89271158ca29daf25650eztenghui    return mOutputFormat;
664f1732b8068970b368a89271158ca29daf25650eztenghui}
674f1732b8068970b368a89271158ca29daf25650eztenghui
684f1732b8068970b368a89271158ca29daf25650eztenghuivoid MediaAdapter::signalBufferReturned(MediaBuffer *buffer) {
694f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
704f1732b8068970b368a89271158ca29daf25650eztenghui    CHECK(buffer != NULL);
714f1732b8068970b368a89271158ca29daf25650eztenghui    buffer->setObserver(0);
724f1732b8068970b368a89271158ca29daf25650eztenghui    buffer->release();
734f1732b8068970b368a89271158ca29daf25650eztenghui    ALOGV("buffer returned %p", buffer);
744f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReturnedCond.signal();
754f1732b8068970b368a89271158ca29daf25650eztenghui}
764f1732b8068970b368a89271158ca29daf25650eztenghui
774f1732b8068970b368a89271158ca29daf25650eztenghuistatus_t MediaAdapter::read(
7884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber            MediaBuffer **buffer, const ReadOptions * /* options */) {
794f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
804f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
814f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("Read before even started!");
824f1732b8068970b368a89271158ca29daf25650eztenghui        return ERROR_END_OF_STREAM;
834f1732b8068970b368a89271158ca29daf25650eztenghui    }
844f1732b8068970b368a89271158ca29daf25650eztenghui
854f1732b8068970b368a89271158ca29daf25650eztenghui    while (mCurrentMediaBuffer == NULL && mStarted) {
864f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("waiting @ read()");
874f1732b8068970b368a89271158ca29daf25650eztenghui        mBufferReadCond.wait(mAdapterLock);
884f1732b8068970b368a89271158ca29daf25650eztenghui    }
894f1732b8068970b368a89271158ca29daf25650eztenghui
904f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
914f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGV("read interrupted after stop");
924f1732b8068970b368a89271158ca29daf25650eztenghui        CHECK(mCurrentMediaBuffer == NULL);
934f1732b8068970b368a89271158ca29daf25650eztenghui        return ERROR_END_OF_STREAM;
944f1732b8068970b368a89271158ca29daf25650eztenghui    }
954f1732b8068970b368a89271158ca29daf25650eztenghui
964f1732b8068970b368a89271158ca29daf25650eztenghui    CHECK(mCurrentMediaBuffer != NULL);
974f1732b8068970b368a89271158ca29daf25650eztenghui
984f1732b8068970b368a89271158ca29daf25650eztenghui    *buffer = mCurrentMediaBuffer;
994f1732b8068970b368a89271158ca29daf25650eztenghui    mCurrentMediaBuffer = NULL;
1004f1732b8068970b368a89271158ca29daf25650eztenghui    (*buffer)->setObserver(this);
1014f1732b8068970b368a89271158ca29daf25650eztenghui
1024f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
1034f1732b8068970b368a89271158ca29daf25650eztenghui}
1044f1732b8068970b368a89271158ca29daf25650eztenghui
1054f1732b8068970b368a89271158ca29daf25650eztenghuistatus_t MediaAdapter::pushBuffer(MediaBuffer *buffer) {
1064f1732b8068970b368a89271158ca29daf25650eztenghui    if (buffer == NULL) {
1074f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGE("pushBuffer get an NULL buffer");
1084f1732b8068970b368a89271158ca29daf25650eztenghui        return -EINVAL;
1094f1732b8068970b368a89271158ca29daf25650eztenghui    }
1104f1732b8068970b368a89271158ca29daf25650eztenghui
1114f1732b8068970b368a89271158ca29daf25650eztenghui    Mutex::Autolock autoLock(mAdapterLock);
1124f1732b8068970b368a89271158ca29daf25650eztenghui    if (!mStarted) {
1134f1732b8068970b368a89271158ca29daf25650eztenghui        ALOGE("pushBuffer called before start");
1144f1732b8068970b368a89271158ca29daf25650eztenghui        return INVALID_OPERATION;
1154f1732b8068970b368a89271158ca29daf25650eztenghui    }
1164f1732b8068970b368a89271158ca29daf25650eztenghui    mCurrentMediaBuffer = buffer;
1174f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReadCond.signal();
1184f1732b8068970b368a89271158ca29daf25650eztenghui
1194f1732b8068970b368a89271158ca29daf25650eztenghui    ALOGV("wait for the buffer returned @ pushBuffer! %p", buffer);
1204f1732b8068970b368a89271158ca29daf25650eztenghui    mBufferReturnedCond.wait(mAdapterLock);
1214f1732b8068970b368a89271158ca29daf25650eztenghui
1224f1732b8068970b368a89271158ca29daf25650eztenghui    return OK;
1234f1732b8068970b368a89271158ca29daf25650eztenghui}
1244f1732b8068970b368a89271158ca29daf25650eztenghui
1254f1732b8068970b368a89271158ca29daf25650eztenghui}  // namespace android
1264f1732b8068970b368a89271158ca29daf25650eztenghui
127