1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "MediaAdapter" 19#include <utils/Log.h> 20 21#include <media/stagefright/foundation/ADebug.h> 22#include <media/stagefright/MediaAdapter.h> 23#include <media/stagefright/MediaBuffer.h> 24 25namespace android { 26 27MediaAdapter::MediaAdapter(const sp<MetaData> &meta) 28 : mCurrentMediaBuffer(NULL), 29 mStarted(false), 30 mOutputFormat(meta) { 31} 32 33MediaAdapter::~MediaAdapter() { 34 Mutex::Autolock autoLock(mAdapterLock); 35 mOutputFormat.clear(); 36 CHECK(mCurrentMediaBuffer == NULL); 37} 38 39status_t MediaAdapter::start(MetaData *params) { 40 Mutex::Autolock autoLock(mAdapterLock); 41 if (!mStarted) { 42 mStarted = true; 43 } 44 return OK; 45} 46 47status_t MediaAdapter::stop() { 48 Mutex::Autolock autoLock(mAdapterLock); 49 if (mStarted) { 50 mStarted = false; 51 // If stop() happens immediately after a pushBuffer(), we should 52 // clean up the mCurrentMediaBuffer 53 if (mCurrentMediaBuffer != NULL) { 54 mCurrentMediaBuffer->release(); 55 mCurrentMediaBuffer = NULL; 56 } 57 // While read() is still waiting, we should signal it to finish. 58 mBufferReadCond.signal(); 59 } 60 return OK; 61} 62 63sp<MetaData> MediaAdapter::getFormat() { 64 Mutex::Autolock autoLock(mAdapterLock); 65 return mOutputFormat; 66} 67 68void MediaAdapter::signalBufferReturned(MediaBuffer *buffer) { 69 Mutex::Autolock autoLock(mAdapterLock); 70 CHECK(buffer != NULL); 71 buffer->setObserver(0); 72 buffer->release(); 73 ALOGV("buffer returned %p", buffer); 74 mBufferReturnedCond.signal(); 75} 76 77status_t MediaAdapter::read( 78 MediaBuffer **buffer, const ReadOptions *options) { 79 Mutex::Autolock autoLock(mAdapterLock); 80 if (!mStarted) { 81 ALOGV("Read before even started!"); 82 return ERROR_END_OF_STREAM; 83 } 84 85 while (mCurrentMediaBuffer == NULL && mStarted) { 86 ALOGV("waiting @ read()"); 87 mBufferReadCond.wait(mAdapterLock); 88 } 89 90 if (!mStarted) { 91 ALOGV("read interrupted after stop"); 92 CHECK(mCurrentMediaBuffer == NULL); 93 return ERROR_END_OF_STREAM; 94 } 95 96 CHECK(mCurrentMediaBuffer != NULL); 97 98 *buffer = mCurrentMediaBuffer; 99 mCurrentMediaBuffer = NULL; 100 (*buffer)->setObserver(this); 101 102 return OK; 103} 104 105status_t MediaAdapter::pushBuffer(MediaBuffer *buffer) { 106 if (buffer == NULL) { 107 ALOGE("pushBuffer get an NULL buffer"); 108 return -EINVAL; 109 } 110 111 Mutex::Autolock autoLock(mAdapterLock); 112 if (!mStarted) { 113 ALOGE("pushBuffer called before start"); 114 return INVALID_OPERATION; 115 } 116 mCurrentMediaBuffer = buffer; 117 mBufferReadCond.signal(); 118 119 ALOGV("wait for the buffer returned @ pushBuffer! %p", buffer); 120 mBufferReturnedCond.wait(mAdapterLock); 121 122 return OK; 123} 124 125} // namespace android 126 127