#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/MediaProfiles.h>
#include "OMX_Video.h"
/********************
virtual status_t read(MediaBuffer **buffer,
const ReadOptions *options = NULL);
virtual int32_t storeBuffer(MediaBuffer *buffer);
+ virtual int32_t getNumberOfBuffersInQueue();
protected:
virtual ~VideoEditorVideoEncoderSource();
return mNbBuffer;
}
+int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
+ Mutex::Autolock autolock(mLock);
+ return mNbBuffer;
+}
/********************
* PULLER *
********************/
MediaBuffer* getBufferBlocking();
MediaBuffer* getBufferNonBlocking();
void putBuffer(MediaBuffer* buffer);
+ bool hasMediaSourceReturnedError();
private:
static int acquireThreadStart(void* arg);
void acquireThreadFunc();
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(
mAskToStop = false;
mAcquireStopped = false;
mReleaseStopped = false;
+ mSourceError = OK;
androidCreateThread(acquireThreadStart, this);
androidCreateThread(releaseThreadStart, this);
}
stop();
}
+bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() {
+ Mutex::Autolock autolock(mLock);
+ return ((mSourceError != OK) ? true : false);
+}
void VideoEditorVideoEncoderPuller::start() {
Mutex::Autolock autolock(mLock);
mAskToStart = true;
mLock.unlock();
status_t result = mSource->read(&pBuffer, NULL);
mLock.lock();
+ mSourceError = result;
if (result != OK) {
break;
}
int64_t mFirstOutputCts;
int64_t mLastOutputCts;
+ MediaProfiles *mVideoEditorProfile;
+ int32_t mMaxPrefetchFrames;
} VideoEditorVideoEncoder_Context;
/********************
// Context initialization
pEncoderContext->mAccessUnit = pAU;
+ pEncoderContext->mVideoEditorProfile = MediaProfiles::getInstance();
+ pEncoderContext->mMaxPrefetchFrames =
+ pEncoderContext->mVideoEditorProfile->getVideoEditorCapParamByName(
+ "maxPrefetchYUVFrames");
// Allocate & initialize the encoding parameters
SAFE_MALLOC(pEncoderContext->mCodecParams, M4ENCODER_Params, 1,
MediaBuffer *outputBuffer =
pEncoderContext->mPuller->getBufferNonBlocking();
- if (outputBuffer == NULL) break;
-
- // Provide the encoded AU to the writer
- err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
- outputBuffer);
- VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
+ if (outputBuffer == NULL) {
+ int32_t YUVBufferNumber =
+ pEncoderContext->mEncoderSource->getNumberOfBuffersInQueue();
+ /* Make sure that the configured maximum number of prefetch YUV frames is
+ * not exceeded. This is to limit the amount of memory usage of video editor engine.
+ * The value of maximum prefetch Yuv frames is defined in media_profiles.xml */
+ if ((YUVBufferNumber < pEncoderContext->mMaxPrefetchFrames) ||
+ (pEncoderContext->mPuller->hasMediaSourceReturnedError()
+ == true)) {
+ break;
+ }
+ } else {
+ // Provide the encoded AU to the writer
+ err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
+ outputBuffer);
+ VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
- pEncoderContext->mPuller->putBuffer(outputBuffer);
+ pEncoderContext->mPuller->putBuffer(outputBuffer);
+ }
}
cleanUp: