diff options
Diffstat (limited to 'libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c')
-rwxr-xr-x | libvideoeditor/vss/src/M4VSS3GPP_EditVideo.c | 3955 |
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, ¤tBitrate); - - 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; -} |