Loading libvideoeditor/vss/stagefrightshells/src/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ MediaBufferPuller.cpp \ VideoEditorVideoDecoder.cpp \ VideoEditorAudioDecoder.cpp \ VideoEditorMp3Reader.cpp \ Loading libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.cpp 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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 "MediaBufferPuller" #include <utils/Log.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include "MediaBufferPuller.h" namespace android { MediaBufferPuller::MediaBufferPuller(const sp<MediaSource>& source) : mSource(source), mAskToStart(false), mAskToStop(false), mAcquireStopped(false), mReleaseStopped(false), mSourceError(OK) { androidCreateThread(acquireThreadStart, this); androidCreateThread(releaseThreadStart, this); } MediaBufferPuller::~MediaBufferPuller() { stop(); } bool MediaBufferPuller::hasMediaSourceReturnedError() const { Mutex::Autolock autolock(mLock); return ((mSourceError != OK) ? true : false); } void MediaBufferPuller::start() { Mutex::Autolock autolock(mLock); mAskToStart = true; mAcquireCond.signal(); mReleaseCond.signal(); } void MediaBufferPuller::stop() { Mutex::Autolock autolock(mLock); mAskToStop = true; mAcquireCond.signal(); mReleaseCond.signal(); while (!mAcquireStopped || !mReleaseStopped) { mUserCond.wait(mLock); } // Release remaining buffers for (size_t i = 0; i < mBuffers.size(); i++) { mBuffers.itemAt(i)->release(); } for (size_t i = 0; i < mReleaseBuffers.size(); i++) { mReleaseBuffers.itemAt(i)->release(); } mBuffers.clear(); mReleaseBuffers.clear(); } MediaBuffer* MediaBufferPuller::getBufferNonBlocking() { Mutex::Autolock autolock(mLock); if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } MediaBuffer* MediaBufferPuller::getBufferBlocking() { Mutex::Autolock autolock(mLock); while (mBuffers.empty() && !mAcquireStopped) { mUserCond.wait(mLock); } if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } void MediaBufferPuller::putBuffer(MediaBuffer* buffer) { Mutex::Autolock autolock(mLock); mReleaseBuffers.push(buffer); mReleaseCond.signal(); } int MediaBufferPuller::acquireThreadStart(void* arg) { MediaBufferPuller* self = (MediaBufferPuller*)arg; self->acquireThreadFunc(); return 0; } int MediaBufferPuller::releaseThreadStart(void* arg) { MediaBufferPuller* self = (MediaBufferPuller*)arg; self->releaseThreadFunc(); return 0; } void MediaBufferPuller::acquireThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mAcquireCond.wait(mLock); } // Loop until we are asked to stop, or there is nothing more to read while (!mAskToStop) { MediaBuffer* pBuffer; mLock.unlock(); status_t result = mSource->read(&pBuffer, NULL); mLock.lock(); mSourceError = result; if (result != OK) { break; } mBuffers.push(pBuffer); mUserCond.signal(); } mAcquireStopped = true; mUserCond.signal(); mLock.unlock(); } void MediaBufferPuller::releaseThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mReleaseCond.wait(mLock); } // Loop until we are asked to stop while (1) { if (mReleaseBuffers.empty()) { if (mAskToStop) { break; } else { mReleaseCond.wait(mLock); continue; } } MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0); mReleaseBuffers.removeAt(0); mLock.unlock(); pBuffer->release(); mLock.lock(); } mReleaseStopped = true; mUserCond.signal(); mLock.unlock(); } }; // namespace android libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.h 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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. */ #ifndef _MEDIA_BUFFER_PULLER_H #define _MEDIA_BUFFER_PULLER_H #include <utils/threads.h> #include <utils/Vector.h> namespace android { struct MediaSource; struct MediaBuffer; /* * An object of this class can pull a list of media buffers * from a MediaSource repeatedly. The user can then get the * buffers from that list. */ struct MediaBufferPuller { public: MediaBufferPuller(const sp<MediaSource>& source); ~MediaBufferPuller(); // Start to build up the list of the buffers. void start(); // Release the list of the available buffers, and stop // pulling buffers from the MediaSource. void stop(); // Get a buffer from the list. If there is no buffer available // at the time this method is called, NULL is returned. MediaBuffer* getBufferBlocking(); // Get a buffer from the list. If there is no buffer available // at the time this method is called, it blocks waiting for // a buffer to become available or until stop() is called. MediaBuffer* getBufferNonBlocking(); // Add a buffer to the end of the list available media buffers void putBuffer(MediaBuffer* buffer); // Check whether the source returned an error or not. bool hasMediaSourceReturnedError() const; private: static int acquireThreadStart(void* arg); void acquireThreadFunc(); static int releaseThreadStart(void* arg); void releaseThreadFunc(); sp<MediaSource> mSource; Vector<MediaBuffer*> mBuffers; Vector<MediaBuffer*> mReleaseBuffers; mutable Mutex mLock; Condition mUserCond; // for the user of this class Condition mAcquireCond; // for the acquire thread Condition mReleaseCond; // for the release thread bool mAskToStart; // Asks the threads to start bool mAskToStop; // Asks the threads to stop bool mAcquireStopped; // The acquire thread has stopped bool mReleaseStopped; // The release thread has stopped status_t mSourceError; // Error returned by MediaSource read // Don't call me! MediaBufferPuller(const MediaBufferPuller&); MediaBufferPuller& operator=(const MediaBufferPuller&); }; } // namespace android #endif // _MEDIA_BUFFER_PULLER_H libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp +4 −190 Original line number Diff line number Diff line Loading @@ -29,8 +29,10 @@ #include "M4SYS_AccessUnit.h" #include "VideoEditorVideoEncoder.h" #include "VideoEditorUtils.h" #include "MediaBufferPuller.h" #include <I420ColorConverter.h> #include <unistd.h> #include "utils/Log.h" #include "utils/Vector.h" #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -248,194 +250,6 @@ int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() { Mutex::Autolock autolock(mLock); return mNbBuffer; } /******************** * PULLER * ********************/ // Pulls media buffers from a MediaSource repeatedly. // The user can then get the buffers from that list. class VideoEditorVideoEncoderPuller { public: VideoEditorVideoEncoderPuller(sp<MediaSource> source); ~VideoEditorVideoEncoderPuller(); void start(); void stop(); MediaBuffer* getBufferBlocking(); MediaBuffer* getBufferNonBlocking(); void putBuffer(MediaBuffer* buffer); bool hasMediaSourceReturnedError(); private: static int acquireThreadStart(void* arg); void acquireThreadFunc(); static int releaseThreadStart(void* arg); void releaseThreadFunc(); sp<MediaSource> mSource; Vector<MediaBuffer*> mBuffers; Vector<MediaBuffer*> mReleaseBuffers; Mutex mLock; Condition mUserCond; // for the user of this class Condition mAcquireCond; // for the acquire thread Condition mReleaseCond; // for the release thread bool mAskToStart; // Asks the threads to start bool mAskToStop; // Asks the threads to stop bool mAcquireStopped; // The acquire thread has stopped bool mReleaseStopped; // The release thread has stopped status_t mSourceError; // Error returned by MediaSource read }; VideoEditorVideoEncoderPuller::VideoEditorVideoEncoderPuller( sp<MediaSource> source) { mSource = source; mAskToStart = false; mAskToStop = false; mAcquireStopped = false; mReleaseStopped = false; mSourceError = OK; androidCreateThread(acquireThreadStart, this); androidCreateThread(releaseThreadStart, this); } VideoEditorVideoEncoderPuller::~VideoEditorVideoEncoderPuller() { stop(); } bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() { Mutex::Autolock autolock(mLock); return ((mSourceError != OK) ? true : false); } void VideoEditorVideoEncoderPuller::start() { Mutex::Autolock autolock(mLock); mAskToStart = true; mAcquireCond.signal(); mReleaseCond.signal(); } void VideoEditorVideoEncoderPuller::stop() { Mutex::Autolock autolock(mLock); mAskToStop = true; mAcquireCond.signal(); mReleaseCond.signal(); while (!mAcquireStopped || !mReleaseStopped) { mUserCond.wait(mLock); } // Release remaining buffers for (size_t i = 0; i < mBuffers.size(); i++) { mBuffers.itemAt(i)->release(); } for (size_t i = 0; i < mReleaseBuffers.size(); i++) { mReleaseBuffers.itemAt(i)->release(); } mBuffers.clear(); mReleaseBuffers.clear(); } MediaBuffer* VideoEditorVideoEncoderPuller::getBufferNonBlocking() { Mutex::Autolock autolock(mLock); if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } MediaBuffer* VideoEditorVideoEncoderPuller::getBufferBlocking() { Mutex::Autolock autolock(mLock); while (mBuffers.empty() && !mAcquireStopped) { mUserCond.wait(mLock); } if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } void VideoEditorVideoEncoderPuller::putBuffer(MediaBuffer* buffer) { Mutex::Autolock autolock(mLock); mReleaseBuffers.push(buffer); mReleaseCond.signal(); } int VideoEditorVideoEncoderPuller::acquireThreadStart(void* arg) { VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg; self->acquireThreadFunc(); return 0; } int VideoEditorVideoEncoderPuller::releaseThreadStart(void* arg) { VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg; self->releaseThreadFunc(); return 0; } void VideoEditorVideoEncoderPuller::acquireThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mAcquireCond.wait(mLock); } // Loop until we are asked to stop, or there is nothing more to read while (!mAskToStop) { MediaBuffer* pBuffer; mLock.unlock(); status_t result = mSource->read(&pBuffer, NULL); mLock.lock(); mSourceError = result; if (result != OK) { break; } mBuffers.push(pBuffer); mUserCond.signal(); } mAcquireStopped = true; mUserCond.signal(); mLock.unlock(); } void VideoEditorVideoEncoderPuller::releaseThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mReleaseCond.wait(mLock); } // Loop until we are asked to stop while (1) { if (mReleaseBuffers.empty()) { if (mAskToStop) { break; } else { mReleaseCond.wait(mLock); continue; } } MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0); mReleaseBuffers.removeAt(0); mLock.unlock(); pBuffer->release(); mLock.lock(); } mReleaseStopped = true; mUserCond.signal(); mLock.unlock(); } /** ****************************************************************************** Loading Loading @@ -468,7 +282,7 @@ typedef struct { OMXClient mClient; sp<MediaSource> mEncoder; OMX_COLOR_FORMATTYPE mEncoderColorFormat; VideoEditorVideoEncoderPuller* mPuller; MediaBufferPuller* mPuller; I420ColorConverter* mI420ColorConverter; uint32_t mNbInputFrames; Loading Loading @@ -902,7 +716,7 @@ M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext, pEncoderContext->mEncoderSource, NULL, codecFlags); VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE); ALOGV("VideoEditorVideoEncoder_open : DONE"); pEncoderContext->mPuller = new VideoEditorVideoEncoderPuller( pEncoderContext->mPuller = new MediaBufferPuller( pEncoderContext->mEncoder); // Set the new state Loading Loading
libvideoeditor/vss/stagefrightshells/src/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ MediaBufferPuller.cpp \ VideoEditorVideoDecoder.cpp \ VideoEditorAudioDecoder.cpp \ VideoEditorMp3Reader.cpp \ Loading
libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.cpp 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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 "MediaBufferPuller" #include <utils/Log.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include "MediaBufferPuller.h" namespace android { MediaBufferPuller::MediaBufferPuller(const sp<MediaSource>& source) : mSource(source), mAskToStart(false), mAskToStop(false), mAcquireStopped(false), mReleaseStopped(false), mSourceError(OK) { androidCreateThread(acquireThreadStart, this); androidCreateThread(releaseThreadStart, this); } MediaBufferPuller::~MediaBufferPuller() { stop(); } bool MediaBufferPuller::hasMediaSourceReturnedError() const { Mutex::Autolock autolock(mLock); return ((mSourceError != OK) ? true : false); } void MediaBufferPuller::start() { Mutex::Autolock autolock(mLock); mAskToStart = true; mAcquireCond.signal(); mReleaseCond.signal(); } void MediaBufferPuller::stop() { Mutex::Autolock autolock(mLock); mAskToStop = true; mAcquireCond.signal(); mReleaseCond.signal(); while (!mAcquireStopped || !mReleaseStopped) { mUserCond.wait(mLock); } // Release remaining buffers for (size_t i = 0; i < mBuffers.size(); i++) { mBuffers.itemAt(i)->release(); } for (size_t i = 0; i < mReleaseBuffers.size(); i++) { mReleaseBuffers.itemAt(i)->release(); } mBuffers.clear(); mReleaseBuffers.clear(); } MediaBuffer* MediaBufferPuller::getBufferNonBlocking() { Mutex::Autolock autolock(mLock); if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } MediaBuffer* MediaBufferPuller::getBufferBlocking() { Mutex::Autolock autolock(mLock); while (mBuffers.empty() && !mAcquireStopped) { mUserCond.wait(mLock); } if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } void MediaBufferPuller::putBuffer(MediaBuffer* buffer) { Mutex::Autolock autolock(mLock); mReleaseBuffers.push(buffer); mReleaseCond.signal(); } int MediaBufferPuller::acquireThreadStart(void* arg) { MediaBufferPuller* self = (MediaBufferPuller*)arg; self->acquireThreadFunc(); return 0; } int MediaBufferPuller::releaseThreadStart(void* arg) { MediaBufferPuller* self = (MediaBufferPuller*)arg; self->releaseThreadFunc(); return 0; } void MediaBufferPuller::acquireThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mAcquireCond.wait(mLock); } // Loop until we are asked to stop, or there is nothing more to read while (!mAskToStop) { MediaBuffer* pBuffer; mLock.unlock(); status_t result = mSource->read(&pBuffer, NULL); mLock.lock(); mSourceError = result; if (result != OK) { break; } mBuffers.push(pBuffer); mUserCond.signal(); } mAcquireStopped = true; mUserCond.signal(); mLock.unlock(); } void MediaBufferPuller::releaseThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mReleaseCond.wait(mLock); } // Loop until we are asked to stop while (1) { if (mReleaseBuffers.empty()) { if (mAskToStop) { break; } else { mReleaseCond.wait(mLock); continue; } } MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0); mReleaseBuffers.removeAt(0); mLock.unlock(); pBuffer->release(); mLock.lock(); } mReleaseStopped = true; mUserCond.signal(); mLock.unlock(); } }; // namespace android
libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.h 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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. */ #ifndef _MEDIA_BUFFER_PULLER_H #define _MEDIA_BUFFER_PULLER_H #include <utils/threads.h> #include <utils/Vector.h> namespace android { struct MediaSource; struct MediaBuffer; /* * An object of this class can pull a list of media buffers * from a MediaSource repeatedly. The user can then get the * buffers from that list. */ struct MediaBufferPuller { public: MediaBufferPuller(const sp<MediaSource>& source); ~MediaBufferPuller(); // Start to build up the list of the buffers. void start(); // Release the list of the available buffers, and stop // pulling buffers from the MediaSource. void stop(); // Get a buffer from the list. If there is no buffer available // at the time this method is called, NULL is returned. MediaBuffer* getBufferBlocking(); // Get a buffer from the list. If there is no buffer available // at the time this method is called, it blocks waiting for // a buffer to become available or until stop() is called. MediaBuffer* getBufferNonBlocking(); // Add a buffer to the end of the list available media buffers void putBuffer(MediaBuffer* buffer); // Check whether the source returned an error or not. bool hasMediaSourceReturnedError() const; private: static int acquireThreadStart(void* arg); void acquireThreadFunc(); static int releaseThreadStart(void* arg); void releaseThreadFunc(); sp<MediaSource> mSource; Vector<MediaBuffer*> mBuffers; Vector<MediaBuffer*> mReleaseBuffers; mutable Mutex mLock; Condition mUserCond; // for the user of this class Condition mAcquireCond; // for the acquire thread Condition mReleaseCond; // for the release thread bool mAskToStart; // Asks the threads to start bool mAskToStop; // Asks the threads to stop bool mAcquireStopped; // The acquire thread has stopped bool mReleaseStopped; // The release thread has stopped status_t mSourceError; // Error returned by MediaSource read // Don't call me! MediaBufferPuller(const MediaBufferPuller&); MediaBufferPuller& operator=(const MediaBufferPuller&); }; } // namespace android #endif // _MEDIA_BUFFER_PULLER_H
libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp +4 −190 Original line number Diff line number Diff line Loading @@ -29,8 +29,10 @@ #include "M4SYS_AccessUnit.h" #include "VideoEditorVideoEncoder.h" #include "VideoEditorUtils.h" #include "MediaBufferPuller.h" #include <I420ColorConverter.h> #include <unistd.h> #include "utils/Log.h" #include "utils/Vector.h" #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -248,194 +250,6 @@ int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() { Mutex::Autolock autolock(mLock); return mNbBuffer; } /******************** * PULLER * ********************/ // Pulls media buffers from a MediaSource repeatedly. // The user can then get the buffers from that list. class VideoEditorVideoEncoderPuller { public: VideoEditorVideoEncoderPuller(sp<MediaSource> source); ~VideoEditorVideoEncoderPuller(); void start(); void stop(); MediaBuffer* getBufferBlocking(); MediaBuffer* getBufferNonBlocking(); void putBuffer(MediaBuffer* buffer); bool hasMediaSourceReturnedError(); private: static int acquireThreadStart(void* arg); void acquireThreadFunc(); static int releaseThreadStart(void* arg); void releaseThreadFunc(); sp<MediaSource> mSource; Vector<MediaBuffer*> mBuffers; Vector<MediaBuffer*> mReleaseBuffers; Mutex mLock; Condition mUserCond; // for the user of this class Condition mAcquireCond; // for the acquire thread Condition mReleaseCond; // for the release thread bool mAskToStart; // Asks the threads to start bool mAskToStop; // Asks the threads to stop bool mAcquireStopped; // The acquire thread has stopped bool mReleaseStopped; // The release thread has stopped status_t mSourceError; // Error returned by MediaSource read }; VideoEditorVideoEncoderPuller::VideoEditorVideoEncoderPuller( sp<MediaSource> source) { mSource = source; mAskToStart = false; mAskToStop = false; mAcquireStopped = false; mReleaseStopped = false; mSourceError = OK; androidCreateThread(acquireThreadStart, this); androidCreateThread(releaseThreadStart, this); } VideoEditorVideoEncoderPuller::~VideoEditorVideoEncoderPuller() { stop(); } bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() { Mutex::Autolock autolock(mLock); return ((mSourceError != OK) ? true : false); } void VideoEditorVideoEncoderPuller::start() { Mutex::Autolock autolock(mLock); mAskToStart = true; mAcquireCond.signal(); mReleaseCond.signal(); } void VideoEditorVideoEncoderPuller::stop() { Mutex::Autolock autolock(mLock); mAskToStop = true; mAcquireCond.signal(); mReleaseCond.signal(); while (!mAcquireStopped || !mReleaseStopped) { mUserCond.wait(mLock); } // Release remaining buffers for (size_t i = 0; i < mBuffers.size(); i++) { mBuffers.itemAt(i)->release(); } for (size_t i = 0; i < mReleaseBuffers.size(); i++) { mReleaseBuffers.itemAt(i)->release(); } mBuffers.clear(); mReleaseBuffers.clear(); } MediaBuffer* VideoEditorVideoEncoderPuller::getBufferNonBlocking() { Mutex::Autolock autolock(mLock); if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } MediaBuffer* VideoEditorVideoEncoderPuller::getBufferBlocking() { Mutex::Autolock autolock(mLock); while (mBuffers.empty() && !mAcquireStopped) { mUserCond.wait(mLock); } if (mBuffers.empty()) { return NULL; } else { MediaBuffer* b = mBuffers.itemAt(0); mBuffers.removeAt(0); return b; } } void VideoEditorVideoEncoderPuller::putBuffer(MediaBuffer* buffer) { Mutex::Autolock autolock(mLock); mReleaseBuffers.push(buffer); mReleaseCond.signal(); } int VideoEditorVideoEncoderPuller::acquireThreadStart(void* arg) { VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg; self->acquireThreadFunc(); return 0; } int VideoEditorVideoEncoderPuller::releaseThreadStart(void* arg) { VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg; self->releaseThreadFunc(); return 0; } void VideoEditorVideoEncoderPuller::acquireThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mAcquireCond.wait(mLock); } // Loop until we are asked to stop, or there is nothing more to read while (!mAskToStop) { MediaBuffer* pBuffer; mLock.unlock(); status_t result = mSource->read(&pBuffer, NULL); mLock.lock(); mSourceError = result; if (result != OK) { break; } mBuffers.push(pBuffer); mUserCond.signal(); } mAcquireStopped = true; mUserCond.signal(); mLock.unlock(); } void VideoEditorVideoEncoderPuller::releaseThreadFunc() { mLock.lock(); // Wait for the start signal while (!mAskToStart && !mAskToStop) { mReleaseCond.wait(mLock); } // Loop until we are asked to stop while (1) { if (mReleaseBuffers.empty()) { if (mAskToStop) { break; } else { mReleaseCond.wait(mLock); continue; } } MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0); mReleaseBuffers.removeAt(0); mLock.unlock(); pBuffer->release(); mLock.lock(); } mReleaseStopped = true; mUserCond.signal(); mLock.unlock(); } /** ****************************************************************************** Loading Loading @@ -468,7 +282,7 @@ typedef struct { OMXClient mClient; sp<MediaSource> mEncoder; OMX_COLOR_FORMATTYPE mEncoderColorFormat; VideoEditorVideoEncoderPuller* mPuller; MediaBufferPuller* mPuller; I420ColorConverter* mI420ColorConverter; uint32_t mNbInputFrames; Loading Loading @@ -902,7 +716,7 @@ M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext, pEncoderContext->mEncoderSource, NULL, codecFlags); VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE); ALOGV("VideoEditorVideoEncoder_open : DONE"); pEncoderContext->mPuller = new VideoEditorVideoEncoderPuller( pEncoderContext->mPuller = new MediaBufferPuller( pEncoderContext->mEncoder); // Set the new state Loading