summaryrefslogtreecommitdiffstats
path: root/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c')
-rwxr-xr-xlibvideoeditor/vss/src/M4VSS3GPP_EditVideo.c3955
1 files changed, 0 insertions, 3955 deletions
diff --git a/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c b/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
deleted file mode 100755
index f19f412..0000000
--- a/libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c
+++ /dev/null
@@ -1,3955 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-/**
- ******************************************************************************
- * @file M4VSS3GPP_EditVideo.c
- * @brief Video Studio Service 3GPP edit API implementation.
- * @note
- ******************************************************************************
- */
-#undef M4OSA_TRACE_LEVEL
-#define M4OSA_TRACE_LEVEL 1
-
-/****************/
-/*** Includes ***/
-/****************/
-
-#include "NXPSW_CompilerSwitches.h"
-/**
- * Our header */
-#include "M4VSS3GPP_API.h"
-#include "M4VSS3GPP_InternalTypes.h"
-#include "M4VSS3GPP_InternalFunctions.h"
-#include "M4VSS3GPP_InternalConfig.h"
-#include "M4VSS3GPP_ErrorCodes.h"
-
-// StageFright encoders require %16 resolution
-#include "M4ENCODER_common.h"
-/**
- * OSAL headers */
-#include "M4OSA_Memory.h" /**< OSAL memory management */
-#include "M4OSA_Debug.h" /**< OSAL debug management */
-
-/**
- * component includes */
-#include "M4VFL_transition.h" /**< video effects */
-
-/*for transition behaviour*/
-#include <math.h>
-#include "M4AIR_API.h"
-#include "M4VSS3GPP_Extended_API.h"
-/** Determine absolute value of a. */
-#define M4xVSS_ABS(a) ( ( (a) < (0) ) ? (-(a)) : (a) )
-#define Y_PLANE_BORDER_VALUE 0x00
-#define U_PLANE_BORDER_VALUE 0x80
-#define V_PLANE_BORDER_VALUE 0x80
-
-/************************************************************************/
-/* Static local functions */
-/************************************************************************/
-
-static M4OSA_ERR M4VSS3GPP_intCheckVideoMode(
- M4VSS3GPP_InternalEditContext *pC );
-static M4OSA_Void
-M4VSS3GPP_intCheckVideoEffects( M4VSS3GPP_InternalEditContext *pC,
- M4OSA_UInt8 uiClipNumber );
-static M4OSA_ERR M4VSS3GPP_intApplyVideoEffect(
- M4VSS3GPP_InternalEditContext *pC, M4VIFI_ImagePlane *pPlaneIn,
- M4VIFI_ImagePlane *pPlaneOut, M4OSA_Bool bSkipFramingEffect);
-
-static M4OSA_ERR
-M4VSS3GPP_intVideoTransition( M4VSS3GPP_InternalEditContext *pC,
- M4VIFI_ImagePlane *pPlaneOut );
-
-static M4OSA_Void
-M4VSS3GPP_intUpdateTimeInfo( M4VSS3GPP_InternalEditContext *pC,
- M4SYS_AccessUnit *pAU );
-static M4OSA_Void M4VSS3GPP_intSetH263TimeCounter( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt8 uiCts );
-static M4OSA_Void M4VSS3GPP_intSetMPEG4Gov( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt32 uiCtsSec );
-static M4OSA_Void M4VSS3GPP_intGetMPEG4Gov( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt32 *pCtsSec );
-static M4OSA_ERR M4VSS3GPP_intAllocateYUV420( M4VIFI_ImagePlane *pPlanes,
- M4OSA_UInt32 uiWidth, M4OSA_UInt32 uiHeight );
-static M4OSA_ERR M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420(
- M4OSA_Void* pFileIn, M4OSA_FileReadPointer* pFileReadPtr,
- M4VIFI_ImagePlane* pImagePlanes,
- M4OSA_UInt32 width,M4OSA_UInt32 height);
-static M4OSA_ERR M4VSS3GPP_intApplyRenderingMode(
- M4VSS3GPP_InternalEditContext *pC,
- M4xVSS_MediaRendering renderingMode,
- M4VIFI_ImagePlane* pInplane,
- M4VIFI_ImagePlane* pOutplane);
-
-static M4OSA_ERR M4VSS3GPP_intSetYuv420PlaneFromARGB888 (
- M4VSS3GPP_InternalEditContext *pC,
- M4VSS3GPP_ClipContext* pClipCtxt);
-static M4OSA_ERR M4VSS3GPP_intRenderFrameWithEffect(
- M4VSS3GPP_InternalEditContext *pC,
- M4VSS3GPP_ClipContext* pClipCtxt,
- M4_MediaTime ts,
- M4OSA_Bool bIsClip1,
- M4VIFI_ImagePlane *pResizePlane,
- M4VIFI_ImagePlane *pPlaneNoResize,
- M4VIFI_ImagePlane *pPlaneOut);
-
-static M4OSA_ERR M4VSS3GPP_intRotateVideo(M4VIFI_ImagePlane* pPlaneIn,
- M4OSA_UInt32 rotationDegree);
-
-static M4OSA_ERR M4VSS3GPP_intSetYUV420Plane(M4VIFI_ImagePlane* planeIn,
- M4OSA_UInt32 width, M4OSA_UInt32 height);
-
-static M4OSA_ERR M4VSS3GPP_intApplyVideoOverlay (
- M4VSS3GPP_InternalEditContext *pC,
- M4VIFI_ImagePlane *pPlaneIn,
- M4VIFI_ImagePlane *pPlaneOut);
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intEditStepVideo()
- * @brief One step of video processing
- * @param pC (IN/OUT) Internal edit context
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intEditStepVideo( M4VSS3GPP_InternalEditContext *pC )
-{
- M4OSA_ERR err;
- M4OSA_Int32 iCts, iNextCts;
- M4ENCODER_FrameMode FrameMode;
- M4OSA_Bool bSkipFrame;
- M4OSA_UInt16 offset;
-
- /**
- * Check if we reached end cut. Decorrelate input and output encoding
- * timestamp to handle encoder prefetch
- */
- if ( ((M4OSA_Int32)(pC->ewc.dInputVidCts) - pC->pC1->iVoffset
- + pC->iInOutTimeOffset) >= pC->pC1->iEndTime )
- {
- /* Re-adjust video to precise cut time */
- pC->iInOutTimeOffset = ((M4OSA_Int32)(pC->ewc.dInputVidCts))
- - pC->pC1->iVoffset + pC->iInOutTimeOffset - pC->pC1->iEndTime;
- if ( pC->iInOutTimeOffset < 0 ) {
- pC->iInOutTimeOffset = 0;
- }
-
- /**
- * Video is done for this clip */
- err = M4VSS3GPP_intReachedEndOfVideo(pC);
-
- /* RC: to know when a file has been processed */
- if (M4NO_ERROR != err && err != M4VSS3GPP_WAR_SWITCH_CLIP)
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: M4VSS3GPP_intReachedEndOfVideo returns 0x%x",
- err);
- }
-
- return err;
- }
-
- /* Don't change the states if we are in decodeUpTo() */
- if ( (M4VSS3GPP_kClipStatus_DECODE_UP_TO != pC->pC1->Vstatus)
- && (( pC->pC2 == M4OSA_NULL)
- || (M4VSS3GPP_kClipStatus_DECODE_UP_TO != pC->pC2->Vstatus)) )
- {
- /**
- * Check Video Mode, depending on the current output CTS */
- err = M4VSS3GPP_intCheckVideoMode(
- pC); /**< This function change the pC->Vstate variable! */
-
- if (M4NO_ERROR != err)
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: M4VSS3GPP_intCheckVideoMode returns 0x%x!",
- err);
- return err;
- }
- }
-
-
- switch( pC->Vstate )
- {
- /* _________________ */
- /*| |*/
- /*| READ_WRITE MODE |*/
- /*|_________________|*/
-
- case M4VSS3GPP_kEditVideoState_READ_WRITE:
- case M4VSS3GPP_kEditVideoState_AFTER_CUT:
- {
- M4OSA_TRACE3_0("M4VSS3GPP_intEditStepVideo READ_WRITE");
-
- bSkipFrame = M4OSA_FALSE;
-
- /**
- * If we were decoding the clip, we must jump to be sure
- * to get to the good position. */
- if( M4VSS3GPP_kClipStatus_READ != pC->pC1->Vstatus )
- {
- /**
- * Jump to target video time (tc = to-T) */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- iCts = (M4OSA_Int32)(pC->ewc.dInputVidCts) - pC->pC1->iVoffset;
- err = pC->pC1->ShellAPI.m_pReader->m_pFctJump(
- pC->pC1->pReaderContext,
- (M4_StreamHandler *)pC->pC1->pVideoStream, &iCts);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo:\
- READ_WRITE: m_pReader->m_pFctJump(V1) returns 0x%x!",
- err);
- return err;
- }
-
- err = pC->pC1->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
- pC->pC1->pReaderContext,
- (M4_StreamHandler *)pC->pC1->pVideoStream,
- &pC->pC1->VideoAU);
-
- if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo:\
- READ_WRITE: m_pReader->m_pFctGetNextAu returns 0x%x!",
- err);
- return err;
- }
-
- M4OSA_TRACE2_3("A .... read : cts = %.0f + %ld [ 0x%x ]",
- pC->pC1->VideoAU.m_CTS, pC->pC1->iVoffset,
- pC->pC1->VideoAU.m_size);
-
- /* This frame has been already written in BEGIN CUT step -> skip it */
- if( pC->pC1->VideoAU.m_CTS == iCts
- && pC->pC1->iVideoRenderCts >= iCts )
- {
- bSkipFrame = M4OSA_TRUE;
- }
- }
-
- /* This frame has been already written in BEGIN CUT step -> skip it */
- if( ( pC->Vstate == M4VSS3GPP_kEditVideoState_AFTER_CUT)
- && (pC->pC1->VideoAU.m_CTS
- + pC->pC1->iVoffset <= pC->ewc.WriterVideoAU.CTS) )
- {
- bSkipFrame = M4OSA_TRUE;
- }
-
- /**
- * Remember the clip reading state */
- pC->pC1->Vstatus = M4VSS3GPP_kClipStatus_READ;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- // Rounding is to compensate reader imprecision (m_CTS is actually an integer)
- iCts = ((M4OSA_Int32)pC->ewc.dInputVidCts) - pC->pC1->iVoffset - 1;
- iNextCts = iCts + ((M4OSA_Int32)pC->dOutputFrameDuration) + 1;
- /* Avoid to write a last frame of duration 0 */
- if( iNextCts > pC->pC1->iEndTime )
- iNextCts = pC->pC1->iEndTime;
-
- /**
- * If the AU is good to be written, write it, else just skip it */
- if( ( M4OSA_FALSE == bSkipFrame)
- && (( pC->pC1->VideoAU.m_CTS >= iCts)
- && (pC->pC1->VideoAU.m_CTS < iNextCts)
- && (pC->pC1->VideoAU.m_size > 0)) )
- {
- /**
- * Get the output AU to write into */
- err = pC->ShellAPI.pWriterDataFcts->pStartAU(
- pC->ewc.p3gpWriterContext,
- M4VSS3GPP_WRITER_VIDEO_STREAM_ID,
- &pC->ewc.WriterVideoAU);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: READ_WRITE:\
- pWriterDataFcts->pStartAU(Video) returns 0x%x!",
- err);
- return err;
- }
-
- /**
- * Copy the input AU to the output AU */
- pC->ewc.WriterVideoAU.attribute = pC->pC1->VideoAU.m_attribute;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->ewc.WriterVideoAU.CTS = (M4OSA_Time)pC->pC1->VideoAU.m_CTS +
- (M4OSA_Time)pC->pC1->iVoffset;
- pC->ewc.dInputVidCts += pC->dOutputFrameDuration;
- offset = 0;
- /* for h.264 stream do not read the 1st 4 bytes as they are header
- indicators */
- if( pC->pC1->pVideoStream->m_basicProperties.m_streamType
- == M4DA_StreamTypeVideoMpeg4Avc )
- offset = 4;
-
- pC->ewc.WriterVideoAU.size = pC->pC1->VideoAU.m_size - offset;
- if( pC->ewc.WriterVideoAU.size > pC->ewc.uiVideoMaxAuSize )
- {
- M4OSA_TRACE1_2(
- "M4VSS3GPP_intEditStepVideo: READ_WRITE: AU size greater than\
- MaxAuSize (%d>%d)! returning M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE",
- pC->ewc.WriterVideoAU.size, pC->ewc.uiVideoMaxAuSize);
- return M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE;
- }
-
- memcpy((void *)pC->ewc.WriterVideoAU.dataAddress,
- (void *)(pC->pC1->VideoAU.m_dataAddress + offset),
- (pC->ewc.WriterVideoAU.size));
-
- /**
- * Update time info for the Counter Time System to be equal to the bit
- -stream time*/
- M4VSS3GPP_intUpdateTimeInfo(pC, &pC->ewc.WriterVideoAU);
- M4OSA_TRACE2_2("B ---- write : cts = %lu [ 0x%x ]",
- pC->ewc.WriterVideoAU.CTS, pC->ewc.WriterVideoAU.size);
-
- /**
- * Write the AU */
- err = pC->ShellAPI.pWriterDataFcts->pProcessAU(
- pC->ewc.p3gpWriterContext,
- M4VSS3GPP_WRITER_VIDEO_STREAM_ID,
- &pC->ewc.WriterVideoAU);
-
- if( M4NO_ERROR != err )
- {
- /* the warning M4WAR_WRITER_STOP_REQ is returned when the targeted output
- file size is reached
- The editing is then finished, the warning M4VSS3GPP_WAR_EDITING_DONE
- is returned*/
- if( M4WAR_WRITER_STOP_REQ == err )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intEditStepVideo: File was cut to avoid oversize");
- return M4VSS3GPP_WAR_EDITING_DONE;
- }
- else
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: READ_WRITE:\
- pWriterDataFcts->pProcessAU(Video) returns 0x%x!",
- err);
- return err;
- }
- }
-
- /**
- * Read next AU for next step */
- err = pC->pC1->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
- pC->pC1->pReaderContext,
- (M4_StreamHandler *)pC->pC1->pVideoStream,
- &pC->pC1->VideoAU);
-
- if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: READ_WRITE:\
- m_pReaderDataIt->m_pFctGetNextAu returns 0x%x!",
- err);
- return err;
- }
-
- M4OSA_TRACE2_3("C .... read : cts = %.0f + %ld [ 0x%x ]",
- pC->pC1->VideoAU.m_CTS, pC->pC1->iVoffset,
- pC->pC1->VideoAU.m_size);
- }
- else
- {
- /**
- * Decide wether to read or to increment time increment */
- if( ( pC->pC1->VideoAU.m_size == 0)
- || (pC->pC1->VideoAU.m_CTS >= iNextCts) )
- {
- /*Increment time by the encoding period (NO_MORE_AU or reader in advance */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->ewc.dInputVidCts += pC->dOutputFrameDuration;
-
- /* Switch (from AFTER_CUT) to normal mode because time is
- no more frozen */
- pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE;
- }
- else
- {
- /* In other cases (reader late), just let the reader catch up
- pC->ewc.dVTo */
- err = pC->pC1->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
- pC->pC1->pReaderContext,
- (M4_StreamHandler *)pC->pC1->pVideoStream,
- &pC->pC1->VideoAU);
-
- if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: READ_WRITE:\
- m_pReaderDataIt->m_pFctGetNextAu returns 0x%x!",
- err);
- return err;
- }
-
- M4OSA_TRACE2_3("D .... read : cts = %.0f + %ld [ 0x%x ]",
- pC->pC1->VideoAU.m_CTS, pC->pC1->iVoffset,
- pC->pC1->VideoAU.m_size);
- }
- }
- }
- break;
-
- /* ____________________ */
- /*| |*/
- /*| DECODE_ENCODE MODE |*/
- /*| BEGIN_CUT MODE |*/
- /*|____________________|*/
-
- case M4VSS3GPP_kEditVideoState_DECODE_ENCODE:
- case M4VSS3GPP_kEditVideoState_BEGIN_CUT:
- {
- M4OSA_TRACE3_0(
- "M4VSS3GPP_intEditStepVideo DECODE_ENCODE / BEGIN_CUT");
-
- if ((pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (M4OSA_FALSE ==
- pC->pC1->pSettings->ClipProperties.bSetImageData)) {
-
- err = M4VSS3GPP_intSetYuv420PlaneFromARGB888(pC, pC->pC1);
- if( M4NO_ERROR != err ) {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: DECODE_ENCODE:\
- M4VSS3GPP_intSetYuv420PlaneFromARGB888 err=%x", err);
- return err;
- }
- }
- /**
- * Decode the video up to the target time
- (will jump to the previous RAP if needed ) */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- err = M4VSS3GPP_intClipDecodeVideoUpToCts(pC->pC1, (M4OSA_Int32)pC->ewc.dInputVidCts);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: DECODE_ENCODE:\
- M4VSS3GPP_intDecodeVideoUpToCts returns err=0x%x",
- err);
- return err;
- }
-
- /* If the decoding is not completed, do one more step with time frozen */
- if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pC->pC1->Vstatus )
- {
- return M4NO_ERROR;
- }
-
- /**
- * Reset the video pre-processing error before calling the encoder */
- pC->ewc.VppError = M4NO_ERROR;
-
- M4OSA_TRACE2_0("E ++++ encode AU");
-
- /**
- * Encode the frame(rendering,filtering and writing will be done
- in encoder callbacks)*/
- if( pC->Vstate == M4VSS3GPP_kEditVideoState_BEGIN_CUT )
- FrameMode = M4ENCODER_kIFrame;
- else
- FrameMode = M4ENCODER_kNormalFrame;
-
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctEncode(pC->ewc.pEncContext, M4OSA_NULL,
- pC->ewc.dInputVidCts, FrameMode);
- /**
- * Check if we had a VPP error... */
- if( M4NO_ERROR != pC->ewc.VppError )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: DECODE_ENCODE:\
- pVideoEncoderGlobalFcts->pFctEncode, returning VppErr=0x%x",
- pC->ewc.VppError);
-#ifdef M4VSS_SUPPORT_OMX_CODECS
-
- if( M4WAR_VIDEORENDERER_NO_NEW_FRAME != pC->ewc.VppError )
- {
-#endif //M4VSS_SUPPORT_OMX_CODECS
-
- return pC->ewc.VppError;
-#ifdef M4VSS_SUPPORT_OMX_CODECS
-
- }
-
-#endif //M4VSS_SUPPORT_OMX_CODECS
- }
- else if( M4NO_ERROR != err ) /**< ...or an encoder error */
- {
- if( ((M4OSA_UInt32)M4ERR_ALLOC) == err )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intEditStepVideo: DECODE_ENCODE:\
- returning M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR");
- return M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR;
- }
- /* the warning M4WAR_WRITER_STOP_REQ is returned when the targeted output
- file size is reached
- The editing is then finished, the warning M4VSS3GPP_WAR_EDITING_DONE
- is returned*/
- else if( M4WAR_WRITER_STOP_REQ == err )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intEditStepVideo: File was cut to avoid oversize");
- return M4VSS3GPP_WAR_EDITING_DONE;
- }
- else
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: DECODE_ENCODE:\
- pVideoEncoderGlobalFcts->pFctEncode returns 0x%x",
- err);
- return err;
- }
- }
-
- /**
- * Increment time by the encoding period (for begin cut, do not increment to not
- loose P-frames) */
- if( M4VSS3GPP_kEditVideoState_DECODE_ENCODE == pC->Vstate )
- {
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->ewc.dInputVidCts += pC->dOutputFrameDuration;
- }
- }
- break;
-
- /* _________________ */
- /*| |*/
- /*| TRANSITION MODE |*/
- /*|_________________|*/
-
- case M4VSS3GPP_kEditVideoState_TRANSITION:
- {
- M4OSA_TRACE3_0("M4VSS3GPP_intEditStepVideo TRANSITION");
-
- /* Don't decode more than needed */
- if( !(( M4VSS3GPP_kClipStatus_DECODE_UP_TO != pC->pC1->Vstatus)
- && (M4VSS3GPP_kClipStatus_DECODE_UP_TO == pC->pC2->Vstatus)) )
- {
- /**
- * Decode the clip1 video up to the target time
- (will jump to the previous RAP if needed */
- if ((pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (M4OSA_FALSE ==
- pC->pC1->pSettings->ClipProperties.bSetImageData)) {
-
- err = M4VSS3GPP_intSetYuv420PlaneFromARGB888(pC, pC->pC1);
- if( M4NO_ERROR != err ) {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- M4VSS3GPP_intSetYuv420PlaneFromARGB888 err=%x", err);
- return err;
- }
- }
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- err = M4VSS3GPP_intClipDecodeVideoUpToCts(pC->pC1,
- (M4OSA_Int32)pC->ewc.dInputVidCts);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- M4VSS3GPP_intDecodeVideoUpToCts(C1) returns err=0x%x",
- err);
- return err;
- }
-
- /* If the decoding is not completed, do one more step with time frozen */
- if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pC->pC1->Vstatus )
- {
- return M4NO_ERROR;
- }
- }
-
- /* Don't decode more than needed */
- if( !(( M4VSS3GPP_kClipStatus_DECODE_UP_TO != pC->pC2->Vstatus)
- && (M4VSS3GPP_kClipStatus_DECODE_UP_TO == pC->pC1->Vstatus)) )
- {
- /**
- * Decode the clip2 video up to the target time
- (will jump to the previous RAP if needed) */
- if ((pC->pC2->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (M4OSA_FALSE ==
- pC->pC2->pSettings->ClipProperties.bSetImageData)) {
-
- err = M4VSS3GPP_intSetYuv420PlaneFromARGB888(pC, pC->pC2);
- if( M4NO_ERROR != err ) {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- M4VSS3GPP_intSetYuv420PlaneFromARGB888 err=%x", err);
- return err;
- }
- }
-
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- err = M4VSS3GPP_intClipDecodeVideoUpToCts(pC->pC2,
- (M4OSA_Int32)pC->ewc.dInputVidCts);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- M4VSS3GPP_intDecodeVideoUpToCts(C2) returns err=0x%x",
- err);
- return err;
- }
-
- /* If the decoding is not completed, do one more step with time frozen */
- if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pC->pC2->Vstatus )
- {
- return M4NO_ERROR;
- }
- }
-
- /**
- * Reset the video pre-processing error before calling the encoder */
- pC->ewc.VppError = M4NO_ERROR;
-
- M4OSA_TRACE2_0("F **** blend AUs");
-
- /**
- * Encode the frame (rendering, filtering and writing will be done
- in encoder callbacks */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctEncode(pC->ewc.pEncContext, M4OSA_NULL,
- pC->ewc.dInputVidCts, M4ENCODER_kNormalFrame);
-
- /**
- * If encode returns a process frame error, it is likely to be a VPP error */
- if( M4NO_ERROR != pC->ewc.VppError )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- pVideoEncoderGlobalFcts->pFctEncode, returning VppErr=0x%x",
- pC->ewc.VppError);
-#ifdef M4VSS_SUPPORT_OMX_CODECS
-
- if( M4WAR_VIDEORENDERER_NO_NEW_FRAME != pC->ewc.VppError )
- {
-
-#endif //M4VSS_SUPPORT_OMX_CODECS
-
- return pC->ewc.VppError;
-#ifdef M4VSS_SUPPORT_OMX_CODECS
-
- }
-
-#endif //M4VSS_SUPPORT_OMX_CODECS
- }
- else if( M4NO_ERROR != err ) /**< ...or an encoder error */
- {
- if( ((M4OSA_UInt32)M4ERR_ALLOC) == err )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- returning M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR");
- return M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR;
- }
-
- /* the warning M4WAR_WRITER_STOP_REQ is returned when the targeted output
- file size is reached
- The editing is then finished, the warning M4VSS3GPP_WAR_EDITING_DONE is
- returned*/
- else if( M4WAR_WRITER_STOP_REQ == err )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intEditStepVideo: File was cut to avoid oversize");
- return M4VSS3GPP_WAR_EDITING_DONE;
- }
- else
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: TRANSITION:\
- pVideoEncoderGlobalFcts->pFctEncode returns 0x%x",
- err);
- return err;
- }
- }
-
- /**
- * Increment time by the encoding period */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->ewc.dInputVidCts += pC->dOutputFrameDuration;
- }
- break;
-
- /* ____________ */
- /*| |*/
- /*| ERROR CASE |*/
- /*|____________|*/
-
- default:
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intEditStepVideo: invalid internal state (0x%x),\
- returning M4VSS3GPP_ERR_INTERNAL_STATE",
- pC->Vstate);
- return M4VSS3GPP_ERR_INTERNAL_STATE;
- }
-
- /**
- * Return with no error */
- M4OSA_TRACE3_0("M4VSS3GPP_intEditStepVideo: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intCheckVideoMode()
- * @brief Check which video process mode we must use, depending on the output CTS.
- * @param pC (IN/OUT) Internal edit context
- ******************************************************************************
- */
-static M4OSA_ERR M4VSS3GPP_intCheckVideoMode(
- M4VSS3GPP_InternalEditContext *pC )
-{
- M4OSA_ERR err;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- const M4OSA_Int32 t = (M4OSA_Int32)pC->ewc.dInputVidCts;
- /**< Transition duration */
- const M4OSA_Int32 TD = pC->pTransitionList[pC->uiCurrentClip].uiTransitionDuration;
-
- M4OSA_Int32 iTmp;
-
- const M4VSS3GPP_EditVideoState previousVstate = pC->Vstate;
-
- /**
- * Check if Clip1 is on its begin cut, or in an effect zone */
- M4VSS3GPP_intCheckVideoEffects(pC, 1);
-
- /**
- * Check if we are in the transition with next clip */
- if( ( TD > 0) && (( t - pC->pC1->iVoffset) >= (pC->pC1->iEndTime - TD)) )
- {
- /**
- * We are in a transition */
- pC->Vstate = M4VSS3GPP_kEditVideoState_TRANSITION;
- pC->bTransitionEffect = M4OSA_TRUE;
-
- /**
- * Open second clip for transition, if not yet opened */
- if( M4OSA_NULL == pC->pC2 )
- {
- pC->pC1->bGetYuvDataFromDecoder = M4OSA_TRUE;
-
- err = M4VSS3GPP_intOpenClip(pC, &pC->pC2,
- &pC->pClipList[pC->uiCurrentClip + 1]);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCheckVideoMode: M4VSS3GPP_editOpenClip returns 0x%x!",
- err);
- return err;
- }
-
- /**
- * Add current video output CTS to the clip offset
- * (audio output CTS is not yet at the transition, so audio
- * offset can't be updated yet). */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->pC2->iVoffset += (M4OSA_UInt32)pC->ewc.dInputVidCts;
-
- /**
- * 2005-03-24: BugFix for audio-video synchro:
- * Update transition duration due to the actual video transition beginning time.
- * It will avoid desynchronization when doing the audio transition. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- iTmp = ((M4OSA_Int32)pC->ewc.dInputVidCts)\
- - (pC->pC1->iEndTime - TD + pC->pC1->iVoffset);
- if (iTmp < (M4OSA_Int32)pC->pTransitionList[pC->uiCurrentClip].uiTransitionDuration)
- /**< Test in case of a very short transition */
- {
- pC->pTransitionList[pC->
- uiCurrentClip].uiTransitionDuration -= iTmp;
-
- /**
- * Don't forget to also correct the total duration used for the progress bar
- * (it was computed with the original transition duration). */
- pC->ewc.iOutputDuration += iTmp;
- }
- /**< No "else" here because it's hard predict the effect of 0 duration transition...*/
- }
-
- /**
- * Check effects for clip2 */
- M4VSS3GPP_intCheckVideoEffects(pC, 2);
- }
- else
- {
- /**
- * We are not in a transition */
- pC->bTransitionEffect = M4OSA_FALSE;
-
- /* If there is an effect we go to decode/encode mode */
- if((pC->nbActiveEffects > 0) || (pC->nbActiveEffects1 > 0) ||
- (pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) ||
- (pC->pC1->pSettings->bTranscodingRequired == M4OSA_TRUE)) {
- pC->Vstate = M4VSS3GPP_kEditVideoState_DECODE_ENCODE;
- }
- /* We do a begin cut, except if already done (time is not progressing because we want
- to catch all P-frames after the cut) */
- else if( M4OSA_TRUE == pC->bClip1AtBeginCut )
- {
- 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 {
- pC->Vstate = M4VSS3GPP_kEditVideoState_BEGIN_CUT;
- }
- }
- /* Else we are in default copy/paste mode */
- else
- {
- if( ( M4VSS3GPP_kEditVideoState_BEGIN_CUT == previousVstate)
- || (M4VSS3GPP_kEditVideoState_AFTER_CUT == previousVstate) )
- {
- pC->Vstate = M4VSS3GPP_kEditVideoState_AFTER_CUT;
- }
- else if( pC->bIsMMS == M4OSA_TRUE )
- {
- M4OSA_UInt32 currentBitrate;
- M4OSA_ERR err = M4NO_ERROR;
-
- /* Do we need to reencode the video to downgrade the bitrate or not ? */
- /* Let's compute the cirrent bitrate of the current edited clip */
- err = pC->pC1->ShellAPI.m_pReader->m_pFctGetOption(
- pC->pC1->pReaderContext,
- M4READER_kOptionID_Bitrate, &currentBitrate);
-
- if( err != M4NO_ERROR )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCheckVideoMode:\
- Error when getting next bitrate of edited clip: 0x%x",
- err);
- return err;
- }
-
- /* Remove audio bitrate */
- currentBitrate -= 12200;
-
- /* Test if we go into copy/paste mode or into decode/encode mode */
- if( currentBitrate > pC->uiMMSVideoBitrate )
- {
- pC->Vstate = M4VSS3GPP_kEditVideoState_DECODE_ENCODE;
- }
- else
- {
- pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE;
- }
- }
- else if(!((pC->m_bClipExternalHasStarted == M4OSA_TRUE) &&
- (pC->Vstate == M4VSS3GPP_kEditVideoState_DECODE_ENCODE)) &&
- pC->bEncodeTillEoF == M4OSA_FALSE)
- {
- /**
- * Test if we go into copy/paste mode or into decode/encode mode
- * If an external effect has been applied on the current clip
- * then continue to be in decode/encode mode till end of
- * clip to avoid H.264 distortion.
- */
- pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE;
- }
- }
- }
-
- /**
- * Check if we create an encoder */
- if( ( ( M4VSS3GPP_kEditVideoState_READ_WRITE == previousVstate)
- || (M4VSS3GPP_kEditVideoState_AFTER_CUT
- == previousVstate)) /**< read mode */
- && (( M4VSS3GPP_kEditVideoState_DECODE_ENCODE == pC->Vstate)
- || (M4VSS3GPP_kEditVideoState_BEGIN_CUT == pC->Vstate)
- || (M4VSS3GPP_kEditVideoState_TRANSITION
- == pC->Vstate)) /**< encode mode */
- && pC->bIsMMS == M4OSA_FALSE )
- {
- /**
- * Create the encoder, if not created already*/
- if (pC->ewc.encoderState == M4VSS3GPP_kNoEncoder) {
- err = M4VSS3GPP_intCreateVideoEncoder(pC);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCheckVideoMode: M4VSS3GPP_intCreateVideoEncoder \
- returns 0x%x!", err);
- return err;
- }
- }
- }
- else if( pC->bIsMMS == M4OSA_TRUE && pC->ewc.pEncContext == M4OSA_NULL )
- {
- /**
- * Create the encoder */
- err = M4VSS3GPP_intCreateVideoEncoder(pC);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCheckVideoMode: M4VSS3GPP_intCreateVideoEncoder returns 0x%x!",
- err);
- return err;
- }
- }
-
- /**
- * When we go from filtering to read/write, we must act like a begin cut,
- * because the last filtered image may be different than the original image. */
- else if( ( ( M4VSS3GPP_kEditVideoState_DECODE_ENCODE == previousVstate)
- || (M4VSS3GPP_kEditVideoState_TRANSITION
- == previousVstate)) /**< encode mode */
- && (M4VSS3GPP_kEditVideoState_READ_WRITE == pC->Vstate) /**< read mode */
- && (pC->bEncodeTillEoF == M4OSA_FALSE) )
- {
- pC->Vstate = M4VSS3GPP_kEditVideoState_BEGIN_CUT;
- }
-
- /**
- * Check if we destroy an encoder */
- else if( ( ( M4VSS3GPP_kEditVideoState_DECODE_ENCODE == previousVstate)
- || (M4VSS3GPP_kEditVideoState_BEGIN_CUT == previousVstate)
- || (M4VSS3GPP_kEditVideoState_TRANSITION
- == previousVstate)) /**< encode mode */
- && (( M4VSS3GPP_kEditVideoState_READ_WRITE == pC->Vstate)
- || (M4VSS3GPP_kEditVideoState_AFTER_CUT
- == pC->Vstate)) /**< read mode */
- && pC->bIsMMS == M4OSA_FALSE )
- {
- /**
- * Destroy the previously created encoder */
- err = M4VSS3GPP_intDestroyVideoEncoder(pC);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCheckVideoMode: M4VSS3GPP_intDestroyVideoEncoder returns 0x%x!",
- err);
- return err;
- }
- }
-
- /**
- * Return with no error */
- M4OSA_TRACE3_0("M4VSS3GPP_intCheckVideoMode: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intStartAU()
- * @brief StartAU writer-like interface used for the VSS 3GPP only
- * @note
- * @param pContext: (IN) It is the VSS 3GPP context in our case
- * @param streamID: (IN) Id of the stream to which the Access Unit is related.
- * @param pAU: (IN/OUT) Access Unit to be prepared.
- * @return M4NO_ERROR: there is no error
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intStartAU( M4WRITER_Context pContext,
- M4SYS_StreamID streamID, M4SYS_AccessUnit *pAU )
-{
- M4OSA_ERR err;
- M4OSA_UInt32 uiMaxAuSize;
-
- /**
- * Given context is actually the VSS3GPP context */
- M4VSS3GPP_InternalEditContext *pC =
- (M4VSS3GPP_InternalEditContext *)pContext;
-
- /**
- * Get the output AU to write into */
- err = pC->ShellAPI.pWriterDataFcts->pStartAU(pC->ewc.p3gpWriterContext,
- M4VSS3GPP_WRITER_VIDEO_STREAM_ID, pAU);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intStartAU: pWriterDataFcts->pStartAU(Video) returns 0x%x!",
- err);
- return err;
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intStartAU: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intProcessAU()
- * @brief ProcessAU writer-like interface used for the VSS 3GPP only
- * @note
- * @param pContext: (IN) It is the VSS 3GPP context in our case
- * @param streamID: (IN) Id of the stream to which the Access Unit is related.
- * @param pAU: (IN/OUT) Access Unit to be written
- * @return M4NO_ERROR: there is no error
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intProcessAU( M4WRITER_Context pContext,
- M4SYS_StreamID streamID, M4SYS_AccessUnit *pAU )
-{
- M4OSA_ERR err;
-
- /**
- * Given context is actually the VSS3GPP context */
- M4VSS3GPP_InternalEditContext *pC =
- (M4VSS3GPP_InternalEditContext *)pContext;
-
- /**
- * Fix the encoded AU time */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- pC->ewc.dOutputVidCts = pAU->CTS;
- /**
- * Update time info for the Counter Time System to be equal to the bit-stream time */
- M4VSS3GPP_intUpdateTimeInfo(pC, pAU);
-
- /**
- * Write the AU */
- err = pC->ShellAPI.pWriterDataFcts->pProcessAU(pC->ewc.p3gpWriterContext,
- M4VSS3GPP_WRITER_VIDEO_STREAM_ID, pAU);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intProcessAU: pWriterDataFcts->pProcessAU(Video) returns 0x%x!",
- err);
- return err;
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intProcessAU: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intVPP()
- * @brief We implement our own VideoPreProcessing function
- * @note It is called by the video encoder
- * @param pContext (IN) VPP context, which actually is the VSS 3GPP context in our case
- * @param pPlaneIn (IN)
- * @param pPlaneOut (IN/OUT) Pointer to an array of 3 planes that will contain the output
- * YUV420 image
- * @return M4NO_ERROR: No error
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intVPP( M4VPP_Context pContext, M4VIFI_ImagePlane *pPlaneIn,
- M4VIFI_ImagePlane *pPlaneOut )
-{
- M4OSA_ERR err = M4NO_ERROR;
- M4_MediaTime ts;
- M4VIFI_ImagePlane *pTmp = M4OSA_NULL;
- M4VIFI_ImagePlane *pLastDecodedFrame = M4OSA_NULL ;
- M4VIFI_ImagePlane *pDecoderRenderFrame = M4OSA_NULL;
- M4VIFI_ImagePlane pTemp1[3],pTemp2[3];
- M4VIFI_ImagePlane pTempPlaneClip1[3],pTempPlaneClip2[3];
- M4OSA_UInt32 i = 0, yuvFrameWidth = 0, yuvFrameHeight = 0;
- M4OSA_Bool bSkipFrameEffect = M4OSA_FALSE;
- /**
- * VPP context is actually the VSS3GPP context */
- M4VSS3GPP_InternalEditContext *pC =
- (M4VSS3GPP_InternalEditContext *)pContext;
-
- memset((void *)pTemp1, 0, 3*sizeof(M4VIFI_ImagePlane));
- memset((void *)pTemp2, 0, 3*sizeof(M4VIFI_ImagePlane));
- memset((void *)pTempPlaneClip1, 0, 3*sizeof(M4VIFI_ImagePlane));
- memset((void *)pTempPlaneClip2, 0, 3*sizeof(M4VIFI_ImagePlane));
-
- /**
- * Reset VPP error remembered in context */
- pC->ewc.VppError = M4NO_ERROR;
-
- /**
- * At the end of the editing, we may be called when no more clip is loaded.
- * (because to close the encoder properly it must be stepped one or twice...) */
- if( M4OSA_NULL == pC->pC1 )
- {
- /**
- * We must fill the input of the encoder with a dummy image, because
- * encoding noise leads to a huge video AU, and thus a writer buffer overflow. */
- memset((void *)pPlaneOut[0].pac_data,0,
- pPlaneOut[0].u_stride * pPlaneOut[0].u_height);
- memset((void *)pPlaneOut[1].pac_data,0,
- pPlaneOut[1].u_stride * pPlaneOut[1].u_height);
- memset((void *)pPlaneOut[2].pac_data,0,
- pPlaneOut[2].u_stride * pPlaneOut[2].u_height);
-
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: returning M4NO_ERROR (abort)");
- return M4NO_ERROR;
- }
-
- /**
- **************** Transition case ****************/
- if( M4OSA_TRUE == pC->bTransitionEffect )
- {
-
- err = M4VSS3GPP_intAllocateYUV420(pTemp1, pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if (M4NO_ERROR != err)
- {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420(1) returns 0x%x, \
- returning M4NO_ERROR", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
-
- err = M4VSS3GPP_intAllocateYUV420(pTemp2, pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if (M4NO_ERROR != err)
- {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420(2) returns 0x%x, \
- returning M4NO_ERROR", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
-
- err = M4VSS3GPP_intAllocateYUV420(pC->yuv1, pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420(3) returns 0x%x,\
- returning M4NO_ERROR",
- err);
- pC->ewc.VppError = err;
- return
- M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
-
- err = M4VSS3GPP_intAllocateYUV420(pC->yuv2, pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420(4) returns 0x%x,\
- returning M4NO_ERROR",
- err);
- pC->ewc.VppError = err;
- return
- M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
-
- err = M4VSS3GPP_intAllocateYUV420(pC->yuv3, pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420(3) returns 0x%x,\
- returning M4NO_ERROR",
- err);
- pC->ewc.VppError = err;
- return
- M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
-
- /**
- * Compute the time in the clip1 base: ts = to - Offset */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- ts = pC->ewc.dInputVidCts - pC->pC1->iVoffset;
-
- /**
- * Render Clip1 */
- if( pC->pC1->isRenderDup == M4OSA_FALSE )
- {
- err = M4VSS3GPP_intRenderFrameWithEffect(pC, pC->pC1, ts, M4OSA_TRUE,
- pTempPlaneClip1, pTemp1,
- pPlaneOut);
- if ((M4NO_ERROR != err) &&
- (M4WAR_VIDEORENDERER_NO_NEW_FRAME != err)) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intRenderFrameWithEffect returns 0x%x", err);
- pC->ewc.VppError = err;
- /** Return no error to the encoder core
- * else it may leak in some situations.*/
- return M4NO_ERROR;
- }
- }
- if ((pC->pC1->isRenderDup == M4OSA_TRUE) ||
- (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)) {
- pTmp = pC->yuv1;
- if (pC->pC1->lastDecodedPlane != M4OSA_NULL) {
- /* Copy last decoded plane to output plane */
- memcpy((void *)pTmp[0].pac_data,
- (void *)pC->pC1->lastDecodedPlane[0].pac_data,
- (pTmp[0].u_height * pTmp[0].u_width));
- memcpy((void *)pTmp[1].pac_data,
- (void *)pC->pC1->lastDecodedPlane[1].pac_data,
- (pTmp[1].u_height * pTmp[1].u_width));
- memcpy((void *)pTmp[2].pac_data,
- (void *)pC->pC1->lastDecodedPlane[2].pac_data,
- (pTmp[2].u_height * pTmp[2].u_width));
- } else {
- err = M4VSS3GPP_ERR_NO_VALID_VID_FRAME;
- M4OSA_TRACE1_3("Can not find an input frame. Set error 0x%x in %s (%d)",
- err, __FILE__, __LINE__);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pC->pC1->lastDecodedPlane = pTmp;
- }
-
- /**
- * Compute the time in the clip2 base: ts = to - Offset */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- ts = pC->ewc.dInputVidCts - pC->pC2->iVoffset;
- /**
- * Render Clip2 */
- if( pC->pC2->isRenderDup == M4OSA_FALSE )
- {
-
- err = M4VSS3GPP_intRenderFrameWithEffect(pC, pC->pC2, ts, M4OSA_FALSE,
- pTempPlaneClip2, pTemp2,
- pPlaneOut);
- if ((M4NO_ERROR != err) &&
- (M4WAR_VIDEORENDERER_NO_NEW_FRAME != err)) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intRenderFrameWithEffect returns 0x%x", err);
- pC->ewc.VppError = err;
- /** Return no error to the encoder core
- * else it may leak in some situations.*/
- return M4NO_ERROR;
- }
- }
- if ((pC->pC2->isRenderDup == M4OSA_TRUE) ||
- (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)) {
- pTmp = pC->yuv2;
- if (pC->pC2->lastDecodedPlane != M4OSA_NULL) {
- /* Copy last decoded plane to output plane */
- memcpy((void *)pTmp[0].pac_data,
- (void *)pC->pC2->lastDecodedPlane[0].pac_data,
- (pTmp[0].u_height * pTmp[0].u_width));
- memcpy((void *)pTmp[1].pac_data,
- (void *)pC->pC2->lastDecodedPlane[1].pac_data,
- (pTmp[1].u_height * pTmp[1].u_width));
- memcpy((void *)pTmp[2].pac_data,
- (void *)pC->pC2->lastDecodedPlane[2].pac_data,
- (pTmp[2].u_height * pTmp[2].u_width));
- } else {
- err = M4VSS3GPP_ERR_NO_VALID_VID_FRAME;
- M4OSA_TRACE1_3("Can not find an input frame. Set error 0x%x in %s (%d)",
- err, __FILE__, __LINE__);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pC->pC2->lastDecodedPlane = pTmp;
- }
-
-
- pTmp = pPlaneOut;
- err = M4VSS3GPP_intVideoTransition(pC, pTmp);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVPP: M4VSS3GPP_intVideoTransition returns 0x%x,\
- returning M4NO_ERROR",
- err);
- pC->ewc.VppError = err;
- return M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
- for (i=0; i < 3; i++)
- {
- if(pTempPlaneClip2[i].pac_data != M4OSA_NULL) {
- free(pTempPlaneClip2[i].pac_data);
- pTempPlaneClip2[i].pac_data = M4OSA_NULL;
- }
-
- if(pTempPlaneClip1[i].pac_data != M4OSA_NULL) {
- free(pTempPlaneClip1[i].pac_data);
- pTempPlaneClip1[i].pac_data = M4OSA_NULL;
- }
-
- if (pTemp2[i].pac_data != M4OSA_NULL) {
- free(pTemp2[i].pac_data);
- pTemp2[i].pac_data = M4OSA_NULL;
- }
-
- if (pTemp1[i].pac_data != M4OSA_NULL) {
- free(pTemp1[i].pac_data);
- pTemp1[i].pac_data = M4OSA_NULL;
- }
- }
- }
- /**
- **************** No Transition case ****************/
- else
- {
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: NO transition case");
- /**
- * Compute the time in the clip base: ts = to - Offset */
- ts = pC->ewc.dInputVidCts - pC->pC1->iVoffset;
- pC->bIssecondClip = M4OSA_FALSE;
- /**
- * Render */
- if (pC->pC1->isRenderDup == M4OSA_FALSE) {
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: renderdup false");
- /**
- * Check if resizing is needed */
- if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame) {
- if ((pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (pC->nbActiveEffects == 0) &&
- (pC->pC1->bGetYuvDataFromDecoder == M4OSA_FALSE)) {
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pC->pC1->pViDecCtxt,
- M4DECODER_kOptionID_EnableYuvWithEffect,
- (M4OSA_DataOption)M4OSA_TRUE);
- if (M4NO_ERROR == err ) {
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pC->pC1->pViDecCtxt, &ts,
- pPlaneOut, M4OSA_TRUE);
- }
- } else {
- if (pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) {
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pC->pC1->pViDecCtxt,
- M4DECODER_kOptionID_EnableYuvWithEffect,
- (M4OSA_DataOption)M4OSA_FALSE);
- }
- if (M4NO_ERROR == err) {
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pC->pC1->pViDecCtxt, &ts,
- pC->pC1->m_pPreResizeFrame, M4OSA_TRUE);
- }
- }
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- m_pFctRender() returns error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- if (pC->pC1->pSettings->FileType !=
- M4VIDEOEDITING_kFileType_ARGB8888) {
- if (0 != pC->pC1->pSettings->ClipProperties.videoRotationDegrees) {
- // Save width and height of un-rotated frame
- yuvFrameWidth = pC->pC1->m_pPreResizeFrame[0].u_width;
- yuvFrameHeight = pC->pC1->m_pPreResizeFrame[0].u_height;
- err = M4VSS3GPP_intRotateVideo(pC->pC1->m_pPreResizeFrame,
- pC->pC1->pSettings->ClipProperties.videoRotationDegrees);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- rotateVideo() returns error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
- }
-
- if (pC->nbActiveEffects > 0) {
- pC->pC1->bGetYuvDataFromDecoder = M4OSA_TRUE;
- /**
- * If we do modify the image, we need an intermediate
- * image plane */
- err = M4VSS3GPP_intAllocateYUV420(pTemp1,
- pC->pC1->m_pPreResizeFrame[0].u_width,
- pC->pC1->m_pPreResizeFrame[0].u_height);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intAllocateYUV420 error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- /* If video frame need to be resized, then apply the overlay after
- * the frame was rendered with rendering mode.
- * Here skip the framing(overlay) effect when applying video Effect. */
- bSkipFrameEffect = M4OSA_TRUE;
- err = M4VSS3GPP_intApplyVideoEffect(pC,
- pC->pC1->m_pPreResizeFrame, pTemp1, bSkipFrameEffect);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intApplyVideoEffect() error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pDecoderRenderFrame= pTemp1;
-
- } else {
- pDecoderRenderFrame = pC->pC1->m_pPreResizeFrame;
- }
- /* Prepare overlay temporary buffer if overlay exist */
- if (pC->bClip1ActiveFramingEffect) {
- err = M4VSS3GPP_intAllocateYUV420(pTemp2,
- pPlaneOut[0].u_width, pPlaneOut[0].u_height);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420 \
- returns 0x%x, returning M4NO_ERROR", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pTmp = pTemp2;
- } else {
- pTmp = pPlaneOut;
- }
-
- /* Do rendering mode. */
- if ((pC->pC1->bGetYuvDataFromDecoder == M4OSA_TRUE) ||
- (pC->pC1->pSettings->FileType !=
- M4VIDEOEDITING_kFileType_ARGB8888)) {
-
- err = M4VSS3GPP_intApplyRenderingMode(pC,
- pC->pC1->pSettings->xVSS.MediaRendering,
- pDecoderRenderFrame, pTmp);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intApplyRenderingMode) error 0x%x ", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
-
- /* Apply overlay if overlay is exist */
- if (pC->bClip1ActiveFramingEffect) {
- pDecoderRenderFrame = pTmp;
- pTmp = pPlaneOut;
- err = M4VSS3GPP_intApplyVideoOverlay(pC,
- pDecoderRenderFrame, pTmp);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intApplyVideoOverlay) error 0x%x ", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
-
- if ((pC->pC1->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (pC->nbActiveEffects == 0) &&
- (pC->pC1->bGetYuvDataFromDecoder == M4OSA_TRUE)) {
-
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pC->pC1->pViDecCtxt,
- M4DECODER_kOptionID_YuvWithEffectNonContiguous,
- (M4OSA_DataOption)pTmp);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pC->pC1->bGetYuvDataFromDecoder = M4OSA_FALSE;
- }
-
- // Reset original width and height for resize frame plane
- if (0 != pC->pC1->pSettings->ClipProperties.videoRotationDegrees &&
- 180 != pC->pC1->pSettings->ClipProperties.videoRotationDegrees) {
-
- M4VSS3GPP_intSetYUV420Plane(pC->pC1->m_pPreResizeFrame,
- yuvFrameWidth, yuvFrameHeight);
- }
- }
- else
- {
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: NO resize required");
- if (pC->nbActiveEffects > 0) {
- /** If we do modify the image, we need an
- * intermediate image plane */
- err = M4VSS3GPP_intAllocateYUV420(pTemp1,
- pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pDecoderRenderFrame = pTemp1;
- }
- else {
- pDecoderRenderFrame = pPlaneOut;
- }
-
- pTmp = pPlaneOut;
- err = pC->pC1->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pC->pC1->pViDecCtxt, &ts,
- pDecoderRenderFrame, M4OSA_TRUE);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
-
- if (pC->nbActiveEffects > 0) {
- /* Here we do not skip the overlay effect since
- * overlay and video frame are both of same resolution */
- bSkipFrameEffect = M4OSA_FALSE;
- err = M4VSS3GPP_intApplyVideoEffect(pC,
- pDecoderRenderFrame,pPlaneOut,bSkipFrameEffect);
- }
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
- pC->pC1->lastDecodedPlane = pTmp;
- pC->pC1->iVideoRenderCts = (M4OSA_Int32)ts;
-
- } else {
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: renderdup true");
-
- if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame) {
- /**
- * Copy last decoded plane to output plane */
- if (pC->pC1->lastDecodedPlane != M4OSA_NULL) {
-
- memcpy((void *)pC->pC1->m_pPreResizeFrame[0].pac_data,
- (void *)pC->pC1->lastDecodedPlane[0].pac_data,
- (pC->pC1->m_pPreResizeFrame[0].u_height * \
- pC->pC1->m_pPreResizeFrame[0].u_width));
-
- memcpy((void *)pC->pC1->m_pPreResizeFrame[1].pac_data,
- (void *)pC->pC1->lastDecodedPlane[1].pac_data,
- (pC->pC1->m_pPreResizeFrame[1].u_height * \
- pC->pC1->m_pPreResizeFrame[1].u_width));
-
- memcpy((void *)pC->pC1->m_pPreResizeFrame[2].pac_data,
- (void *)pC->pC1->lastDecodedPlane[2].pac_data,
- (pC->pC1->m_pPreResizeFrame[2].u_height * \
- pC->pC1->m_pPreResizeFrame[2].u_width));
- } else {
- err = M4VSS3GPP_ERR_NO_VALID_VID_FRAME;
- M4OSA_TRACE1_3("Can not find an input frame. Set error 0x%x in %s (%d)",
- err, __FILE__, __LINE__);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
-
- if(pC->nbActiveEffects > 0) {
- /**
- * If we do modify the image, we need an
- * intermediate image plane */
- err = M4VSS3GPP_intAllocateYUV420(pTemp1,
- pC->pC1->m_pPreResizeFrame[0].u_width,
- pC->pC1->m_pPreResizeFrame[0].u_height);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- /* If video frame need to be resized, then apply the overlay after
- * the frame was rendered with rendering mode.
- * Here skip the framing(overlay) effect when applying video Effect. */
- bSkipFrameEffect = M4OSA_TRUE;
- err = M4VSS3GPP_intApplyVideoEffect(pC,
- pC->pC1->m_pPreResizeFrame,pTemp1, bSkipFrameEffect);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pDecoderRenderFrame= pTemp1;
- } else {
- pDecoderRenderFrame = pC->pC1->m_pPreResizeFrame;
- }
- /* Prepare overlay temporary buffer if overlay exist */
- if (pC->bClip1ActiveFramingEffect) {
- err = M4VSS3GPP_intAllocateYUV420(
- pTemp2, pC->ewc.uiVideoWidth, pC->ewc.uiVideoHeight);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: M4VSS3GPP_intAllocateYUV420 \
- returns 0x%x, returning M4NO_ERROR", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pTmp = pTemp2;
- } else {
- pTmp = pPlaneOut;
- }
- /* Do rendering mode */
- err = M4VSS3GPP_intApplyRenderingMode(pC,
- pC->pC1->pSettings->xVSS.MediaRendering,
- pDecoderRenderFrame, pTmp);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- /* Apply overlay if overlay is exist */
- pTmp = pPlaneOut;
- if (pC->bClip1ActiveFramingEffect) {
- err = M4VSS3GPP_intApplyVideoOverlay(pC,
- pTemp2, pTmp);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intApplyRenderingMode) error 0x%x ", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
- } else {
-
- err = M4VSS3GPP_intAllocateYUV420(pTemp1,
- pC->ewc.uiVideoWidth,
- pC->ewc.uiVideoHeight);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- /**
- * Copy last decoded plane to output plane */
- if (pC->pC1->lastDecodedPlane != M4OSA_NULL &&
- pLastDecodedFrame != M4OSA_NULL) {
- memcpy((void *)pLastDecodedFrame[0].pac_data,
- (void *)pC->pC1->lastDecodedPlane[0].pac_data,
- (pLastDecodedFrame[0].u_height * pLastDecodedFrame[0].u_width));
-
- memcpy((void *)pLastDecodedFrame[1].pac_data,
- (void *)pC->pC1->lastDecodedPlane[1].pac_data,
- (pLastDecodedFrame[1].u_height * pLastDecodedFrame[1].u_width));
-
- memcpy((void *)pLastDecodedFrame[2].pac_data,
- (void *)pC->pC1->lastDecodedPlane[2].pac_data,
- (pLastDecodedFrame[2].u_height * pLastDecodedFrame[2].u_width));
- } else {
- err = M4VSS3GPP_ERR_NO_VALID_VID_FRAME;
- M4OSA_TRACE1_3("Can not find an input frame. Set error 0x%x in %s (%d)",
- err, __FILE__, __LINE__);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
-
- pTmp = pPlaneOut;
- /**
- * Check if there is a effect */
- if(pC->nbActiveEffects > 0) {
- /* Here we do not skip the overlay effect since
- * overlay and video are both of same resolution */
- bSkipFrameEffect = M4OSA_FALSE;
- err = M4VSS3GPP_intApplyVideoEffect(pC,
- pLastDecodedFrame, pTmp,bSkipFrameEffect);
- if (M4NO_ERROR != err) {
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- }
- }
- pC->pC1->lastDecodedPlane = pTmp;
- }
-
- M4OSA_TRACE3_1("M4VSS3GPP_intVPP: Rendered at CTS %.3f", ts);
-
- for (i=0; i<3; i++) {
- if (pTemp1[i].pac_data != M4OSA_NULL) {
- free(pTemp1[i].pac_data);
- pTemp1[i].pac_data = M4OSA_NULL;
- }
- }
- for (i=0; i<3; i++) {
- if (pTemp2[i].pac_data != M4OSA_NULL) {
- free(pTemp2[i].pac_data);
- pTemp2[i].pac_data = M4OSA_NULL;
- }
- }
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intVPP: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intApplyVideoOverlay()
- * @brief Apply video overlay from pPlaneIn to pPlaneOut
- * @param pC (IN/OUT) Internal edit context
- * @param pInputPlanes (IN) Input raw YUV420 image
- * @param pOutputPlanes (IN/OUT) Output raw YUV420 image
- * @return M4NO_ERROR: No error
- ******************************************************************************
- */
-static M4OSA_ERR
-M4VSS3GPP_intApplyVideoOverlay (M4VSS3GPP_InternalEditContext *pC,
- M4VIFI_ImagePlane *pPlaneIn, M4VIFI_ImagePlane *pPlaneOut) {
-
- M4VSS3GPP_ClipContext *pClip;
- M4VSS3GPP_EffectSettings *pFx;
- M4VSS3GPP_ExternalProgress extProgress;
- M4OSA_Double VideoEffectTime;
- M4OSA_Double PercentageDone;
- M4OSA_UInt8 NumActiveEffects =0;
- M4OSA_UInt32 Cts = 0;
- M4OSA_Int32 nextEffectTime;
- M4OSA_Int32 tmp;
- M4OSA_UInt8 i;
- M4OSA_ERR err;
-
- pClip = pC->pC1;
- if (pC->bIssecondClip == M4OSA_TRUE) {
- NumActiveEffects = pC->nbActiveEffects1;
- } else {
- NumActiveEffects = pC->nbActiveEffects;
- }
- for (i=0; i<NumActiveEffects; i++) {
- if (pC->bIssecondClip == M4OSA_TRUE) {
- pFx = &(pC->pEffectsList[pC->pActiveEffectsList1[i]]);
- /* Compute how far from the beginning of the effect we are, in clip-base time. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- VideoEffectTime = ((M4OSA_Int32)pC->ewc.dInputVidCts) +
- pC->pTransitionList[pC->uiCurrentClip].uiTransitionDuration - pFx->uiStartTime;
- } else {
- pFx = &(pC->pEffectsList[pC->pActiveEffectsList[i]]);
- /* Compute how far from the beginning of the effect we are, in clip-base time. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- VideoEffectTime = ((M4OSA_Int32)pC->ewc.dInputVidCts) - pFx->uiStartTime;
- }
- /* Do the framing(overlay) effect only,
- * skip other color effect which had been applied */
- if (pFx->xVSS.pFramingBuffer == M4OSA_NULL) {
- continue;
- }
-
- /* To calculate %, substract timeIncrement because effect should finish
- * on the last frame which is presented from CTS = eof-timeIncrement till CTS = eof */
- PercentageDone = VideoEffectTime / ((M4OSA_Float)pFx->uiDuration);
-
- if (PercentageDone < 0.0) {
- PercentageDone = 0.0;
- }
- if (PercentageDone > 1.0) {
- PercentageDone = 1.0;
- }
- /**
- * Compute where we are in the effect (scale is 0->1000) */
- tmp = (M4OSA_Int32)(PercentageDone * 1000);
-
- /**
- * Set the progress info provided to the external function */
- extProgress.uiProgress = (M4OSA_UInt32)tmp;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- extProgress.uiOutputTime = (M4OSA_UInt32)pC->ewc.dInputVidCts;
- extProgress.uiClipTime = extProgress.uiOutputTime - pClip->iVoffset;
- extProgress.bIsLast = M4OSA_FALSE;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- nextEffectTime = (M4OSA_Int32)(pC->ewc.dInputVidCts \
- + pC->dOutputFrameDuration);
- if (nextEffectTime >= (M4OSA_Int32)(pFx->uiStartTime + pFx->uiDuration)) {
- extProgress.bIsLast = M4OSA_TRUE;
- }
- err = pFx->ExtVideoEffectFct(pFx->pExtVideoEffectFctCtxt,
- pPlaneIn, pPlaneOut, &extProgress,
- pFx->VideoEffectType - M4VSS3GPP_kVideoEffectType_External);
-
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoOverlay: \
- External video effect function returns 0x%x!",
- err);
- return err;
- }
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intApplyVideoOverlay: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intApplyVideoEffect()
- * @brief Apply video effect from pPlaneIn to pPlaneOut
- * @param pC (IN/OUT) Internal edit context
- * @param uiClip1orClip2 (IN/OUT) 1 for first clip, 2 for second clip
- * @param pInputPlanes (IN) Input raw YUV420 image
- * @param pOutputPlanes (IN/OUT) Output raw YUV420 image
- * @param bSkipFramingEffect (IN) skip framing effect flag
- * @return M4NO_ERROR: No error
- ******************************************************************************
- */
-static M4OSA_ERR
-M4VSS3GPP_intApplyVideoEffect (M4VSS3GPP_InternalEditContext *pC,
- M4VIFI_ImagePlane *pPlaneIn, M4VIFI_ImagePlane *pPlaneOut,
- M4OSA_Bool bSkipFramingEffect) {
-
- M4OSA_ERR err;
-
- M4VSS3GPP_ClipContext *pClip;
- M4VSS3GPP_EffectSettings *pFx;
- M4VSS3GPP_ExternalProgress extProgress;
-
- M4OSA_Double VideoEffectTime;
- M4OSA_Double PercentageDone;
- M4OSA_Int32 tmp;
-
- M4VIFI_ImagePlane *pPlaneTempIn;
- M4VIFI_ImagePlane *pPlaneTempOut;
- M4VIFI_ImagePlane pTempYuvPlane[3];
- M4OSA_UInt8 i;
- M4OSA_UInt8 NumActiveEffects =0;
-
-
- pClip = pC->pC1;
- if (pC->bIssecondClip == M4OSA_TRUE)
- {
- NumActiveEffects = pC->nbActiveEffects1;
- }
- else
- {
- NumActiveEffects = pC->nbActiveEffects;
- }
-
- memset((void *)pTempYuvPlane, 0, 3*sizeof(M4VIFI_ImagePlane));
-
- /**
- * Allocate temporary plane if needed RC */
- if (NumActiveEffects > 1) {
- err = M4VSS3GPP_intAllocateYUV420(pTempYuvPlane, pPlaneOut->u_width,
- pPlaneOut->u_height);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoEffect: M4VSS3GPP_intAllocateYUV420(4) returns 0x%x,\
- returning M4NO_ERROR",
- err);
- pC->ewc.VppError = err;
- return
- M4NO_ERROR; /**< Return no error to the encoder core
- (else it may leak in some situations...) */
- }
- }
-
- if (NumActiveEffects % 2 == 0)
- {
- pPlaneTempIn = pPlaneIn;
- pPlaneTempOut = pTempYuvPlane;
- }
- else
- {
- pPlaneTempIn = pPlaneIn;
- pPlaneTempOut = pPlaneOut;
- }
-
- for (i=0; i<NumActiveEffects; i++)
- {
- if (pC->bIssecondClip == M4OSA_TRUE)
- {
-
-
- pFx = &(pC->pEffectsList[pC->pActiveEffectsList1[i]]);
- /* Compute how far from the beginning of the effect we are, in clip-base time. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- VideoEffectTime = ((M4OSA_Int32)pC->ewc.dInputVidCts) +
- pC->pTransitionList[pC->uiCurrentClip].
- uiTransitionDuration- pFx->uiStartTime;
- }
- else
- {
- pFx = &(pC->pEffectsList[pC->pActiveEffectsList[i]]);
- /* Compute how far from the beginning of the effect we are, in clip-base time. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- VideoEffectTime = ((M4OSA_Int32)pC->ewc.dInputVidCts) - pFx->uiStartTime;
- }
-
-
-
- /* To calculate %, substract timeIncrement because effect should finish on the last frame*/
- /* which is presented from CTS = eof-timeIncrement till CTS = eof */
- PercentageDone = VideoEffectTime
- / ((M4OSA_Float)pFx->uiDuration/*- pC->dOutputFrameDuration*/);
-
- if( PercentageDone < 0.0 )
- PercentageDone = 0.0;
-
- if( PercentageDone > 1.0 )
- PercentageDone = 1.0;
-
- switch( pFx->VideoEffectType )
- {
- case M4VSS3GPP_kVideoEffectType_FadeFromBlack:
- /**
- * Compute where we are in the effect (scale is 0->1024). */
- tmp = (M4OSA_Int32)(PercentageDone * 1024);
-
- /**
- * Apply the darkening effect */
- err =
- M4VFL_modifyLumaWithScale((M4ViComImagePlane *)pPlaneTempIn,
- (M4ViComImagePlane *)pPlaneTempOut, tmp, M4OSA_NULL);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoEffect:\
- M4VFL_modifyLumaWithScale returns error 0x%x,\
- returning M4VSS3GPP_ERR_LUMA_FILTER_ERROR",
- err);
- return M4VSS3GPP_ERR_LUMA_FILTER_ERROR;
- }
- break;
-
- case M4VSS3GPP_kVideoEffectType_FadeToBlack:
- /**
- * Compute where we are in the effect (scale is 0->1024) */
- tmp = (M4OSA_Int32)(( 1.0 - PercentageDone) * 1024);
-
- /**
- * Apply the darkening effect */
- err =
- M4VFL_modifyLumaWithScale((M4ViComImagePlane *)pPlaneTempIn,
- (M4ViComImagePlane *)pPlaneTempOut, tmp, M4OSA_NULL);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoEffect:\
- M4VFL_modifyLumaWithScale returns error 0x%x,\
- returning M4VSS3GPP_ERR_LUMA_FILTER_ERROR",
- err);
- return M4VSS3GPP_ERR_LUMA_FILTER_ERROR;
- }
- break;
-
- default:
- if( pFx->VideoEffectType
- >= M4VSS3GPP_kVideoEffectType_External )
- {
- M4OSA_UInt32 Cts = 0;
- M4OSA_Int32 nextEffectTime;
-
- /**
- * Compute where we are in the effect (scale is 0->1000) */
- tmp = (M4OSA_Int32)(PercentageDone * 1000);
-
- /**
- * Set the progress info provided to the external function */
- extProgress.uiProgress = (M4OSA_UInt32)tmp;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- extProgress.uiOutputTime = (M4OSA_UInt32)pC->ewc.dInputVidCts;
- extProgress.uiClipTime = extProgress.uiOutputTime - pClip->iVoffset;
- extProgress.bIsLast = M4OSA_FALSE;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- nextEffectTime = (M4OSA_Int32)(pC->ewc.dInputVidCts \
- + pC->dOutputFrameDuration);
- if(nextEffectTime >= (M4OSA_Int32)(pFx->uiStartTime + pFx->uiDuration))
- {
- extProgress.bIsLast = M4OSA_TRUE;
- }
- /* Here skip the framing effect,
- * do the framing effect after apply rendering mode */
- if ((pFx->xVSS.pFramingBuffer != M4OSA_NULL) &&
- bSkipFramingEffect == M4OSA_TRUE) {
- memcpy(pPlaneTempOut[0].pac_data, pPlaneTempIn[0].pac_data,
- pPlaneTempIn[0].u_height * pPlaneTempIn[0].u_width);
- memcpy(pPlaneTempOut[1].pac_data, pPlaneTempIn[1].pac_data,
- pPlaneTempIn[1].u_height * pPlaneTempIn[1].u_width);
- memcpy(pPlaneTempOut[2].pac_data, pPlaneTempIn[2].pac_data,
- pPlaneTempIn[2].u_height * pPlaneTempIn[2].u_width);
-
- } else {
- err = pFx->ExtVideoEffectFct(pFx->pExtVideoEffectFctCtxt,
- pPlaneTempIn, pPlaneTempOut, &extProgress,
- pFx->VideoEffectType
- - M4VSS3GPP_kVideoEffectType_External);
- }
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoEffect: \
- External video effect function returns 0x%x!",
- err);
- return err;
- }
- break;
- }
- else
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intApplyVideoEffect: unknown effect type (0x%x),\
- returning M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE",
- pFx->VideoEffectType);
- return M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE;
- }
- }
- /**
- * RC Updates pTempPlaneIn and pTempPlaneOut depending on current effect */
- if (((i % 2 == 0) && (NumActiveEffects % 2 == 0))
- || ((i % 2 != 0) && (NumActiveEffects % 2 != 0)))
- {
- pPlaneTempIn = pTempYuvPlane;
- pPlaneTempOut = pPlaneOut;
- }
- else
- {
- pPlaneTempIn = pPlaneOut;
- pPlaneTempOut = pTempYuvPlane;
- }
- }
-
- for(i=0; i<3; i++) {
- if(pTempYuvPlane[i].pac_data != M4OSA_NULL) {
- free(pTempYuvPlane[i].pac_data);
- pTempYuvPlane[i].pac_data = M4OSA_NULL;
- }
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intApplyVideoEffect: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intVideoTransition()
- * @brief Apply video transition effect pC1+pC2->pPlaneOut
- * @param pC (IN/OUT) Internal edit context
- * @param pOutputPlanes (IN/OUT) Output raw YUV420 image
- * @return M4NO_ERROR: No error
- ******************************************************************************
- */
-static M4OSA_ERR
-M4VSS3GPP_intVideoTransition( M4VSS3GPP_InternalEditContext *pC,
- M4VIFI_ImagePlane *pPlaneOut )
-{
- M4OSA_ERR err;
- M4OSA_Int32 iProgress;
- M4VSS3GPP_ExternalProgress extProgress;
- M4VIFI_ImagePlane *pPlane;
- M4OSA_Int32 i;
- const M4OSA_Int32 iDur = (M4OSA_Int32)pC->
- pTransitionList[pC->uiCurrentClip].uiTransitionDuration;
-
- /**
- * Compute how far from the end cut we are, in clip-base time.
- * It is done with integers because the offset and begin cut have been rounded already. */
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- iProgress = (M4OSA_Int32)((M4OSA_Double)pC->pC1->iEndTime) - pC->ewc.dInputVidCts +
- ((M4OSA_Double)pC->pC1->iVoffset);
- /**
- * We must remove the duration of one frame, else we would almost never reach the end
- * (It's kind of a "pile and intervals" issue). */
- iProgress -= (M4OSA_Int32)pC->dOutputFrameDuration;
-
- if( iProgress < 0 ) /**< Sanity checks */
- {
- iProgress = 0;
- }
-
- /**
- * Compute where we are in the transition, on a base 1000 */
- iProgress = ( ( iDur - iProgress) * 1000) / iDur;
-
- /**
- * Sanity checks */
- if( iProgress < 0 )
- {
- iProgress = 0;
- }
- else if( iProgress > 1000 )
- {
- iProgress = 1000;
- }
-
- switch( pC->pTransitionList[pC->uiCurrentClip].TransitionBehaviour )
- {
- case M4VSS3GPP_TransitionBehaviour_SpeedUp:
- iProgress = ( iProgress * iProgress) / 1000;
- break;
-
- case M4VSS3GPP_TransitionBehaviour_Linear:
- /*do nothing*/
- break;
-
- case M4VSS3GPP_TransitionBehaviour_SpeedDown:
- iProgress = (M4OSA_Int32)(sqrt(iProgress * 1000));
- break;
-
- case M4VSS3GPP_TransitionBehaviour_SlowMiddle:
- if( iProgress < 500 )
- {
- iProgress = (M4OSA_Int32)(sqrt(iProgress * 500));
- }
- else
- {
- iProgress =
- (M4OSA_Int32)(( ( ( iProgress - 500) * (iProgress - 500))
- / 500) + 500);
- }
- break;
-
- case M4VSS3GPP_TransitionBehaviour_FastMiddle:
- if( iProgress < 500 )
- {
- iProgress = (M4OSA_Int32)(( iProgress * iProgress) / 500);
- }
- else
- {
- iProgress = (M4OSA_Int32)(sqrt(( iProgress - 500) * 500) + 500);
- }
- break;
-
- default:
- /*do nothing*/
- break;
- }
-
- switch( pC->pTransitionList[pC->uiCurrentClip].VideoTransitionType )
- {
- case M4VSS3GPP_kVideoTransitionType_CrossFade:
- /**
- * Apply the transition effect */
- err = M4VIFI_ImageBlendingonYUV420(M4OSA_NULL,
- (M4ViComImagePlane *)pC->yuv1,
- (M4ViComImagePlane *)pC->yuv2,
- (M4ViComImagePlane *)pPlaneOut, iProgress);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVideoTransition:\
- M4VIFI_ImageBlendingonYUV420 returns error 0x%x,\
- returning M4VSS3GPP_ERR_TRANSITION_FILTER_ERROR",
- err);
- return M4VSS3GPP_ERR_TRANSITION_FILTER_ERROR;
- }
- break;
-
- case M4VSS3GPP_kVideoTransitionType_None:
- /**
- * This is a stupid-non optimized version of the None transition...
- * We copy the YUV frame */
- if( iProgress < 500 ) /**< first half of transition */
- {
- pPlane = pC->yuv1;
- }
- else /**< second half of transition */
- {
- pPlane = pC->yuv2;
- }
- /**
- * Copy the input YUV frames */
- i = 3;
-
- while( i-- > 0 )
- {
- memcpy((void *)pPlaneOut[i].pac_data,
- (void *)pPlane[i].pac_data,
- pPlaneOut[i].u_stride * pPlaneOut[i].u_height);
- }
- break;
-
- default:
- if( pC->pTransitionList[pC->uiCurrentClip].VideoTransitionType
- >= M4VSS3GPP_kVideoTransitionType_External )
- {
- /**
- * Set the progress info provided to the external function */
- extProgress.uiProgress = (M4OSA_UInt32)iProgress;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- extProgress.uiOutputTime = (M4OSA_UInt32)pC->ewc.dInputVidCts;
- extProgress.uiClipTime = extProgress.uiOutputTime - pC->pC1->iVoffset;
-
- err = pC->pTransitionList[pC->
- uiCurrentClip].ExtVideoTransitionFct(
- pC->pTransitionList[pC->
- uiCurrentClip].pExtVideoTransitionFctCtxt,
- pC->yuv1, pC->yuv2, pPlaneOut, &extProgress,
- pC->pTransitionList[pC->
- uiCurrentClip].VideoTransitionType
- - M4VSS3GPP_kVideoTransitionType_External);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVideoTransition:\
- External video transition function returns 0x%x!",
- err);
- return err;
- }
- break;
- }
- else
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intVideoTransition: unknown transition type (0x%x),\
- returning M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE",
- pC->pTransitionList[pC->uiCurrentClip].VideoTransitionType);
- return M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE;
- }
- }
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intVideoTransition: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
- ******************************************************************************
- * M4OSA_Void M4VSS3GPP_intUpdateTimeInfo()
- * @brief Update bit stream time info by Counter Time System to be compliant with
- * players using bit stream time info
- * @note H263 uses an absolute time counter unlike MPEG4 which uses Group Of Vops
- * (GOV, see the standard)
- * @param pC (IN/OUT) returns time updated video AU,
- * the offset between system and video time (MPEG4 only)
- * and the state of the current clip (MPEG4 only)
- * @return nothing
- ******************************************************************************
- */
-static M4OSA_Void
-M4VSS3GPP_intUpdateTimeInfo( M4VSS3GPP_InternalEditContext *pC,
- M4SYS_AccessUnit *pAU )
-{
- M4OSA_UInt8 uiTmp;
- M4OSA_UInt32 uiCts = 0;
- M4OSA_MemAddr8 pTmp;
- M4OSA_UInt32 uiAdd;
- M4OSA_UInt32 uiCurrGov;
- M4OSA_Int8 iDiff;
-
- M4VSS3GPP_ClipContext *pClipCtxt = pC->pC1;
- M4OSA_Int32 *pOffset = &(pC->ewc.iMpeg4GovOffset);
-
- /**
- * Set H263 time counter from system time */
- if( M4SYS_kH263 == pAU->stream->streamType )
- {
- uiTmp = (M4OSA_UInt8)((M4OSA_UInt32)( ( pAU->CTS * 30) / 1001 + 0.5)
- % M4VSS3GPP_EDIT_H263_MODULO_TIME);
- M4VSS3GPP_intSetH263TimeCounter((M4OSA_MemAddr8)(pAU->dataAddress),
- uiTmp);
- }
- /*
- * Set MPEG4 GOV time counter regarding video and system time */
- else if( M4SYS_kMPEG_4 == pAU->stream->streamType )
- {
- /*
- * If GOV.
- * beware of little/big endian! */
- /* correction: read 8 bits block instead of one 32 bits block */
- M4OSA_UInt8 *temp8 = (M4OSA_UInt8 *)(pAU->dataAddress);
- M4OSA_UInt32 temp32 = 0;
-
- temp32 = ( 0x000000ff & (M4OSA_UInt32)(*temp8))
- + (0x0000ff00 & ((M4OSA_UInt32)(*(temp8 + 1))) << 8)
- + (0x00ff0000 & ((M4OSA_UInt32)(*(temp8 + 2))) << 16)
- + (0xff000000 & ((M4OSA_UInt32)(*(temp8 + 3))) << 24);
-
- M4OSA_TRACE3_2("RC: Temp32: 0x%x, dataAddress: 0x%x\n", temp32,
- *(pAU->dataAddress));
-
- if( M4VSS3GPP_EDIT_GOV_HEADER == temp32 )
- {
- pTmp =
- (M4OSA_MemAddr8)(pAU->dataAddress
- + 1); /**< Jump to the time code (just after the 32 bits header) */
- uiAdd = (M4OSA_UInt32)(pAU->CTS)+( *pOffset);
-
- switch( pClipCtxt->bMpeg4GovState )
- {
- case M4OSA_FALSE: /*< INIT */
- {
- /* video time = ceil (system time + offset) */
- uiCts = ( uiAdd + 999) / 1000;
-
- /* offset update */
- ( *pOffset) += (( uiCts * 1000) - uiAdd);
-
- /* Save values */
- pClipCtxt->uiMpeg4PrevGovValueSet = uiCts;
-
- /* State to 'first' */
- pClipCtxt->bMpeg4GovState = M4OSA_TRUE;
- }
- break;
-
- case M4OSA_TRUE: /*< UPDATE */
- {
- /* Get current Gov value */
- M4VSS3GPP_intGetMPEG4Gov(pTmp, &uiCurrGov);
-
- /* video time = floor or ceil (system time + offset) */
- uiCts = (uiAdd / 1000);
- iDiff = (M4OSA_Int8)(uiCurrGov
- - pClipCtxt->uiMpeg4PrevGovValueGet - uiCts
- + pClipCtxt->uiMpeg4PrevGovValueSet);
-
- /* ceiling */
- if( iDiff > 0 )
- {
- uiCts += (M4OSA_UInt32)(iDiff);
-
- /* offset update */
- ( *pOffset) += (( uiCts * 1000) - uiAdd);
- }
-
- /* Save values */
- pClipCtxt->uiMpeg4PrevGovValueGet = uiCurrGov;
- pClipCtxt->uiMpeg4PrevGovValueSet = uiCts;
- }
- break;
- }
-
- M4VSS3GPP_intSetMPEG4Gov(pTmp, uiCts);
- }
- }
- return;
-}
-
-/**
- ******************************************************************************
- * M4OSA_Void M4VSS3GPP_intCheckVideoEffects()
- * @brief Check which video effect must be applied at the current time
- ******************************************************************************
- */
-static M4OSA_Void
-M4VSS3GPP_intCheckVideoEffects( M4VSS3GPP_InternalEditContext *pC,
- M4OSA_UInt8 uiClipNumber )
-{
- M4OSA_UInt8 uiClipIndex;
- M4OSA_UInt8 uiFxIndex, i;
- M4VSS3GPP_ClipContext *pClip;
- M4VSS3GPP_EffectSettings *pFx;
- M4OSA_Int32 Off, BC, EC;
- // Decorrelate input and output encoding timestamp to handle encoder prefetch
- M4OSA_Int32 t = (M4OSA_Int32)pC->ewc.dInputVidCts;
-
- uiClipIndex = pC->uiCurrentClip;
- if (uiClipNumber == 1) {
- pClip = pC->pC1;
- pC->bClip1ActiveFramingEffect = M4OSA_FALSE;
- } else {
- pClip = pC->pC2;
- pC->bClip2ActiveFramingEffect = M4OSA_FALSE;
- }
- /**
- * Shortcuts for code readability */
- Off = pClip->iVoffset;
- BC = pClip->iActualVideoBeginCut;
- EC = pClip->iEndTime;
-
- i = 0;
-
- for ( uiFxIndex = 0; uiFxIndex < pC->nbEffects; uiFxIndex++ )
- {
- /** Shortcut, reverse order because of priority between effects(EndEffect always clean )*/
- pFx = &(pC->pEffectsList[pC->nbEffects - 1 - uiFxIndex]);
-
- if( M4VSS3GPP_kVideoEffectType_None != pFx->VideoEffectType )
- {
- /**
- * Check if there is actually a video effect */
-
- if(uiClipNumber ==1)
- {
- /**< Are we after the start time of the effect?
- * or Are we into the effect duration?
- */
- if ( (t >= (M4OSA_Int32)(pFx->uiStartTime)) &&
- (t <= (M4OSA_Int32)(pFx->uiStartTime + pFx->uiDuration)) ) {
- /**
- * Set the active effect(s) */
- pC->pActiveEffectsList[i] = pC->nbEffects-1-uiFxIndex;
-
- /**
- * Update counter of active effects */
- i++;
- if (pFx->xVSS.pFramingBuffer != M4OSA_NULL) {
- pC->bClip1ActiveFramingEffect = M4OSA_TRUE;
- }
-
- /**
- * For all external effects set this flag to true. */
- if(pFx->VideoEffectType > M4VSS3GPP_kVideoEffectType_External)
- {
- pC->m_bClipExternalHasStarted = M4OSA_TRUE;
- }
- }
-
- }
- else
- {
- /**< Are we into the effect duration? */
- if ( ((M4OSA_Int32)(t + pC->pTransitionList[uiClipIndex].uiTransitionDuration)
- >= (M4OSA_Int32)(pFx->uiStartTime))
- && ( (M4OSA_Int32)(t + pC->pTransitionList[uiClipIndex].uiTransitionDuration)
- <= (M4OSA_Int32)(pFx->uiStartTime + pFx->uiDuration)) ) {
- /**
- * Set the active effect(s) */
- pC->pActiveEffectsList1[i] = pC->nbEffects-1-uiFxIndex;
-
- /**
- * Update counter of active effects */
- i++;
- if (pFx->xVSS.pFramingBuffer != M4OSA_NULL) {
- pC->bClip2ActiveFramingEffect = M4OSA_TRUE;
- }
- /**
- * For all external effects set this flag to true. */
- if(pFx->VideoEffectType > M4VSS3GPP_kVideoEffectType_External)
- {
- pC->m_bClipExternalHasStarted = M4OSA_TRUE;
- }
-
- /**
- * The third effect has the highest priority, then the second one, then the first one.
- * Hence, as soon as we found an active effect, we can get out of this loop */
- }
- }
- if (M4VIDEOEDITING_kH264 !=
- pC->pC1->pSettings->ClipProperties.VideoStreamType) {
-
- // For Mpeg4 and H263 clips, full decode encode not required
- pC->m_bClipExternalHasStarted = M4OSA_FALSE;
- }
- }
- }
- if(1==uiClipNumber)
- {
- /**
- * Save number of active effects */
- pC->nbActiveEffects = i;
- }
- else
- {
- pC->nbActiveEffects1 = i;
- }
-
- /**
- * Change the absolut time to clip related time */
- t -= Off;
-
- /**
- * Check if we are on the begin cut (for clip1 only) */
- if( ( 0 != BC) && (t == BC) && (1 == uiClipNumber) )
- {
- pC->bClip1AtBeginCut = M4OSA_TRUE;
- }
- else
- {
- pC->bClip1AtBeginCut = M4OSA_FALSE;
- }
-
- return;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intCreateVideoEncoder()
- * @brief Creates the video encoder
- * @note
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intCreateVideoEncoder( M4VSS3GPP_InternalEditContext *pC )
-{
- M4OSA_ERR err;
- M4ENCODER_AdvancedParams EncParams;
-
- /**
- * Simulate a writer interface with our specific function */
- pC->ewc.OurWriterDataInterface.pProcessAU =
- M4VSS3GPP_intProcessAU; /**< This function is VSS 3GPP specific,
- but it follow the writer interface */
- pC->ewc.OurWriterDataInterface.pStartAU =
- M4VSS3GPP_intStartAU; /**< This function is VSS 3GPP specific,
- but it follow the writer interface */
- pC->ewc.OurWriterDataInterface.pWriterContext =
- (M4WRITER_Context)
- pC; /**< We give the internal context as writer context */
-
- /**
- * Get the encoder interface, if not already done */
- if( M4OSA_NULL == pC->ShellAPI.pVideoEncoderGlobalFcts )
- {
- err = M4VSS3GPP_setCurrentVideoEncoder(&pC->ShellAPI,
- pC->ewc.VideoStreamType);
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCreateVideoEncoder: setCurrentEncoder returns 0x%x",
- err);
- M4ERR_CHECK_RETURN(err);
- }
-
- /**
- * Set encoder shell parameters according to VSS settings */
-
- /* Common parameters */
- EncParams.InputFormat = M4ENCODER_kIYUV420;
- EncParams.FrameWidth = pC->ewc.uiVideoWidth;
- EncParams.FrameHeight = pC->ewc.uiVideoHeight;
- EncParams.uiTimeScale = pC->ewc.uiVideoTimeScale;
-
- if( pC->bIsMMS == M4OSA_FALSE )
- {
- /* No strict regulation in video editor */
- /* Because of the effects and transitions we should allow more flexibility */
- /* Also it prevents to drop important frames (with a bad result on sheduling and
- block effetcs) */
- EncParams.bInternalRegulation = M4OSA_FALSE;
- // Variable framerate is not supported by StageFright encoders
- EncParams.FrameRate = M4ENCODER_k30_FPS;
- }
- else
- {
- /* In case of MMS mode, we need to enable bitrate regulation to be sure */
- /* to reach the targeted output file size */
- EncParams.bInternalRegulation = M4OSA_TRUE;
- EncParams.FrameRate = pC->MMSvideoFramerate;
- }
-
- /**
- * Other encoder settings (defaults) */
- EncParams.uiHorizontalSearchRange = 0; /* use default */
- EncParams.uiVerticalSearchRange = 0; /* use default */
- EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
- EncParams.uiIVopPeriod = 0; /* use default */
- EncParams.uiMotionEstimationTools = 0; /* M4V_MOTION_EST_TOOLS_ALL */
- EncParams.bAcPrediction = M4OSA_TRUE; /* use AC prediction */
- EncParams.uiStartingQuantizerValue = 10; /* initial QP = 10 */
- EncParams.bDataPartitioning = M4OSA_FALSE; /* no data partitioning */
-
- /**
- * Set the video profile and level */
- EncParams.videoProfile = pC->ewc.outputVideoProfile;
- EncParams.videoLevel= pC->ewc.outputVideoLevel;
-
- switch ( pC->ewc.VideoStreamType )
- {
- case M4SYS_kH263:
-
- EncParams.Format = M4ENCODER_kH263;
-
- EncParams.uiStartingQuantizerValue = 10;
- EncParams.uiRateFactor = 1; /* default */
-
- EncParams.bErrorResilience = M4OSA_FALSE;
- EncParams.bDataPartitioning = M4OSA_FALSE;
- break;
-
- case M4SYS_kMPEG_4:
-
- EncParams.Format = M4ENCODER_kMPEG4;
-
- EncParams.uiStartingQuantizerValue = 8;
- EncParams.uiRateFactor = (M4OSA_UInt8)(( pC->dOutputFrameDuration
- * pC->ewc.uiVideoTimeScale) / 1000.0 + 0.5);
-
- if( EncParams.uiRateFactor == 0 )
- EncParams.uiRateFactor = 1; /* default */
-
- if( M4OSA_FALSE == pC->ewc.bVideoDataPartitioning )
- {
- EncParams.bErrorResilience = M4OSA_FALSE;
- EncParams.bDataPartitioning = M4OSA_FALSE;
- }
- else
- {
- EncParams.bErrorResilience = M4OSA_TRUE;
- EncParams.bDataPartitioning = M4OSA_TRUE;
- }
- break;
-
- case M4SYS_kH264:
- M4OSA_TRACE1_0("M4VSS3GPP_intCreateVideoEncoder: M4SYS_H264");
-
- EncParams.Format = M4ENCODER_kH264;
-
- EncParams.uiStartingQuantizerValue = 10;
- EncParams.uiRateFactor = 1; /* default */
-
- EncParams.bErrorResilience = M4OSA_FALSE;
- EncParams.bDataPartitioning = M4OSA_FALSE;
- //EncParams.FrameRate = M4VIDEOEDITING_k5_FPS;
- break;
-
- default:
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCreateVideoEncoder: Unknown videoStreamType 0x%x",
- pC->ewc.VideoStreamType);
- return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT;
- }
-
- if( pC->bIsMMS == M4OSA_FALSE )
- {
- EncParams.Bitrate = pC->xVSS.outputVideoBitrate;
-
- }
- else
- {
- EncParams.Bitrate = pC->uiMMSVideoBitrate; /* RC */
- EncParams.uiTimeScale = 0; /* We let the encoder choose the timescale */
- }
-
- M4OSA_TRACE1_0("M4VSS3GPP_intCreateVideoEncoder: calling encoder pFctInit");
- /**
- * Init the video encoder (advanced settings version of the encoder Open function) */
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctInit(&pC->ewc.pEncContext,
- &pC->ewc.OurWriterDataInterface, M4VSS3GPP_intVPP, pC,
- pC->ShellAPI.pCurrentVideoEncoderExternalAPI,
- pC->ShellAPI.pCurrentVideoEncoderUserData);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCreateVideoEncoder: pVideoEncoderGlobalFcts->pFctInit returns 0x%x",
- err);
- return err;
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kEncoderClosed;
- M4OSA_TRACE1_0("M4VSS3GPP_intCreateVideoEncoder: calling encoder pFctOpen");
-
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctOpen(pC->ewc.pEncContext,
- &pC->ewc.WriterVideoAU, &EncParams);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCreateVideoEncoder: pVideoEncoderGlobalFcts->pFctOpen returns 0x%x",
- err);
- return err;
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kEncoderStopped;
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intCreateVideoEncoder: calling encoder pFctStart");
-
- if( M4OSA_NULL != pC->ShellAPI.pVideoEncoderGlobalFcts->pFctStart )
- {
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctStart(
- pC->ewc.pEncContext);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intCreateVideoEncoder: pVideoEncoderGlobalFcts->pFctStart returns 0x%x",
- err);
- return err;
- }
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kEncoderRunning;
-
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intCreateVideoEncoder: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intDestroyVideoEncoder()
- * @brief Destroy the video encoder
- * @note
- ******************************************************************************
- */
-M4OSA_ERR M4VSS3GPP_intDestroyVideoEncoder( M4VSS3GPP_InternalEditContext *pC )
-{
- M4OSA_ERR err = M4NO_ERROR;
-
- if( M4OSA_NULL != pC->ewc.pEncContext )
- {
- if( M4VSS3GPP_kEncoderRunning == pC->ewc.encoderState )
- {
- if( pC->ShellAPI.pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
- {
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctStop(
- pC->ewc.pEncContext);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intDestroyVideoEncoder:\
- pVideoEncoderGlobalFcts->pFctStop returns 0x%x",
- err);
- /* Well... how the heck do you handle a failed cleanup? */
- }
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kEncoderStopped;
- }
-
- /* Has the encoder actually been opened? Don't close it if that's not the case. */
- if( M4VSS3GPP_kEncoderStopped == pC->ewc.encoderState )
- {
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctClose(
- pC->ewc.pEncContext);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intDestroyVideoEncoder:\
- pVideoEncoderGlobalFcts->pFctClose returns 0x%x",
- err);
- /* Well... how the heck do you handle a failed cleanup? */
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kEncoderClosed;
- }
-
- err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctCleanup(
- pC->ewc.pEncContext);
-
- if( M4NO_ERROR != err )
- {
- M4OSA_TRACE1_1(
- "M4VSS3GPP_intDestroyVideoEncoder:\
- pVideoEncoderGlobalFcts->pFctCleanup returns 0x%x!",
- err);
- /**< We do not return the error here because we still have stuff to free */
- }
-
- pC->ewc.encoderState = M4VSS3GPP_kNoEncoder;
- /**
- * Reset variable */
- pC->ewc.pEncContext = M4OSA_NULL;
- }
-
- M4OSA_TRACE3_1("M4VSS3GPP_intDestroyVideoEncoder: returning 0x%x", err);
- return err;
-}
-
-/**
- ******************************************************************************
- * M4OSA_Void M4VSS3GPP_intSetH263TimeCounter()
- * @brief Modify the time counter of the given H263 video AU
- * @note
- * @param pAuDataBuffer (IN/OUT) H263 Video AU to modify
- * @param uiCts (IN) New time counter value
- * @return nothing
- ******************************************************************************
- */
-static M4OSA_Void M4VSS3GPP_intSetH263TimeCounter( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt8 uiCts )
-{
- /*
- * The H263 time counter is 8 bits located on the "x" below:
- *
- * |--------|--------|--------|--------|
- * ???????? ???????? ??????xx xxxxxx??
- */
-
- /**
- * Write the 2 bits on the third byte */
- pAuDataBuffer[2] = ( pAuDataBuffer[2] & 0xFC) | (( uiCts >> 6) & 0x3);
-
- /**
- * Write the 6 bits on the fourth byte */
- pAuDataBuffer[3] = ( ( uiCts << 2) & 0xFC) | (pAuDataBuffer[3] & 0x3);
-
- return;
-}
-
-/**
- ******************************************************************************
- * M4OSA_Void M4VSS3GPP_intSetMPEG4Gov()
- * @brief Modify the time info from Group Of VOP video AU
- * @note
- * @param pAuDataBuffer (IN) MPEG4 Video AU to modify
- * @param uiCtsSec (IN) New GOV time info in second unit
- * @return nothing
- ******************************************************************************
- */
-static M4OSA_Void M4VSS3GPP_intSetMPEG4Gov( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt32 uiCtsSec )
-{
- /*
- * The MPEG-4 time code length is 18 bits:
- *
- * hh mm marker ss
- * xxxxx|xxx xxx 1 xxxx xx ??????
- * |----- ---|--- - ----|-- ------|
- */
- M4OSA_UInt8 uiHh;
- M4OSA_UInt8 uiMm;
- M4OSA_UInt8 uiSs;
- M4OSA_UInt8 uiTmp;
-
- /**
- * Write the 2 last bits ss */
- uiSs = (M4OSA_UInt8)(uiCtsSec % 60); /**< modulo part */
- pAuDataBuffer[2] = (( ( uiSs & 0x03) << 6) | (pAuDataBuffer[2] & 0x3F));
-
- if( uiCtsSec < 60 )
- {
- /**
- * Write the 3 last bits of mm, the marker bit (0x10 */
- pAuDataBuffer[1] = (( 0x10) | (uiSs >> 2));
-
- /**
- * Write the 5 bits of hh and 3 of mm (out of 6) */
- pAuDataBuffer[0] = 0;
- }
- else
- {
- /**
- * Write the 3 last bits of mm, the marker bit (0x10 */
- uiTmp = (M4OSA_UInt8)(uiCtsSec / 60); /**< integer part */
- uiMm = (M4OSA_UInt8)(uiTmp % 60);
- pAuDataBuffer[1] = (( uiMm << 5) | (0x10) | (uiSs >> 2));
-
- if( uiTmp < 60 )
- {
- /**
- * Write the 5 bits of hh and 3 of mm (out of 6) */
- pAuDataBuffer[0] = ((uiMm >> 3));
- }
- else
- {
- /**
- * Write the 5 bits of hh and 3 of mm (out of 6) */
- uiHh = (M4OSA_UInt8)(uiTmp / 60);
- pAuDataBuffer[0] = (( uiHh << 3) | (uiMm >> 3));
- }
- }
- return;
-}
-
-/**
- ******************************************************************************
- * M4OSA_Void M4VSS3GPP_intGetMPEG4Gov()
- * @brief Get the time info from Group Of VOP video AU
- * @note
- * @param pAuDataBuffer (IN) MPEG4 Video AU to modify
- * @param pCtsSec (OUT) Current GOV time info in second unit
- * @return nothing
- ******************************************************************************
- */
-static M4OSA_Void M4VSS3GPP_intGetMPEG4Gov( M4OSA_MemAddr8 pAuDataBuffer,
- M4OSA_UInt32 *pCtsSec )
-{
- /*
- * The MPEG-4 time code length is 18 bits:
- *
- * hh mm marker ss
- * xxxxx|xxx xxx 1 xxxx xx ??????
- * |----- ---|--- - ----|-- ------|
- */
- M4OSA_UInt8 uiHh;
- M4OSA_UInt8 uiMm;
- M4OSA_UInt8 uiSs;
- M4OSA_UInt8 uiTmp;
- M4OSA_UInt32 uiCtsSec;
-
- /**
- * Read ss */
- uiSs = (( pAuDataBuffer[2] & 0xC0) >> 6);
- uiTmp = (( pAuDataBuffer[1] & 0x0F) << 2);
- uiCtsSec = uiSs + uiTmp;
-
- /**
- * Read mm */
- uiMm = (( pAuDataBuffer[1] & 0xE0) >> 5);
- uiTmp = (( pAuDataBuffer[0] & 0x07) << 3);
- uiMm = uiMm + uiTmp;
- uiCtsSec = ( uiMm * 60) + uiCtsSec;
-
- /**
- * Read hh */
- uiHh = (( pAuDataBuffer[0] & 0xF8) >> 3);
-
- if( uiHh )
- {
- uiCtsSec = ( uiHh * 3600) + uiCtsSec;
- }
-
- /*
- * in sec */
- *pCtsSec = uiCtsSec;
-
- return;
-}
-
-/**
- ******************************************************************************
- * M4OSA_ERR M4VSS3GPP_intAllocateYUV420()
- * @brief Allocate the three YUV 4:2:0 planes
- * @note
- * @param pPlanes (IN/OUT) valid pointer to 3 M4VIFI_ImagePlane structures
- * @param uiWidth (IN) Image width
- * @param uiHeight(IN) Image height
- ******************************************************************************
- */
-static M4OSA_ERR M4VSS3GPP_intAllocateYUV420( M4VIFI_ImagePlane *pPlanes,
- M4OSA_UInt32 uiWidth, M4OSA_UInt32 uiHeight )
-{
- if (pPlanes == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_intAllocateYUV420: Invalid pPlanes pointer");
- return M4ERR_PARAMETER;
- }
- /* if the buffer is not NULL and same size with target size,
- * do not malloc again*/
- if (pPlanes[0].pac_data != M4OSA_NULL &&
- pPlanes[0].u_width == uiWidth &&
- pPlanes[0].u_height == uiHeight) {
- return M4NO_ERROR;
- }
-
- pPlanes[0].u_width = uiWidth;
- pPlanes[0].u_height = uiHeight;
- pPlanes[0].u_stride = uiWidth;
- pPlanes[0].u_topleft = 0;
-
- if (pPlanes[0].pac_data != M4OSA_NULL) {
- free(pPlanes[0].pac_data);
- pPlanes[0].pac_data = M4OSA_NULL;
- }
- pPlanes[0].pac_data = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pPlanes[0].u_stride
- * pPlanes[0].u_height, M4VSS3GPP, (M4OSA_Char *)"pPlanes[0].pac_data");
-
- if( M4OSA_NULL == pPlanes[0].pac_data )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intAllocateYUV420: unable to allocate pPlanes[0].pac_data,\
- returning M4ERR_ALLOC");
- return M4ERR_ALLOC;
- }
-
- pPlanes[1].u_width = pPlanes[0].u_width >> 1;
- pPlanes[1].u_height = pPlanes[0].u_height >> 1;
- pPlanes[1].u_stride = pPlanes[1].u_width;
- pPlanes[1].u_topleft = 0;
- if (pPlanes[1].pac_data != M4OSA_NULL) {
- free(pPlanes[1].pac_data);
- pPlanes[1].pac_data = M4OSA_NULL;
- }
- pPlanes[1].pac_data = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pPlanes[1].u_stride
- * pPlanes[1].u_height, M4VSS3GPP,(M4OSA_Char *) "pPlanes[1].pac_data");
-
- if( M4OSA_NULL == pPlanes[1].pac_data )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intAllocateYUV420: unable to allocate pPlanes[1].pac_data,\
- returning M4ERR_ALLOC");
- free((void *)pPlanes[0].pac_data);
- pPlanes[0].pac_data = M4OSA_NULL;
- return M4ERR_ALLOC;
- }
-
- pPlanes[2].u_width = pPlanes[1].u_width;
- pPlanes[2].u_height = pPlanes[1].u_height;
- pPlanes[2].u_stride = pPlanes[2].u_width;
- pPlanes[2].u_topleft = 0;
- if (pPlanes[2].pac_data != M4OSA_NULL) {
- free(pPlanes[2].pac_data);
- pPlanes[2].pac_data = M4OSA_NULL;
- }
- pPlanes[2].pac_data = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pPlanes[2].u_stride
- * pPlanes[2].u_height, M4VSS3GPP, (M4OSA_Char *)"pPlanes[2].pac_data");
-
- if( M4OSA_NULL == pPlanes[2].pac_data )
- {
- M4OSA_TRACE1_0(
- "M4VSS3GPP_intAllocateYUV420: unable to allocate pPlanes[2].pac_data,\
- returning M4ERR_ALLOC");
- free((void *)pPlanes[0].pac_data);
- free((void *)pPlanes[1].pac_data);
- pPlanes[0].pac_data = M4OSA_NULL;
- pPlanes[1].pac_data = M4OSA_NULL;
- return M4ERR_ALLOC;
- }
-
- memset((void *)pPlanes[0].pac_data, 0, pPlanes[0].u_stride*pPlanes[0].u_height);
- memset((void *)pPlanes[1].pac_data, 0, pPlanes[1].u_stride*pPlanes[1].u_height);
- memset((void *)pPlanes[2].pac_data, 0, pPlanes[2].u_stride*pPlanes[2].u_height);
- /**
- * Return */
- M4OSA_TRACE3_0("M4VSS3GPP_intAllocateYUV420: returning M4NO_ERROR");
- return M4NO_ERROR;
-}
-
-/**
-******************************************************************************
-* M4OSA_ERR M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420(M4OSA_Void* pFileIn,
-* M4OSA_FileReadPointer* pFileReadPtr,
-* M4VIFI_ImagePlane* pImagePlanes,
-* M4OSA_UInt32 width,
-* M4OSA_UInt32 height);
-* @brief It Coverts and resizes a ARGB8888 image to YUV420
-* @note
-* @param pFileIn (IN) The ARGB888 input file
-* @param pFileReadPtr (IN) Pointer on filesystem functions
-* @param pImagePlanes (IN/OUT) Pointer on YUV420 output planes allocated by the user.
-* ARGB8888 image will be converted and resized to output
-* YUV420 plane size
-* @param width (IN) width of the ARGB8888
-* @param height (IN) height of the ARGB8888
-* @return M4NO_ERROR: No error
-* @return M4ERR_ALLOC: memory error
-* @return M4ERR_PARAMETER: At least one of the function parameters is null
-******************************************************************************
-*/
-
-M4OSA_ERR M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420(M4OSA_Void* pFileIn,
- M4OSA_FileReadPointer* pFileReadPtr,
- M4VIFI_ImagePlane* pImagePlanes,
- M4OSA_UInt32 width,M4OSA_UInt32 height) {
- M4OSA_Context pARGBIn;
- M4VIFI_ImagePlane rgbPlane1 ,rgbPlane2;
- M4OSA_UInt32 frameSize_argb = width * height * 4;
- M4OSA_UInt32 frameSize_rgb888 = width * height * 3;
- M4OSA_UInt32 i = 0,j= 0;
- M4OSA_ERR err = M4NO_ERROR;
-
- M4OSA_UInt8 *pArgbPlane =
- (M4OSA_UInt8*) M4OSA_32bitAlignedMalloc(frameSize_argb,
- M4VS, (M4OSA_Char*)"argb data");
- if (pArgbPlane == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420: \
- Failed to allocate memory for ARGB plane");
- return M4ERR_ALLOC;
- }
-
- /* Get file size */
- err = pFileReadPtr->openRead(&pARGBIn, pFileIn, M4OSA_kFileRead);
- if (err != M4NO_ERROR) {
- M4OSA_TRACE1_2("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 : \
- Can not open input ARGB8888 file %s, error: 0x%x\n",pFileIn, err);
- free(pArgbPlane);
- pArgbPlane = M4OSA_NULL;
- goto cleanup;
- }
-
- err = pFileReadPtr->readData(pARGBIn,(M4OSA_MemAddr8)pArgbPlane,
- &frameSize_argb);
- if (err != M4NO_ERROR) {
- M4OSA_TRACE1_2("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 \
- Can not read ARGB8888 file %s, error: 0x%x\n",pFileIn, err);
- pFileReadPtr->closeRead(pARGBIn);
- free(pArgbPlane);
- pArgbPlane = M4OSA_NULL;
- goto cleanup;
- }
-
- err = pFileReadPtr->closeRead(pARGBIn);
- if(err != M4NO_ERROR) {
- M4OSA_TRACE1_2("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 \
- Can not close ARGB8888 file %s, error: 0x%x\n",pFileIn, err);
- free(pArgbPlane);
- pArgbPlane = M4OSA_NULL;
- goto cleanup;
- }
-
- rgbPlane1.pac_data =
- (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(frameSize_rgb888,
- M4VS, (M4OSA_Char*)"RGB888 plane1");
- if(rgbPlane1.pac_data == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 \
- Failed to allocate memory for rgb plane1");
- free(pArgbPlane);
- return M4ERR_ALLOC;
- }
-
- rgbPlane1.u_height = height;
- rgbPlane1.u_width = width;
- rgbPlane1.u_stride = width*3;
- rgbPlane1.u_topleft = 0;
-
-
- /** Remove the alpha channel */
- for (i=0, j = 0; i < frameSize_argb; i++) {
- if ((i % 4) == 0) continue;
- rgbPlane1.pac_data[j] = pArgbPlane[i];
- j++;
- }
- free(pArgbPlane);
-
- /**
- * Check if resizing is required with color conversion */
- if(width != pImagePlanes->u_width || height != pImagePlanes->u_height) {
-
- frameSize_rgb888 = pImagePlanes->u_width * pImagePlanes->u_height * 3;
- rgbPlane2.pac_data =
- (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(frameSize_rgb888, M4VS,
- (M4OSA_Char*)"rgb Plane2");
- if(rgbPlane2.pac_data == M4OSA_NULL) {
- M4OSA_TRACE1_0("Failed to allocate memory for rgb plane2");
- free(rgbPlane1.pac_data);
- return M4ERR_ALLOC;
- }
- rgbPlane2.u_height = pImagePlanes->u_height;
- rgbPlane2.u_width = pImagePlanes->u_width;
- rgbPlane2.u_stride = pImagePlanes->u_width*3;
- rgbPlane2.u_topleft = 0;
-
- /* Resizing */
- err = M4VIFI_ResizeBilinearRGB888toRGB888(M4OSA_NULL,
- &rgbPlane1, &rgbPlane2);
- free(rgbPlane1.pac_data);
- if(err != M4NO_ERROR) {
- M4OSA_TRACE1_1("error resizing RGB888 to RGB888: 0x%x\n", err);
- free(rgbPlane2.pac_data);
- return err;
- }
-
- /*Converting Resized RGB888 to YUV420 */
- err = M4VIFI_RGB888toYUV420(M4OSA_NULL, &rgbPlane2, pImagePlanes);
- free(rgbPlane2.pac_data);
- if(err != M4NO_ERROR) {
- M4OSA_TRACE1_1("error converting from RGB888 to YUV: 0x%x\n", err);
- return err;
- }
- } else {
- err = M4VIFI_RGB888toYUV420(M4OSA_NULL, &rgbPlane1, pImagePlanes);
- if(err != M4NO_ERROR) {
- M4OSA_TRACE1_1("error when converting from RGB to YUV: 0x%x\n", err);
- }
- free(rgbPlane1.pac_data);
- }
-cleanup:
- M4OSA_TRACE3_0("M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 exit");
- return err;
-}
-
-M4OSA_ERR M4VSS3GPP_intApplyRenderingMode(M4VSS3GPP_InternalEditContext *pC,
- M4xVSS_MediaRendering renderingMode,
- M4VIFI_ImagePlane* pInplane,
- M4VIFI_ImagePlane* pOutplane) {
-
- M4OSA_ERR err = M4NO_ERROR;
- M4AIR_Params airParams;
- M4VIFI_ImagePlane pImagePlanesTemp[3];
- M4OSA_UInt32 i = 0;
-
- if (renderingMode == M4xVSS_kBlackBorders) {
- memset((void *)pOutplane[0].pac_data, Y_PLANE_BORDER_VALUE,
- (pOutplane[0].u_height*pOutplane[0].u_stride));
- memset((void *)pOutplane[1].pac_data, U_PLANE_BORDER_VALUE,
- (pOutplane[1].u_height*pOutplane[1].u_stride));
- memset((void *)pOutplane[2].pac_data, V_PLANE_BORDER_VALUE,
- (pOutplane[2].u_height*pOutplane[2].u_stride));
- }
-
- if (renderingMode == M4xVSS_kResizing) {
- /**
- * Call the resize filter.
- * From the intermediate frame to the encoder image plane */
- err = M4VIFI_ResizeBilinearYUV420toYUV420(M4OSA_NULL,
- pInplane, pOutplane);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intApplyRenderingMode: \
- M4ViFilResizeBilinearYUV420toYUV420 returns 0x%x!", err);
- return err;
- }
- } else {
- M4VIFI_ImagePlane* pPlaneTemp = M4OSA_NULL;
- M4OSA_UInt8* pOutPlaneY =
- pOutplane[0].pac_data + pOutplane[0].u_topleft;
- M4OSA_UInt8* pOutPlaneU =
- pOutplane[1].pac_data + pOutplane[1].u_topleft;
- M4OSA_UInt8* pOutPlaneV =
- pOutplane[2].pac_data + pOutplane[2].u_topleft;
- M4OSA_UInt8* pInPlaneY = M4OSA_NULL;
- M4OSA_UInt8* pInPlaneU = M4OSA_NULL;
- M4OSA_UInt8* pInPlaneV = M4OSA_NULL;
-
- /* To keep media aspect ratio*/
- /* Initialize AIR Params*/
- airParams.m_inputCoord.m_x = 0;
- airParams.m_inputCoord.m_y = 0;
- airParams.m_inputSize.m_height = pInplane->u_height;
- airParams.m_inputSize.m_width = pInplane->u_width;
- airParams.m_outputSize.m_width = pOutplane->u_width;
- airParams.m_outputSize.m_height = pOutplane->u_height;
- airParams.m_bOutputStripe = M4OSA_FALSE;
- airParams.m_outputOrientation = M4COMMON_kOrientationTopLeft;
-
- /**
- Media rendering: Black borders*/
- if (renderingMode == M4xVSS_kBlackBorders) {
- pImagePlanesTemp[0].u_width = pOutplane[0].u_width;
- pImagePlanesTemp[0].u_height = pOutplane[0].u_height;
- pImagePlanesTemp[0].u_stride = pOutplane[0].u_width;
- pImagePlanesTemp[0].u_topleft = 0;
-
- pImagePlanesTemp[1].u_width = pOutplane[1].u_width;
- pImagePlanesTemp[1].u_height = pOutplane[1].u_height;
- pImagePlanesTemp[1].u_stride = pOutplane[1].u_width;
- pImagePlanesTemp[1].u_topleft = 0;
-
- pImagePlanesTemp[2].u_width = pOutplane[2].u_width;
- pImagePlanesTemp[2].u_height = pOutplane[2].u_height;
- pImagePlanesTemp[2].u_stride = pOutplane[2].u_width;
- pImagePlanesTemp[2].u_topleft = 0;
-
- /**
- * Allocates plan in local image plane structure */
- pImagePlanesTemp[0].pac_data =
- (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
- pImagePlanesTemp[0].u_width * pImagePlanesTemp[0].u_height,
- M4VS, (M4OSA_Char *)"pImagePlaneTemp Y") ;
- if (pImagePlanesTemp[0].pac_data == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_intApplyRenderingMode: Alloc Error");
- return M4ERR_ALLOC;
- }
- pImagePlanesTemp[1].pac_data =
- (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
- pImagePlanesTemp[1].u_width * pImagePlanesTemp[1].u_height,
- M4VS, (M4OSA_Char *)"pImagePlaneTemp U") ;
- if (pImagePlanesTemp[1].pac_data == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_intApplyRenderingMode: Alloc Error");
- free(pImagePlanesTemp[0].pac_data);
- return M4ERR_ALLOC;
- }
- pImagePlanesTemp[2].pac_data =
- (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
- pImagePlanesTemp[2].u_width * pImagePlanesTemp[2].u_height,
- M4VS, (M4OSA_Char *)"pImagePlaneTemp V") ;
- if (pImagePlanesTemp[2].pac_data == M4OSA_NULL) {
- M4OSA_TRACE1_0("M4VSS3GPP_intApplyRenderingMode: Alloc Error");
- free(pImagePlanesTemp[0].pac_data);
- free(pImagePlanesTemp[1].pac_data);
- return M4ERR_ALLOC;
- }
-
- pInPlaneY = pImagePlanesTemp[0].pac_data ;
- pInPlaneU = pImagePlanesTemp[1].pac_data ;
- pInPlaneV = pImagePlanesTemp[2].pac_data ;
-
- memset((void *)pImagePlanesTemp[0].pac_data, Y_PLANE_BORDER_VALUE,
- (pImagePlanesTemp[0].u_height*pImagePlanesTemp[0].u_stride));
- memset((void *)pImagePlanesTemp[1].pac_data, U_PLANE_BORDER_VALUE,
- (pImagePlanesTemp[1].u_height*pImagePlanesTemp[1].u_stride));
- memset((void *)pImagePlanesTemp[2].pac_data, V_PLANE_BORDER_VALUE,
- (pImagePlanesTemp[2].u_height*pImagePlanesTemp[2].u_stride));
-
- M4OSA_UInt32 height =
- (pInplane->u_height * pOutplane->u_width) /pInplane->u_width;
-
- if (height <= pOutplane->u_height) {
- /**
- * Black borders will be on the top and the bottom side */
- airParams.m_outputSize.m_width = pOutplane->u_width;
- airParams.m_outputSize.m_height = height;
- /**
- * Number of lines at the top */
- pImagePlanesTemp[0].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[0].u_height -
- airParams.m_outputSize.m_height)>>1)) *
- pImagePlanesTemp[0].u_stride;
- pImagePlanesTemp[0].u_height = airParams.m_outputSize.m_height;
- pImagePlanesTemp[1].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[1].u_height -
- (airParams.m_outputSize.m_height>>1)))>>1) *
- pImagePlanesTemp[1].u_stride;
- pImagePlanesTemp[1].u_height =
- airParams.m_outputSize.m_height>>1;
- pImagePlanesTemp[2].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[2].u_height -
- (airParams.m_outputSize.m_height>>1)))>>1) *
- pImagePlanesTemp[2].u_stride;
- pImagePlanesTemp[2].u_height =
- airParams.m_outputSize.m_height>>1;
- } else {
- /**
- * Black borders will be on the left and right side */
- airParams.m_outputSize.m_height = pOutplane->u_height;
- airParams.m_outputSize.m_width =
- (M4OSA_UInt32)((pInplane->u_width * pOutplane->u_height)/pInplane->u_height);
-
- pImagePlanesTemp[0].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[0].u_width -
- airParams.m_outputSize.m_width)>>1));
- pImagePlanesTemp[0].u_width = airParams.m_outputSize.m_width;
- pImagePlanesTemp[1].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[1].u_width -
- (airParams.m_outputSize.m_width>>1)))>>1);
- pImagePlanesTemp[1].u_width = airParams.m_outputSize.m_width>>1;
- pImagePlanesTemp[2].u_topleft =
- (M4xVSS_ABS((M4OSA_Int32)(pImagePlanesTemp[2].u_width -
- (airParams.m_outputSize.m_width>>1)))>>1);
- pImagePlanesTemp[2].u_width = airParams.m_outputSize.m_width>>1;
- }
-
- /**
- * Width and height have to be even */
- airParams.m_outputSize.m_width =
- (airParams.m_outputSize.m_width>>1)<<1;
- airParams.m_outputSize.m_height =
- (airParams.m_outputSize.m_height>>1)<<1;
- airParams.m_inputSize.m_width =
- (airParams.m_inputSize.m_width>>1)<<1;
- airParams.m_inputSize.m_height =
- (airParams.m_inputSize.m_height>>1)<<1;
- pImagePlanesTemp[0].u_width =
- (pImagePlanesTemp[0].u_width>>1)<<1;
- pImagePlanesTemp[1].u_width =
- (pImagePlanesTemp[1].u_width>>1)<<1;
- pImagePlanesTemp[2].u_width =
- (pImagePlanesTemp[2].u_width>>1)<<1;
- pImagePlanesTemp[0].u_height =
- (pImagePlanesTemp[0].u_height>>1)<<1;
- pImagePlanesTemp[1].u_height =
- (pImagePlanesTemp[1].u_height>>1)<<1;
- pImagePlanesTemp[2].u_height =
- (pImagePlanesTemp[2].u_height>>1)<<1;
-
- /**
- * Check that values are coherent */
- if (airParams.m_inputSize.m_height ==
- airParams.m_outputSize.m_height) {
- airParams.m_inputSize.m_width =
- airParams.m_outputSize.m_width;
- } else if (airParams.m_inputSize.m_width ==
- airParams.m_outputSize.m_width) {
- airParams.m_inputSize.m_height =
- airParams.m_outputSize.m_height;
- }
- pPlaneTemp = pImagePlanesTemp;
- }
-
- /**
- * Media rendering: Cropping*/
- if (renderingMode == M4xVSS_kCropping) {
- airParams.m_outputSize.m_height = pOutplane->u_height;
- airParams.m_outputSize.m_width = pOutplane->u_width;
- if ((airParams.m_outputSize.m_height *
- airParams.m_inputSize.m_width)/airParams.m_outputSize.m_width <
- airParams.m_inputSize.m_height) {
- /* Height will be cropped */
- airParams.m_inputSize.m_height =
- (M4OSA_UInt32)((airParams.m_outputSize.m_height *
- airParams.m_inputSize.m_width)/airParams.m_outputSize.m_width);
- airParams.m_inputSize.m_height =
- (airParams.m_inputSize.m_height>>1)<<1;
- airParams.m_inputCoord.m_y =
- (M4OSA_Int32)((M4OSA_Int32)((pInplane->u_height -
- airParams.m_inputSize.m_height))>>1);
- } else {
- /* Width will be cropped */
- airParams.m_inputSize.m_width =
- (M4OSA_UInt32)((airParams.m_outputSize.m_width *
- airParams.m_inputSize.m_height)/airParams.m_outputSize.m_height);
- airParams.m_inputSize.m_width =
- (airParams.m_inputSize.m_width>>1)<<1;
- airParams.m_inputCoord.m_x =
- (M4OSA_Int32)((M4OSA_Int32)((pInplane->u_width -
- airParams.m_inputSize.m_width))>>1);
- }
- pPlaneTemp = pOutplane;
- }
- /**
- * Call AIR functions */
- if (M4OSA_NULL == pC->m_air_context) {
- err = M4AIR_create(&pC->m_air_context, M4AIR_kYUV420P);
- if(err != M4NO_ERROR) {
- M4OSA_TRACE1_1("M4VSS3GPP_intApplyRenderingMode: \
- M4AIR_create returned error 0x%x", err);
- goto cleanUp;
- }
- }
-
- err = M4AIR_configure(pC->m_air_context, &airParams);
- if (err != M4NO_ERROR) {
- M4OSA_TRACE1_1("M4VSS3GPP_intApplyRenderingMode: \
- Error when configuring AIR: 0x%x", err);
- M4AIR_cleanUp(pC->m_air_context);
- goto cleanUp;
- }
-
- err = M4AIR_get(pC->m_air_context, pInplane, pPlaneTemp);
- if (err != M4NO_ERROR) {
- M4OSA_TRACE1_1("M4VSS3GPP_intApplyRenderingMode: \
- Error when getting AIR plane: 0x%x", err);
- M4AIR_cleanUp(pC->m_air_context);
- goto cleanUp;
- }
-
- if (renderingMode == M4xVSS_kBlackBorders) {
- for (i=0; i<pOutplane[0].u_height; i++) {
- memcpy((void *)pOutPlaneY, (void *)pInPlaneY,
- pOutplane[0].u_width);
- pInPlaneY += pOutplane[0].u_width;
- pOutPlaneY += pOutplane[0].u_stride;
- }
- for (i=0; i<pOutplane[1].u_height; i++) {
- memcpy((void *)pOutPlaneU, (void *)pInPlaneU,
- pOutplane[1].u_width);
- pInPlaneU += pOutplane[1].u_width;
- pOutPlaneU += pOutplane[1].u_stride;
- }
- for (i=0; i<pOutplane[2].u_height; i++) {
- memcpy((void *)pOutPlaneV, (void *)pInPlaneV,
- pOutplane[2].u_width);
- pInPlaneV += pOutplane[2].u_width;
- pOutPlaneV += pOutplane[2].u_stride;
- }
- }
- }
-cleanUp:
- if (renderingMode == M4xVSS_kBlackBorders) {
- for (i=0; i<3; i++) {
- if (pImagePlanesTemp[i].pac_data != M4OSA_NULL) {
- free(pImagePlanesTemp[i].pac_data);
- pImagePlanesTemp[i].pac_data = M4OSA_NULL;
- }
- }
- }
- return err;
-}
-
-M4OSA_ERR M4VSS3GPP_intSetYuv420PlaneFromARGB888 (
- M4VSS3GPP_InternalEditContext *pC,
- M4VSS3GPP_ClipContext* pClipCtxt) {
-
- M4OSA_ERR err= M4NO_ERROR;
-
- // Allocate memory for YUV plane
- pClipCtxt->pPlaneYuv =
- (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(
- 3*sizeof(M4VIFI_ImagePlane), M4VS,
- (M4OSA_Char*)"pPlaneYuv");
-
- if (pClipCtxt->pPlaneYuv == M4OSA_NULL) {
- return M4ERR_ALLOC;
- }
-
- pClipCtxt->pPlaneYuv[0].u_height =
- pClipCtxt->pSettings->ClipProperties.uiStillPicHeight;
- pClipCtxt->pPlaneYuv[0].u_width =
- pClipCtxt->pSettings->ClipProperties.uiStillPicWidth;
- pClipCtxt->pPlaneYuv[0].u_stride = pClipCtxt->pPlaneYuv[0].u_width;
- pClipCtxt->pPlaneYuv[0].u_topleft = 0;
-
- pClipCtxt->pPlaneYuv[0].pac_data =
- (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(
- pClipCtxt->pPlaneYuv[0].u_height * pClipCtxt->pPlaneYuv[0].u_width * 1.5,
- M4VS, (M4OSA_Char*)"imageClip YUV data");
- if (pClipCtxt->pPlaneYuv[0].pac_data == M4OSA_NULL) {
- free(pClipCtxt->pPlaneYuv);
- return M4ERR_ALLOC;
- }
-
- pClipCtxt->pPlaneYuv[1].u_height = pClipCtxt->pPlaneYuv[0].u_height >>1;
- pClipCtxt->pPlaneYuv[1].u_width = pClipCtxt->pPlaneYuv[0].u_width >> 1;
- pClipCtxt->pPlaneYuv[1].u_stride = pClipCtxt->pPlaneYuv[1].u_width;
- pClipCtxt->pPlaneYuv[1].u_topleft = 0;
- pClipCtxt->pPlaneYuv[1].pac_data = (M4VIFI_UInt8*)(
- pClipCtxt->pPlaneYuv[0].pac_data +
- pClipCtxt->pPlaneYuv[0].u_height * pClipCtxt->pPlaneYuv[0].u_width);
-
- pClipCtxt->pPlaneYuv[2].u_height = pClipCtxt->pPlaneYuv[0].u_height >>1;
- pClipCtxt->pPlaneYuv[2].u_width = pClipCtxt->pPlaneYuv[0].u_width >> 1;
- pClipCtxt->pPlaneYuv[2].u_stride = pClipCtxt->pPlaneYuv[2].u_width;
- pClipCtxt->pPlaneYuv[2].u_topleft = 0;
- pClipCtxt->pPlaneYuv[2].pac_data = (M4VIFI_UInt8*)(
- pClipCtxt->pPlaneYuv[1].pac_data +
- pClipCtxt->pPlaneYuv[1].u_height * pClipCtxt->pPlaneYuv[1].u_width);
-
- err = M4VSS3GPP_internalConvertAndResizeARGB8888toYUV420 (
- pClipCtxt->pSettings->pFile,
- pC->pOsaFileReadPtr,
- pClipCtxt->pPlaneYuv,
- pClipCtxt->pSettings->ClipProperties.uiStillPicWidth,
- pClipCtxt->pSettings->ClipProperties.uiStillPicHeight);
- if (M4NO_ERROR != err) {
- free(pClipCtxt->pPlaneYuv[0].pac_data);
- free(pClipCtxt->pPlaneYuv);
- return err;
- }
-
- // Set the YUV data to the decoder using setoption
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption (
- pClipCtxt->pViDecCtxt,
- M4DECODER_kOptionID_DecYuvData,
- (M4OSA_DataOption)pClipCtxt->pPlaneYuv);
- if (M4NO_ERROR != err) {
- free(pClipCtxt->pPlaneYuv[0].pac_data);
- free(pClipCtxt->pPlaneYuv);
- return err;
- }
-
- pClipCtxt->pSettings->ClipProperties.bSetImageData = M4OSA_TRUE;
-
- // Allocate Yuv plane with effect
- pClipCtxt->pPlaneYuvWithEffect =
- (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(
- 3*sizeof(M4VIFI_ImagePlane), M4VS,
- (M4OSA_Char*)"pPlaneYuvWithEffect");
- if (pClipCtxt->pPlaneYuvWithEffect == M4OSA_NULL) {
- free(pClipCtxt->pPlaneYuv[0].pac_data);
- free(pClipCtxt->pPlaneYuv);
- return M4ERR_ALLOC;
- }
-
- pClipCtxt->pPlaneYuvWithEffect[0].u_height = pC->ewc.uiVideoHeight;
- pClipCtxt->pPlaneYuvWithEffect[0].u_width = pC->ewc.uiVideoWidth;
- pClipCtxt->pPlaneYuvWithEffect[0].u_stride = pC->ewc.uiVideoWidth;
- pClipCtxt->pPlaneYuvWithEffect[0].u_topleft = 0;
-
- pClipCtxt->pPlaneYuvWithEffect[0].pac_data =
- (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(
- pC->ewc.uiVideoHeight * pC->ewc.uiVideoWidth * 1.5,
- M4VS, (M4OSA_Char*)"imageClip YUV data");
- if (pClipCtxt->pPlaneYuvWithEffect[0].pac_data == M4OSA_NULL) {
- free(pClipCtxt->pPlaneYuv[0].pac_data);
- free(pClipCtxt->pPlaneYuv);
- free(pClipCtxt->pPlaneYuvWithEffect);
- return M4ERR_ALLOC;
- }
-
- pClipCtxt->pPlaneYuvWithEffect[1].u_height =
- pClipCtxt->pPlaneYuvWithEffect[0].u_height >>1;
- pClipCtxt->pPlaneYuvWithEffect[1].u_width =
- pClipCtxt->pPlaneYuvWithEffect[0].u_width >> 1;
- pClipCtxt->pPlaneYuvWithEffect[1].u_stride =
- pClipCtxt->pPlaneYuvWithEffect[1].u_width;
- pClipCtxt->pPlaneYuvWithEffect[1].u_topleft = 0;
- pClipCtxt->pPlaneYuvWithEffect[1].pac_data = (M4VIFI_UInt8*)(
- pClipCtxt->pPlaneYuvWithEffect[0].pac_data +
- pClipCtxt->pPlaneYuvWithEffect[0].u_height * pClipCtxt->pPlaneYuvWithEffect[0].u_width);
-
- pClipCtxt->pPlaneYuvWithEffect[2].u_height =
- pClipCtxt->pPlaneYuvWithEffect[0].u_height >>1;
- pClipCtxt->pPlaneYuvWithEffect[2].u_width =
- pClipCtxt->pPlaneYuvWithEffect[0].u_width >> 1;
- pClipCtxt->pPlaneYuvWithEffect[2].u_stride =
- pClipCtxt->pPlaneYuvWithEffect[2].u_width;
- pClipCtxt->pPlaneYuvWithEffect[2].u_topleft = 0;
- pClipCtxt->pPlaneYuvWithEffect[2].pac_data = (M4VIFI_UInt8*)(
- pClipCtxt->pPlaneYuvWithEffect[1].pac_data +
- pClipCtxt->pPlaneYuvWithEffect[1].u_height * pClipCtxt->pPlaneYuvWithEffect[1].u_width);
-
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pClipCtxt->pViDecCtxt, M4DECODER_kOptionID_YuvWithEffectContiguous,
- (M4OSA_DataOption)pClipCtxt->pPlaneYuvWithEffect);
- if (M4NO_ERROR != err) {
- free(pClipCtxt->pPlaneYuv[0].pac_data);
- free(pClipCtxt->pPlaneYuv);
- free(pClipCtxt->pPlaneYuvWithEffect);
- return err;
- }
-
- return M4NO_ERROR;
-}
-
-M4OSA_ERR M4VSS3GPP_intRenderFrameWithEffect(M4VSS3GPP_InternalEditContext *pC,
- M4VSS3GPP_ClipContext* pClipCtxt,
- M4_MediaTime ts,
- M4OSA_Bool bIsClip1,
- M4VIFI_ImagePlane *pResizePlane,
- M4VIFI_ImagePlane *pPlaneNoResize,
- M4VIFI_ImagePlane *pPlaneOut) {
-
- M4OSA_ERR err = M4NO_ERROR;
- M4OSA_UInt8 numEffects = 0;
- M4VIFI_ImagePlane *pDecoderRenderFrame = M4OSA_NULL;
- M4OSA_UInt32 yuvFrameWidth = 0, yuvFrameHeight = 0;
- M4VIFI_ImagePlane* pTmp = M4OSA_NULL;
- M4VIFI_ImagePlane pTemp[3];
- M4OSA_UInt8 i = 0;
- M4OSA_Bool bSkipFramingEffect = M4OSA_FALSE;
-
- memset((void *)pTemp, 0, 3*sizeof(M4VIFI_ImagePlane));
- /* Resize or rotate case */
- if (M4OSA_NULL != pClipCtxt->m_pPreResizeFrame) {
- /**
- * If we do modify the image, we need an intermediate image plane */
- err = M4VSS3GPP_intAllocateYUV420(pResizePlane,
- pClipCtxt->m_pPreResizeFrame[0].u_width,
- pClipCtxt->m_pPreResizeFrame[0].u_height);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- M4VSS3GPP_intAllocateYUV420 returns 0x%x", err);
- return err;
- }
-
- if ((pClipCtxt->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (pC->nbActiveEffects == 0) &&
- (pClipCtxt->bGetYuvDataFromDecoder == M4OSA_FALSE)) {
-
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pClipCtxt->pViDecCtxt,
- M4DECODER_kOptionID_EnableYuvWithEffect,
- (M4OSA_DataOption)M4OSA_TRUE);
- if (M4NO_ERROR == err) {
- pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pClipCtxt->pViDecCtxt, &ts,
- pClipCtxt->pPlaneYuvWithEffect, M4OSA_TRUE);
- }
-
- } else {
- if (pClipCtxt->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) {
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pClipCtxt->pViDecCtxt,
- M4DECODER_kOptionID_EnableYuvWithEffect,
- (M4OSA_DataOption)M4OSA_FALSE);
- }
- if (M4NO_ERROR == err) {
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pClipCtxt->pViDecCtxt, &ts,
- pClipCtxt->m_pPreResizeFrame, M4OSA_TRUE);
- }
-
- }
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- returns error 0x%x", err);
- return err;
- }
-
- if (pClipCtxt->pSettings->FileType !=
- M4VIDEOEDITING_kFileType_ARGB8888) {
- if (0 != pClipCtxt->pSettings->ClipProperties.videoRotationDegrees) {
- // Save width and height of un-rotated frame
- yuvFrameWidth = pClipCtxt->m_pPreResizeFrame[0].u_width;
- yuvFrameHeight = pClipCtxt->m_pPreResizeFrame[0].u_height;
- err = M4VSS3GPP_intRotateVideo(pClipCtxt->m_pPreResizeFrame,
- pClipCtxt->pSettings->ClipProperties.videoRotationDegrees);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- rotateVideo() returns error 0x%x", err);
- return err;
- }
- /* Set the new video size for temporary buffer */
- M4VSS3GPP_intSetYUV420Plane(pResizePlane,
- pClipCtxt->m_pPreResizeFrame[0].u_width,
- pClipCtxt->m_pPreResizeFrame[0].u_height);
- }
- }
-
- if (bIsClip1 == M4OSA_TRUE) {
- pC->bIssecondClip = M4OSA_FALSE;
- numEffects = pC->nbActiveEffects;
- } else {
- numEffects = pC->nbActiveEffects1;
- pC->bIssecondClip = M4OSA_TRUE;
- }
-
- if ( numEffects > 0) {
- pClipCtxt->bGetYuvDataFromDecoder = M4OSA_TRUE;
- /* If video frame need to be resized or rotated,
- * then apply the overlay after the frame was rendered with rendering mode.
- * Here skip the framing(overlay) effect when applying video Effect. */
- bSkipFramingEffect = M4OSA_TRUE;
- err = M4VSS3GPP_intApplyVideoEffect(pC,
- pClipCtxt->m_pPreResizeFrame, pResizePlane, bSkipFramingEffect);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- M4VSS3GPP_intApplyVideoEffect() err 0x%x", err);
- return err;
- }
- pDecoderRenderFrame= pResizePlane;
- } else {
- pDecoderRenderFrame = pClipCtxt->m_pPreResizeFrame;
- }
- /* Do rendering mode */
- if ((pClipCtxt->bGetYuvDataFromDecoder == M4OSA_TRUE) ||
- (pClipCtxt->pSettings->FileType !=
- M4VIDEOEDITING_kFileType_ARGB8888)) {
- if (bIsClip1 == M4OSA_TRUE) {
- if (pC->bClip1ActiveFramingEffect == M4OSA_TRUE) {
- err = M4VSS3GPP_intAllocateYUV420(pTemp,
- pPlaneOut[0].u_width, pPlaneOut[0].u_height);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intAllocateYUV420 error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pTmp = pTemp;
- } else {
- pTmp = pC->yuv1;
- }
- err = M4VSS3GPP_intApplyRenderingMode (pC,
- pClipCtxt->pSettings->xVSS.MediaRendering,
- pDecoderRenderFrame,pTmp);
- } else {
- if (pC->bClip2ActiveFramingEffect == M4OSA_TRUE) {
- err = M4VSS3GPP_intAllocateYUV420(pTemp,
- pPlaneOut[0].u_width, pPlaneOut[0].u_height);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intAllocateYUV420 error 0x%x", err);
- pC->ewc.VppError = err;
- return M4NO_ERROR;
- }
- pTmp = pTemp;
- } else {
- pTmp = pC->yuv2;
- }
- err = M4VSS3GPP_intApplyRenderingMode (pC,
- pClipCtxt->pSettings->xVSS.MediaRendering,
- pDecoderRenderFrame,pTmp);
- }
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- M4VSS3GPP_intApplyRenderingMode error 0x%x ", err);
- for (i=0; i<3; i++) {
- if (pTemp[i].pac_data != M4OSA_NULL) {
- free(pTemp[i].pac_data);
- pTemp[i].pac_data = M4OSA_NULL;
- }
- }
- return err;
- }
- /* Apply overlay if overlay exist*/
- if (bIsClip1 == M4OSA_TRUE) {
- if (pC->bClip1ActiveFramingEffect == M4OSA_TRUE) {
- err = M4VSS3GPP_intApplyVideoOverlay(pC,
- pTemp, pC->yuv1);
- }
- pClipCtxt->lastDecodedPlane = pC->yuv1;
- } else {
- if (pC->bClip2ActiveFramingEffect == M4OSA_TRUE) {
- err = M4VSS3GPP_intApplyVideoOverlay(pC,
- pTemp, pC->yuv2);
- }
- pClipCtxt->lastDecodedPlane = pC->yuv2;
- }
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intVPP: \
- M4VSS3GPP_intApplyVideoOverlay) error 0x%x ", err);
- pC->ewc.VppError = err;
- for (i=0; i<3; i++) {
- if (pTemp[i].pac_data != M4OSA_NULL) {
- free(pTemp[i].pac_data);
- pTemp[i].pac_data = M4OSA_NULL;
- }
- }
- return M4NO_ERROR;
- }
- } else {
- pClipCtxt->lastDecodedPlane = pClipCtxt->pPlaneYuvWithEffect;
- }
- // free the temp buffer
- for (i=0; i<3; i++) {
- if (pTemp[i].pac_data != M4OSA_NULL) {
- free(pTemp[i].pac_data);
- pTemp[i].pac_data = M4OSA_NULL;
- }
- }
-
- if ((pClipCtxt->pSettings->FileType ==
- M4VIDEOEDITING_kFileType_ARGB8888) &&
- (pC->nbActiveEffects == 0) &&
- (pClipCtxt->bGetYuvDataFromDecoder == M4OSA_TRUE)) {
- if (bIsClip1 == M4OSA_TRUE) {
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pClipCtxt->pViDecCtxt,
- M4DECODER_kOptionID_YuvWithEffectNonContiguous,
- (M4OSA_DataOption)pC->yuv1);
- } else {
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
- pClipCtxt->pViDecCtxt,
- M4DECODER_kOptionID_YuvWithEffectNonContiguous,
- (M4OSA_DataOption)pC->yuv2);
- }
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- null decoder setOption error 0x%x ", err);
- return err;
- }
- pClipCtxt->bGetYuvDataFromDecoder = M4OSA_FALSE;
- }
-
- // Reset original width and height for resize frame plane
- if (0 != pClipCtxt->pSettings->ClipProperties.videoRotationDegrees &&
- 180 != pClipCtxt->pSettings->ClipProperties.videoRotationDegrees) {
-
- M4VSS3GPP_intSetYUV420Plane(pClipCtxt->m_pPreResizeFrame,
- yuvFrameWidth, yuvFrameHeight);
- }
-
- } else {
- /* No rotate or no resize case*/
- if (bIsClip1 == M4OSA_TRUE) {
- numEffects = pC->nbActiveEffects;
- } else {
- numEffects = pC->nbActiveEffects1;
- }
-
- if(numEffects > 0) {
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pClipCtxt->pViDecCtxt, &ts, pPlaneNoResize, M4OSA_TRUE);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- Render returns error 0x%x", err);
- return err;
- }
-
- bSkipFramingEffect = M4OSA_FALSE;
- if (bIsClip1 == M4OSA_TRUE) {
- pC->bIssecondClip = M4OSA_FALSE;
- err = M4VSS3GPP_intApplyVideoEffect(pC, pPlaneNoResize,
- pC->yuv1, bSkipFramingEffect);
- pClipCtxt->lastDecodedPlane = pC->yuv1;
- } else {
- pC->bIssecondClip = M4OSA_TRUE;
- err = M4VSS3GPP_intApplyVideoEffect(pC, pPlaneNoResize,
- pC->yuv2, bSkipFramingEffect);
- pClipCtxt->lastDecodedPlane = pC->yuv2;
- }
-
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- M4VSS3GPP_intApplyVideoEffect error 0x%x", err);
- return err;
- }
- } else {
-
- if (bIsClip1 == M4OSA_TRUE) {
- pTmp = pC->yuv1;
- } else {
- pTmp = pC->yuv2;
- }
- err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctRender(
- pClipCtxt->pViDecCtxt, &ts, pTmp, M4OSA_TRUE);
- if (M4NO_ERROR != err) {
- M4OSA_TRACE1_1("M4VSS3GPP_intRenderFrameWithEffect: \
- Render returns error 0x%x,", err);
- return err;
- }
- pClipCtxt->lastDecodedPlane = pTmp;
- }
- pClipCtxt->iVideoRenderCts = (M4OSA_Int32)ts;
- }
-
- return err;
-}
-
-M4OSA_ERR M4VSS3GPP_intRotateVideo(M4VIFI_ImagePlane* pPlaneIn,
- M4OSA_UInt32 rotationDegree) {
-
- M4OSA_ERR err = M4NO_ERROR;
- M4VIFI_ImagePlane outPlane[3];
-
- if (rotationDegree != 180) {
- // Swap width and height of in plane
- outPlane[0].u_width = pPlaneIn[0].u_height;
- outPlane[0].u_height = pPlaneIn[0].u_width;
- outPlane[0].u_stride = outPlane[0].u_width;
- outPlane[0].u_topleft = 0;
- outPlane[0].pac_data = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(
- (outPlane[0].u_stride*outPlane[0].u_height), M4VS,
- (M4OSA_Char*)("out Y plane for rotation"));
- if (outPlane[0].pac_data == M4OSA_NULL) {
- return M4ERR_ALLOC;
- }
-
- outPlane[1].u_width = pPlaneIn[0].u_height/2;
- outPlane[1].u_height = pPlaneIn[0].u_width/2;
- outPlane[1].u_stride = outPlane[1].u_width;
- outPlane[1].u_topleft = 0;
- outPlane[1].pac_data = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(
- (outPlane[1].u_stride*outPlane[1].u_height), M4VS,
- (M4OSA_Char*)("out U plane for rotation"));
- if (outPlane[1].pac_data == M4OSA_NULL) {
- free((void *)outPlane[0].pac_data);
- return M4ERR_ALLOC;
- }
-
- outPlane[2].u_width = pPlaneIn[0].u_height/2;
- outPlane[2].u_height = pPlaneIn[0].u_width/2;
- outPlane[2].u_stride = outPlane[2].u_width;
- outPlane[2].u_topleft = 0;
- outPlane[2].pac_data = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(
- (outPlane[2].u_stride*outPlane[2].u_height), M4VS,
- (M4OSA_Char*)("out V plane for rotation"));
- if (outPlane[2].pac_data == M4OSA_NULL) {
- free((void *)outPlane[0].pac_data);
- free((void *)outPlane[1].pac_data);
- return M4ERR_ALLOC;
- }
- }
-
- switch(rotationDegree) {
- case 90:
- M4VIFI_Rotate90RightYUV420toYUV420(M4OSA_NULL, pPlaneIn, outPlane);
- break;
-
- case 180:
- // In plane rotation, so planeOut = planeIn
- M4VIFI_Rotate180YUV420toYUV420(M4OSA_NULL, pPlaneIn, pPlaneIn);
- break;
-
- case 270:
- M4VIFI_Rotate90LeftYUV420toYUV420(M4OSA_NULL, pPlaneIn, outPlane);
- break;
-
- default:
- M4OSA_TRACE1_1("invalid rotation param %d", (int)rotationDegree);
- err = M4ERR_PARAMETER;
- break;
- }
-
- if (rotationDegree != 180) {
- memset((void *)pPlaneIn[0].pac_data, 0,
- (pPlaneIn[0].u_width*pPlaneIn[0].u_height));
- memset((void *)pPlaneIn[1].pac_data, 0,
- (pPlaneIn[1].u_width*pPlaneIn[1].u_height));
- memset((void *)pPlaneIn[2].pac_data, 0,
- (pPlaneIn[2].u_width*pPlaneIn[2].u_height));
- // Copy Y, U and V planes
- memcpy((void *)pPlaneIn[0].pac_data, (void *)outPlane[0].pac_data,
- (pPlaneIn[0].u_width*pPlaneIn[0].u_height));
- memcpy((void *)pPlaneIn[1].pac_data, (void *)outPlane[1].pac_data,
- (pPlaneIn[1].u_width*pPlaneIn[1].u_height));
- memcpy((void *)pPlaneIn[2].pac_data, (void *)outPlane[2].pac_data,
- (pPlaneIn[2].u_width*pPlaneIn[2].u_height));
-
- free((void *)outPlane[0].pac_data);
- free((void *)outPlane[1].pac_data);
- free((void *)outPlane[2].pac_data);
-
- // Swap the width and height of the in plane
- uint32_t temp = 0;
- temp = pPlaneIn[0].u_width;
- pPlaneIn[0].u_width = pPlaneIn[0].u_height;
- pPlaneIn[0].u_height = temp;
- pPlaneIn[0].u_stride = pPlaneIn[0].u_width;
-
- temp = pPlaneIn[1].u_width;
- pPlaneIn[1].u_width = pPlaneIn[1].u_height;
- pPlaneIn[1].u_height = temp;
- pPlaneIn[1].u_stride = pPlaneIn[1].u_width;
-
- temp = pPlaneIn[2].u_width;
- pPlaneIn[2].u_width = pPlaneIn[2].u_height;
- pPlaneIn[2].u_height = temp;
- pPlaneIn[2].u_stride = pPlaneIn[2].u_width;
- }
-
- return err;
-}
-
-M4OSA_ERR M4VSS3GPP_intSetYUV420Plane(M4VIFI_ImagePlane* planeIn,
- M4OSA_UInt32 width, M4OSA_UInt32 height) {
-
- M4OSA_ERR err = M4NO_ERROR;
-
- if (planeIn == M4OSA_NULL) {
- M4OSA_TRACE1_0("NULL in plane, error");
- return M4ERR_PARAMETER;
- }
-
- planeIn[0].u_width = width;
- planeIn[0].u_height = height;
- planeIn[0].u_stride = planeIn[0].u_width;
-
- planeIn[1].u_width = width/2;
- planeIn[1].u_height = height/2;
- planeIn[1].u_stride = planeIn[1].u_width;
-
- planeIn[2].u_width = width/2;
- planeIn[2].u_height = height/2;
- planeIn[2].u_stride = planeIn[1].u_width;
-
- return err;
-}