Merge "Fix for issue 3439595 : Movie studio playback previous frames"
diff --git a/libvideoeditor/vss/inc/M4VSS3GPP_InternalTypes.h b/libvideoeditor/vss/inc/M4VSS3GPP_InternalTypes.h
index bc29b2a..570b654 100755
--- a/libvideoeditor/vss/inc/M4VSS3GPP_InternalTypes.h
+++ b/libvideoeditor/vss/inc/M4VSS3GPP_InternalTypes.h
@@ -84,14 +84,21 @@
 
 typedef enum
 {
-    M4VSS3GPP_kEditVideoState_READ_WRITE    = 10,    /**< Doing Read/Write operation
-                                                        (no decoding/encoding) */
-    M4VSS3GPP_kEditVideoState_BEGIN_CUT     = 11,    /**< Decode encode to create an I frame */
-    M4VSS3GPP_kEditVideoState_DECODE_ENCODE = 12,    /**< Doing Read-Decode/Filter/
-                                                        Encode-Write operation */
-    M4VSS3GPP_kEditVideoState_TRANSITION    = 13,    /**< Transition; blending of two videos */
-    M4VSS3GPP_kEditVideoState_AFTER_CUT     = 14    /**< Special Read/Write mode after a
-                                                            begin cut (time frozen) */
+    /**< Doing Read/Write operation. This operation will have no processing
+     * on input frames. Only time stamp manipulations in output file. */
+    M4VSS3GPP_kEditVideoState_READ_WRITE    = 10,
+    /**< Decode encode to create an I frame. This is done for a single frame
+     * to create a new reference frame. */
+    M4VSS3GPP_kEditVideoState_BEGIN_CUT     = 11,
+    /**< Doing Read->Decode->Filter->Encode->Write operation on the input file
+     * to create the output file. */
+    M4VSS3GPP_kEditVideoState_DECODE_ENCODE = 12,
+    /**< Applied when Transition is active and blending of two videos is
+     * required. */
+    M4VSS3GPP_kEditVideoState_TRANSITION    = 13,
+    /**< Special Read/Write mode used after BEGIN_CUT state. The frame
+     * is already coded as I frame in BEGIN_CUT state; so skip it. */
+    M4VSS3GPP_kEditVideoState_AFTER_CUT     = 14
 }
 M4VSS3GPP_EditVideoState;
 
@@ -611,6 +618,7 @@
     M4OSA_Bool               m_bClipExternalHasStarted;  /**< Flag to indicate that an
                                                               external effect is active */
     M4OSA_Int32              iInOutTimeOffset;
+    M4OSA_Bool               bEncodeTillEoF;
 } M4VSS3GPP_InternalEditContext;
 
 
diff --git a/libvideoeditor/vss/mcs/src/M4MCS_API.c b/libvideoeditor/vss/mcs/src/M4MCS_API.c
index aaaed14..a327426 100755
--- a/libvideoeditor/vss/mcs/src/M4MCS_API.c
+++ b/libvideoeditor/vss/mcs/src/M4MCS_API.c
@@ -3237,12 +3237,6 @@
         M4OSA_free((M4OSA_MemAddr32)pC->H264MCSTempBuffer);
     }
 
-    if( M4OSA_NULL != pC->m_pInstance )
-    {
-        err = H264MCS_Freeinstance(pC->m_pInstance);
-        pC->m_pInstance = M4OSA_NULL;
-    }
-
     M4OSA_TRACE3_0("M4MCS_close(): returning M4NO_ERROR");
     return err;
 }
@@ -3307,6 +3301,12 @@
         return M4ERR_STATE;
     }
 
+    if( M4OSA_NULL != pC->m_pInstance )
+    {
+        err = H264MCS_Freeinstance(pC->m_pInstance);
+        pC->m_pInstance = M4OSA_NULL;
+    }
+
     /* ----- Free video encoder stuff, if needed ----- */
 
     if( ( M4OSA_NULL != pC->pViEncCtxt)
diff --git a/libvideoeditor/vss/src/M4VSS3GPP_Edit.c b/libvideoeditor/vss/src/M4VSS3GPP_Edit.c
index acdbfdc..8ae0f15 100755
--- a/libvideoeditor/vss/src/M4VSS3GPP_Edit.c
+++ b/libvideoeditor/vss/src/M4VSS3GPP_Edit.c
@@ -230,6 +230,7 @@
     pC->bIsMMS = M4OSA_FALSE;
 
     pC->iInOutTimeOffset = 0;
+    pC->bEncodeTillEoF = M4OSA_FALSE;
 
     /**
     * Return with no error */
@@ -3291,8 +3292,9 @@
             }
         }
     }
-    /* The flag is set to false at the beginning of every clip */
+    /* The flags are set to false at the beginning of every clip */
     pC->m_bClipExternalHasStarted = M4OSA_FALSE;
+    pC->bEncodeTillEoF = M4OSA_FALSE;
 
     /**
     * Return with no error */
diff --git a/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c b/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
index 2dfd07b..d15707c 100755
--- a/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
+++ b/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
@@ -729,11 +729,15 @@
         to catch all P-frames after the cut) */
         else if( M4OSA_TRUE == pC->bClip1AtBeginCut )
         {
-            if( ( M4VSS3GPP_kEditVideoState_BEGIN_CUT == previousVstate)
-                || (M4VSS3GPP_kEditVideoState_AFTER_CUT == previousVstate) )
+            if(pC->pC1->pSettings->ClipProperties.VideoStreamType == M4VIDEOEDITING_kH264) {
+                pC->Vstate = M4VSS3GPP_kEditVideoState_DECODE_ENCODE;
+                pC->bEncodeTillEoF = M4OSA_TRUE;
+            } else if( ( M4VSS3GPP_kEditVideoState_BEGIN_CUT == previousVstate)
+                || (M4VSS3GPP_kEditVideoState_AFTER_CUT == previousVstate) ) {
                 pC->Vstate = M4VSS3GPP_kEditVideoState_AFTER_CUT;
-            else
+            } else {
                 pC->Vstate = M4VSS3GPP_kEditVideoState_BEGIN_CUT;
+            }
         }
         /* Else we are in default copy/paste mode */
         else
@@ -777,7 +781,8 @@
                 }
             }
             else if(!((pC->m_bClipExternalHasStarted == M4OSA_TRUE) &&
-                    (pC->Vstate == M4VSS3GPP_kEditVideoState_DECODE_ENCODE)))
+                    (pC->Vstate == M4VSS3GPP_kEditVideoState_DECODE_ENCODE)) &&
+                    pC->bEncodeTillEoF == M4OSA_FALSE)
             {
                 /**
                  * Test if we go into copy/paste mode or into decode/encode mode
@@ -835,7 +840,7 @@
         || (M4VSS3GPP_kEditVideoState_TRANSITION
         == previousVstate)) /**< encode mode */
         && (M4VSS3GPP_kEditVideoState_READ_WRITE == pC->Vstate) /**< read mode */
-        )
+        && (pC->bEncodeTillEoF == M4OSA_FALSE) )
     {
         pC->Vstate = M4VSS3GPP_kEditVideoState_BEGIN_CUT;
     }