OSDN Git Service

Fix for issue 5309336
authorHong Teng <hongteng@google.com>
Thu, 10 Nov 2011 23:01:09 +0000 (15:01 -0800)
committerHong Teng <hongteng@google.com>
Mon, 14 Nov 2011 21:00:11 +0000 (13:00 -0800)
    -add videoeditor maximum prefetch YUV frames in media_profiles.xml to
     limit the total memory usage.

Change-Id: I43c03fc626194d9ebbe8d914d9209a04bc085831

libvideoeditor/vss/mcs/src/M4MCS_API.c
libvideoeditor/vss/src/M4xVSS_API.c
libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp

index 2ac0be1..d75a495 100755 (executable)
@@ -3746,7 +3746,11 @@ M4OSA_ERR M4MCS_setOutputParams( M4MCS_Context pContext,
             /**
             * Set output video profile and level */
             pC->encodingVideoProfile = pC->InputFileProperties.uiVideoProfile;
-            pC->encodingVideoLevel = pC->InputFileProperties.uiVideoLevel;
+            /** Set the target video level, because input 3gp file may
+             *  have wrong video level value (some encoders do not respect
+             *  level restrictions like video resolution when content is created).
+             **/
+            pC->encodingVideoLevel = pParams->outputVideoLevel;
 
             // Clip's original width and height may not be
             // multiple of 16.
index 37b2e47..eb85227 100755 (executable)
@@ -2587,6 +2587,10 @@ M4OSA_ERR M4xVSS_SendCommand( M4OSA_Context pContext,
                 }
                 else
                 {
+                    pParams->outputVideoProfile =
+                        xVSS_context->pSettings->xVSS.outputVideoProfile;
+                    pParams->outputVideoLevel =
+                        xVSS_context->pSettings->xVSS.outputVideoLevel;
                     pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo;
                     pParams->OutputVideoFrameRate =
                         M4VIDEOEDITING_k15_FPS; /* Must be set, otherwise, MCS returns an error */
index b0a6fdb..f47c921 100755 (executable)
@@ -39,6 +39,7 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
+#include <media/MediaProfiles.h>
 #include "OMX_Video.h"
 
 /********************
@@ -68,6 +69,7 @@ struct VideoEditorVideoEncoderSource : public MediaSource {
         virtual status_t read(MediaBuffer **buffer,
             const ReadOptions *options = NULL);
         virtual int32_t storeBuffer(MediaBuffer *buffer);
+        virtual int32_t getNumberOfBuffersInQueue();
 
     protected:
         virtual ~VideoEditorVideoEncoderSource();
@@ -242,6 +244,10 @@ int32_t VideoEditorVideoEncoderSource::storeBuffer(MediaBuffer *buffer) {
     return mNbBuffer;
 }
 
+int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
+    Mutex::Autolock autolock(mLock);
+    return mNbBuffer;
+}
 /********************
  *      PULLER      *
  ********************/
@@ -257,6 +263,7 @@ public:
     MediaBuffer* getBufferBlocking();
     MediaBuffer* getBufferNonBlocking();
     void putBuffer(MediaBuffer* buffer);
+    bool hasMediaSourceReturnedError();
 private:
     static int acquireThreadStart(void* arg);
     void acquireThreadFunc();
@@ -277,6 +284,7 @@ private:
     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(
@@ -286,6 +294,7 @@ VideoEditorVideoEncoderPuller::VideoEditorVideoEncoderPuller(
     mAskToStop = false;
     mAcquireStopped = false;
     mReleaseStopped = false;
+    mSourceError = OK;
     androidCreateThread(acquireThreadStart, this);
     androidCreateThread(releaseThreadStart, this);
 }
@@ -294,6 +303,10 @@ VideoEditorVideoEncoderPuller::~VideoEditorVideoEncoderPuller() {
     stop();
 }
 
+bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() {
+    Mutex::Autolock autolock(mLock);
+    return ((mSourceError != OK) ? true : false);
+}
 void VideoEditorVideoEncoderPuller::start() {
     Mutex::Autolock autolock(mLock);
     mAskToStart = true;
@@ -381,6 +394,7 @@ void VideoEditorVideoEncoderPuller::acquireThreadFunc() {
         mLock.unlock();
         status_t result = mSource->read(&pBuffer, NULL);
         mLock.lock();
+        mSourceError = result;
         if (result != OK) {
             break;
         }
@@ -464,6 +478,8 @@ typedef struct {
     int64_t                           mFirstOutputCts;
     int64_t                           mLastOutputCts;
 
+    MediaProfiles *mVideoEditorProfile;
+    int32_t mMaxPrefetchFrames;
 } VideoEditorVideoEncoder_Context;
 
 /********************
@@ -747,6 +763,10 @@ M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext,
 
     // 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,
@@ -1181,14 +1201,25 @@ M4OSA_ERR VideoEditorVideoEncoder_encode(M4ENCODER_Context pContext,
         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: