diff options
author | ztenghui <ztenghui@google.com> | 2013-02-04 15:59:38 -0800 |
---|---|---|
committer | ztenghui <ztenghui@google.com> | 2013-02-12 11:10:12 -0800 |
commit | 4f1732b8068970b368a89271158ca29daf25650e (patch) | |
tree | 0444520a23aa61553f9cf8bb67ee0f8127096b6a /media/libstagefright/MediaAdapter.cpp | |
parent | 272ab546940054ad7991bef4b3a36f15175721cd (diff) | |
download | frameworks_av-4f1732b8068970b368a89271158ca29daf25650e.zip frameworks_av-4f1732b8068970b368a89271158ca29daf25650e.tar.gz frameworks_av-4f1732b8068970b368a89271158ca29daf25650e.tar.bz2 |
Add the native MediaMuxer support.
MediaAdapter: a helper class to convert the push model to pull model.
MediaMuxer: the real muxer.
bug:7991013
Change-Id: If3b79551bc6332bc81f5c2740885e579a5c4abf9
Diffstat (limited to 'media/libstagefright/MediaAdapter.cpp')
-rw-r--r-- | media/libstagefright/MediaAdapter.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/media/libstagefright/MediaAdapter.cpp b/media/libstagefright/MediaAdapter.cpp new file mode 100644 index 0000000..2484212 --- /dev/null +++ b/media/libstagefright/MediaAdapter.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "MediaAdapter" +#include <utils/Log.h> + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/MediaAdapter.h> +#include <media/stagefright/MediaBuffer.h> + +namespace android { + +MediaAdapter::MediaAdapter(const sp<MetaData> &meta) + : mCurrentMediaBuffer(NULL), + mStarted(false), + mOutputFormat(meta) { +} + +MediaAdapter::~MediaAdapter() { + Mutex::Autolock autoLock(mAdapterLock); + mOutputFormat.clear(); + CHECK(mCurrentMediaBuffer == NULL); +} + +status_t MediaAdapter::start(MetaData *params) { + Mutex::Autolock autoLock(mAdapterLock); + if (!mStarted) { + mStarted = true; + } + return OK; +} + +status_t MediaAdapter::stop() { + Mutex::Autolock autoLock(mAdapterLock); + if (mStarted) { + mStarted = false; + // If stop() happens immediately after a pushBuffer(), we should + // clean up the mCurrentMediaBuffer + if (mCurrentMediaBuffer != NULL) { + mCurrentMediaBuffer->release(); + mCurrentMediaBuffer = NULL; + } + // While read() is still waiting, we should signal it to finish. + mBufferReadCond.signal(); + } + return OK; +} + +sp<MetaData> MediaAdapter::getFormat() { + Mutex::Autolock autoLock(mAdapterLock); + return mOutputFormat; +} + +void MediaAdapter::signalBufferReturned(MediaBuffer *buffer) { + Mutex::Autolock autoLock(mAdapterLock); + CHECK(buffer != NULL); + buffer->setObserver(0); + buffer->release(); + ALOGV("buffer returned %p", buffer); + mBufferReturnedCond.signal(); +} + +status_t MediaAdapter::read( + MediaBuffer **buffer, const ReadOptions *options) { + Mutex::Autolock autoLock(mAdapterLock); + if (!mStarted) { + ALOGV("Read before even started!"); + return ERROR_END_OF_STREAM; + } + + while (mCurrentMediaBuffer == NULL && mStarted) { + ALOGV("waiting @ read()"); + mBufferReadCond.wait(mAdapterLock); + } + + if (!mStarted) { + ALOGV("read interrupted after stop"); + CHECK(mCurrentMediaBuffer == NULL); + return ERROR_END_OF_STREAM; + } + + CHECK(mCurrentMediaBuffer != NULL); + + *buffer = mCurrentMediaBuffer; + mCurrentMediaBuffer = NULL; + (*buffer)->setObserver(this); + + return OK; +} + +status_t MediaAdapter::pushBuffer(MediaBuffer *buffer) { + if (buffer == NULL) { + ALOGE("pushBuffer get an NULL buffer"); + return -EINVAL; + } + + Mutex::Autolock autoLock(mAdapterLock); + if (!mStarted) { + ALOGE("pushBuffer called before start"); + return INVALID_OPERATION; + } + mCurrentMediaBuffer = buffer; + mBufferReadCond.signal(); + + ALOGV("wait for the buffer returned @ pushBuffer! %p", buffer); + mBufferReturnedCond.wait(mAdapterLock); + + return OK; +} + +} // namespace android + |