Fix for 3409334 Movie Studio "Force Close" after importing a 3gp video

Change-Id: I37949140a6c37a0c2d04221e220e7e267b6c7a02
diff --git a/libvideoeditor/lvpp/PreviewPlayer.cpp b/libvideoeditor/lvpp/PreviewPlayer.cpp
index 59e9bce..ca025d0 100644
--- a/libvideoeditor/lvpp/PreviewPlayer.cpp
+++ b/libvideoeditor/lvpp/PreviewPlayer.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+
 #define LOG_NDEBUG 1
 #define LOG_TAG "PreviewPlayer"
 #include <utils/Log.h>
@@ -75,19 +76,34 @@
 
 
 struct PreviewLocalRenderer : public PreviewPlayerRenderer {
-    PreviewLocalRenderer(
+
+    static PreviewLocalRenderer* initPreviewLocalRenderer (
             bool previewOnly,
             OMX_COLOR_FORMATTYPE colorFormat,
             const sp<Surface> &surface,
             size_t displayWidth, size_t displayHeight,
             size_t decodedWidth, size_t decodedHeight,
             int32_t rotationDegrees = 0)
-        : mTarget(NULL) {
-            init(previewOnly,
+    {
+        PreviewLocalRenderer* mLocalRenderer = new
+            PreviewLocalRenderer(
+                previewOnly,
+                colorFormat,
+                surface,
+                displayWidth, displayHeight,
+                decodedWidth, decodedHeight,
+                rotationDegrees);
+
+        if ( mLocalRenderer->init(previewOnly,
                  colorFormat, surface,
                  displayWidth, displayHeight,
                  decodedWidth, decodedHeight,
-                 rotationDegrees);
+                 rotationDegrees) != OK )
+        {
+            delete mLocalRenderer;
+            return NULL;
+        }
+        return mLocalRenderer;
     }
 
     virtual void render(MediaBuffer *buffer) {
@@ -114,7 +130,18 @@
 private:
     PreviewRenderer *mTarget;
 
-    void init(
+    PreviewLocalRenderer(
+            bool previewOnly,
+            OMX_COLOR_FORMATTYPE colorFormat,
+            const sp<Surface> &surface,
+            size_t displayWidth, size_t displayHeight,
+            size_t decodedWidth, size_t decodedHeight,
+            int32_t rotationDegrees = 0)
+        : mTarget(NULL) {
+    }
+
+
+    int init(
             bool previewOnly,
             OMX_COLOR_FORMATTYPE colorFormat,
             const sp<Surface> &surface,
@@ -126,16 +153,21 @@
     PreviewLocalRenderer &operator=(const PreviewLocalRenderer &);;
 };
 
-void PreviewLocalRenderer::init(
+int PreviewLocalRenderer::init(
         bool previewOnly,
         OMX_COLOR_FORMATTYPE colorFormat,
         const sp<Surface> &surface,
         size_t displayWidth, size_t displayHeight,
         size_t decodedWidth, size_t decodedHeight,
         int32_t rotationDegrees) {
-    mTarget = new PreviewRenderer(
+
+    mTarget = PreviewRenderer::CreatePreviewRenderer (
             colorFormat, surface, displayWidth, displayHeight,
             decodedWidth, decodedHeight, rotationDegrees);
+    if (mTarget == M4OSA_NULL) {
+        return UNKNOWN_ERROR;
+    }
+    return OK;
 }
 
 PreviewPlayer::PreviewPlayer()
@@ -538,7 +570,7 @@
 }
 
 
-void PreviewPlayer::initRenderer_l() {
+status_t PreviewPlayer::initRenderer_l() {
     if (mSurface != NULL || mISurface != NULL) {
         sp<MetaData> meta = mVideoSource->getFormat();
 
@@ -560,14 +592,21 @@
         // allocate their buffers in local address space.
         if(mVideoRenderer == NULL) {
 
-            mVideoRenderer = new PreviewLocalRenderer(
+            mVideoRenderer = PreviewLocalRenderer:: initPreviewLocalRenderer (
                 false,  // previewOnly
                 (OMX_COLOR_FORMATTYPE)format,
                 mSurface,
                 mOutputVideoWidth, mOutputVideoHeight,
                 mOutputVideoWidth, mOutputVideoHeight);
+
+            if ( mVideoRenderer == NULL )
+            {
+                return UNKNOWN_ERROR;
+            }
+            return OK;
         }
     }
+    return OK;
 }
 
 
@@ -749,7 +788,10 @@
                     CHECK(meta->findInt32(kKeyHeight, &mReportedHeight));
                     if (mVideoRenderer != NULL) {
                         mVideoRendererIsPreview = false;
-                        initRenderer_l();
+                        err = initRenderer_l();
+                           if ( err != OK )
+                        postStreamDoneEvent_l(err); // santosh
+
                     }
                     continue;
                 }
@@ -874,7 +916,9 @@
     if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
         mVideoRendererIsPreview = false;
 
-        initRenderer_l();
+        status_t err = initRenderer_l();
+        if ( err != OK )
+        postStreamDoneEvent_l(err); // santosh
     }
 
     // If timestamp exceeds endCutTime of clip, donot render
@@ -887,7 +931,7 @@
         mVideoBuffer = NULL;
         mFlags |= VIDEO_AT_EOS;
         mFlags |= AUDIO_AT_EOS;
-        LOGI("PreviewPlayer: onVideoEvent timeUs > mPlayEndTime; send EOS..");
+        LOGV("PreviewPlayer: onVideoEvent timeUs > mPlayEndTime; send EOS..");
         if (mOverlayUpdateEventPosted) {
             mOverlayUpdateEventPosted = false;
             postOverlayUpdateEvent_l();
@@ -1114,7 +1158,7 @@
     LOGV("onPrepareAsyncEvent");
 
     if (mFlags & PREPARE_CANCELLED) {
-        LOGI("LV PLAYER prepare was cancelled before doing anything");
+        LOGV("LV PLAYER prepare was cancelled before doing anything");
         abortPrepare(UNKNOWN_ERROR);
         return;
     }
@@ -1275,7 +1319,7 @@
 
     if (state->mLastVideoFrame && (mSurface != NULL || mISurface != NULL)) {
         mVideoRenderer =
-            new PreviewLocalRenderer(
+            PreviewLocalRenderer::initPreviewLocalRenderer(
                     true,  // previewOnly
                     (OMX_COLOR_FORMATTYPE)state->mColorFormat,
                     mSurface,
@@ -1731,7 +1775,9 @@
 
                     if (mVideoRenderer != NULL) {
                         mVideoRendererIsPreview = false;
-                        initRenderer_l();
+                        err = initRenderer_l();
+                        if ( err != OK )
+                                postStreamDoneEvent_l(err); // santosh
                     }
                     continue;
                 }
@@ -1756,7 +1802,6 @@
             if((videoTimeUs/1000) < mPlayBeginTimeMsec) {
                 // buffers are before begin cut time
                 // ignore them
-                //LOGI("PreviewPlayer: Ignoring buffers before begin cut time");
                 mVideoBuffer->release();
                 mVideoBuffer = NULL;
                 continue;
diff --git a/libvideoeditor/lvpp/PreviewPlayer.h b/libvideoeditor/lvpp/PreviewPlayer.h
index 59448ad..564c014 100644
--- a/libvideoeditor/lvpp/PreviewPlayer.h
+++ b/libvideoeditor/lvpp/PreviewPlayer.h
@@ -120,7 +120,7 @@
     void reset_l();
     void partial_reset_l();
     status_t play_l();
-    void initRenderer_l();
+    status_t initRenderer_l();
     status_t initAudioDecoder();
     status_t initVideoDecoder(uint32_t flags = 0);
     void onVideoEvent();
diff --git a/libvideoeditor/lvpp/PreviewRenderer.cpp b/libvideoeditor/lvpp/PreviewRenderer.cpp
index c2b6fa9..cfded72 100755
--- a/libvideoeditor/lvpp/PreviewRenderer.cpp
+++ b/libvideoeditor/lvpp/PreviewRenderer.cpp
@@ -29,6 +29,83 @@
 

 namespace android {

 

+PreviewRenderer* PreviewRenderer::CreatePreviewRenderer (OMX_COLOR_FORMATTYPE colorFormat,

+        const sp<Surface> &surface,

+        size_t displayWidth, size_t displayHeight,

+        size_t decodedWidth, size_t decodedHeight,

+        int32_t rotationDegrees) {

+

+        PreviewRenderer* returnCtx =

+            new PreviewRenderer(colorFormat,

+            surface,

+            displayWidth, displayHeight,

+            decodedWidth, decodedHeight,

+            rotationDegrees);

+

+        int result = 0;

+

+        int halFormat;

+        switch (returnCtx->mColorFormat) {

+            case OMX_COLOR_FormatYUV420Planar:

+            {

+                halFormat = HAL_PIXEL_FORMAT_YV12;

+                returnCtx->mYUVMode = None;

+                break;

+            }

+            default:

+                halFormat = HAL_PIXEL_FORMAT_RGB_565;

+

+                returnCtx->mConverter = new ColorConverter(

+                        returnCtx->mColorFormat, OMX_COLOR_Format16bitRGB565);

+                CHECK(returnCtx->mConverter->isValid());

+                break;

+        }

+

+        CHECK(returnCtx->mSurface.get() != NULL);

+        CHECK(returnCtx->mDecodedWidth > 0);

+        CHECK(returnCtx->mDecodedHeight > 0);

+        CHECK(returnCtx->mConverter == NULL || returnCtx->mConverter->isValid());

+

+        result = native_window_set_usage(

+                    returnCtx->mSurface.get(),

+                    GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN

+                    | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);

+

+        if ( result == 0 ) {

+            result = native_window_set_buffer_count(returnCtx->mSurface.get(), 3);

+

+            if (result == 0) {

+                result = native_window_set_buffers_geometry(

+                    returnCtx->mSurface.get(), returnCtx->mDecodedWidth, returnCtx->mDecodedHeight,

+                    halFormat);

+                if ( result == 0) {

+                    uint32_t transform;

+                    switch (rotationDegrees) {

+                        case 0: transform = 0; break;

+                        case 90: transform = HAL_TRANSFORM_ROT_90; break;

+                        case 180: transform = HAL_TRANSFORM_ROT_180; break;

+                        case 270: transform = HAL_TRANSFORM_ROT_270; break;

+                        default: transform = 0; break;

+                    }

+                    if (transform) {

+                        result = native_window_set_buffers_transform(

+                                    returnCtx->mSurface.get(), transform);

+

+                    }

+                }

+            }

+        }

+

+        if ( result != 0 )

+        {

+            /* free the ctx */

+            returnCtx->~PreviewRenderer();

+            return NULL;

+        }

+

+        return returnCtx;

+}

+

 PreviewRenderer::PreviewRenderer(

         OMX_COLOR_FORMATTYPE colorFormat,

         const sp<Surface> &surface,

@@ -43,61 +120,13 @@
       mDisplayHeight(displayHeight),

       mDecodedWidth(decodedWidth),

       mDecodedHeight(decodedHeight) {

+

     LOGV("input format = %d", mColorFormat);

     LOGV("display = %d x %d, decoded = %d x %d",

             mDisplayWidth, mDisplayHeight, mDecodedWidth, mDecodedHeight);

 

     mDecodedWidth = mDisplayWidth;

     mDecodedHeight = mDisplayHeight;

-

-    int halFormat;

-    switch (mColorFormat) {

-        case OMX_COLOR_FormatYUV420Planar:

-        {

-            halFormat = HAL_PIXEL_FORMAT_YV12;

-            mYUVMode = None;

-            break;

-        }

-        default:

-            halFormat = HAL_PIXEL_FORMAT_RGB_565;

-

-            mConverter = new ColorConverter(

-                    mColorFormat, OMX_COLOR_Format16bitRGB565);

-            CHECK(mConverter->isValid());

-            break;

-    }

-

-    CHECK(mSurface.get() != NULL);

-    CHECK(mDecodedWidth > 0);

-    CHECK(mDecodedHeight > 0);

-    CHECK(mConverter == NULL || mConverter->isValid());

-

-    CHECK_EQ(0,

-            native_window_set_usage(

-            mSurface.get(),

-            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN

-            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));

-

-    CHECK_EQ(0, native_window_set_buffer_count(mSurface.get(), 3));

-

-    // Width must be multiple of 32???

-    CHECK_EQ(0, native_window_set_buffers_geometry(

-                mSurface.get(), mDecodedWidth, mDecodedHeight,

-                halFormat));

-

-    uint32_t transform;

-    switch (rotationDegrees) {

-        case 0: transform = 0; break;

-        case 90: transform = HAL_TRANSFORM_ROT_90; break;

-        case 180: transform = HAL_TRANSFORM_ROT_180; break;

-        case 270: transform = HAL_TRANSFORM_ROT_270; break;

-        default: transform = 0; break;

-    }

-

-    if (transform) {

-        CHECK_EQ(0, native_window_set_buffers_transform(

-                    mSurface.get(), transform));

-    }

 }

 

 PreviewRenderer::~PreviewRenderer() {

diff --git a/libvideoeditor/lvpp/PreviewRenderer.h b/libvideoeditor/lvpp/PreviewRenderer.h
index d5dcd85..876ca16 100755
--- a/libvideoeditor/lvpp/PreviewRenderer.h
+++ b/libvideoeditor/lvpp/PreviewRenderer.h
@@ -25,18 +25,19 @@
 #include <ui/GraphicBufferMapper.h>

 #include "SoftwareRenderer.h"

 

+

 namespace android {

 

 class Surface;

 

 class PreviewRenderer {

 public:

-    PreviewRenderer(

-            OMX_COLOR_FORMATTYPE colorFormat,

-            const sp<Surface> &surface,

-            size_t displayWidth, size_t displayHeight,

-            size_t decodedWidth, size_t decodedHeight,

-            int32_t rotationDegrees);

+

+static PreviewRenderer* CreatePreviewRenderer (OMX_COLOR_FORMATTYPE colorFormat,

+        const sp<Surface> &surface,

+        size_t displayWidth, size_t displayHeight,

+        size_t decodedWidth, size_t decodedHeight,

+        int32_t rotationDegrees);

 

     ~PreviewRenderer();

 

@@ -52,6 +53,12 @@
     }

 

 private:

+    PreviewRenderer(

+            OMX_COLOR_FORMATTYPE colorFormat,

+            const sp<Surface> &surface,

+            size_t displayWidth, size_t displayHeight,

+            size_t decodedWidth, size_t decodedHeight,

+            int32_t rotationDegrees);

     enum YUVMode {

         None,

         YUV420ToYUV420sp,

diff --git a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
index fd04fd5..78f0cda 100755
--- a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
@@ -705,9 +705,11 @@
 

     // Initialize the renderer

     if(mTarget == NULL) {

-        mTarget = new PreviewRenderer(

+

+        mTarget = PreviewRenderer::CreatePreviewRenderer(

             OMX_COLOR_FormatYUV420Planar, surface, outputBufferWidth, outputBufferHeight,

             outputBufferWidth, outputBufferHeight, 0);

+

         if(mTarget == NULL) {

             LOGE("renderPreviewFrame: cannot create PreviewRenderer");

             return M4ERR_ALLOC;

@@ -750,7 +752,6 @@
     M4OSA_UInt32 i = 0, iIncrementedDuration = 0, tnTimeMs=0, framesize =0;

     VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo;

     M4VIFI_UInt8 *pixelArray = NULL;

-

     Mutex::Autolock autoLock(mLock);

 

     // Get the Isurface to be passed to renderer

@@ -774,9 +775,14 @@
 

     // Initialize the renderer

     if(mTarget == NULL) {

-        mTarget = new PreviewRenderer(

+        /*mTarget = new PreviewRenderer(

+            OMX_COLOR_FormatYUV420Planar, surface, mOutputVideoWidth, mOutputVideoHeight,

+            mOutputVideoWidth, mOutputVideoHeight, 0);*/

+

+         mTarget = PreviewRenderer::CreatePreviewRenderer(

             OMX_COLOR_FormatYUV420Planar, surface, mOutputVideoWidth, mOutputVideoHeight,

             mOutputVideoWidth, mOutputVideoHeight, 0);

+

         if(mTarget == NULL) {

             LOGE("renderPreviewFrame: cannot create PreviewRenderer");

             return M4ERR_ALLOC;