diff options
Diffstat (limited to 'libvideoeditor/vss/mcs/src/M4MCS_API.c')
-rwxr-xr-x | libvideoeditor/vss/mcs/src/M4MCS_API.c | 10949 |
1 files changed, 0 insertions, 10949 deletions
diff --git a/libvideoeditor/vss/mcs/src/M4MCS_API.c b/libvideoeditor/vss/mcs/src/M4MCS_API.c deleted file mode 100755 index c056ef0..0000000 --- a/libvideoeditor/vss/mcs/src/M4MCS_API.c +++ /dev/null @@ -1,10949 +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 M4MCS_API.c - * @brief MCS implementation (Video Compressor Service) - * @note This file implements the API and the processing of the MCS - ************************************************************************* - **/ - -/** - ******************************************************************** - * Includes - ******************************************************************** - */ -/** - * OSAL headers */ -#include "M4OSA_Memory.h" /**< OSAL memory management */ -#include "M4OSA_Debug.h" /**< OSAL debug management */ - -/* PCM samples */ -#include "VideoEditorResampler.h" -/** - * Decoder interface */ -#include "M4DECODER_Common.h" - -/* Encoder interface*/ -#include "M4ENCODER_common.h" - -/* Enable for DEBUG logging */ -//#define MCS_DUMP_PCM_TO_FILE -#ifdef MCS_DUMP_PCM_TO_FILE -#include <stdio.h> -FILE *file_au_reader = NULL; -FILE *file_pcm_decoder = NULL; -FILE *file_pcm_encoder = NULL; -#endif - -/* Core headers */ -#include "M4MCS_API.h" -#include "M4MCS_ErrorCodes.h" -#include "M4MCS_InternalTypes.h" -#include "M4MCS_InternalConfig.h" -#include "M4MCS_InternalFunctions.h" - -#ifdef M4MCS_SUPPORT_STILL_PICTURE -#include "M4MCS_StillPicture.h" -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - -/* Common headers (for aac) */ -#include "M4_Common.h" - -#include "NXPSW_CompilerSwitches.h" - -#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS -#include "M4VD_EXTERNAL_Interface.h" -#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ - -#include "M4AIR_API.h" -#include "OMX_Video.h" - -/* Version */ -#define M4MCS_VERSION_MAJOR 3 -#define M4MCS_VERSION_MINOR 4 -#define M4MCS_VERSION_REVISION 3 - -/** - ******************************************************************** - * Static local functions - ******************************************************************** - */ - -static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intPrepareVideoDecoder( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intPrepareVideoEncoder( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intPrepareAudioProcessing( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intStepEncoding( - M4MCS_InternalContext *pC, - M4OSA_UInt8 *pTranscodedTime ); -static M4OSA_ERR M4MCS_intStepBeginVideoJump( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intStepBeginVideoDecode( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intGetInputClipProperties( - M4MCS_InternalContext *pContext ); -static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( - M4OSA_MemAddr8 pAudioFrame ); -static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( - M4OSA_MemAddr8 pAudioFrame ); -static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext ); -static M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate( - M4OSA_Int32 freebitrate, - M4OSA_Int8 mode ); -static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( - M4MCS_InternalContext *pC ); -static M4OSA_ERR M4MCS_intReallocTemporaryAU( - M4OSA_MemAddr8 *addr, - M4OSA_UInt32 newSize ); -static M4OSA_ERR M4MCS_intCheckAndGetCodecProperties( - M4MCS_InternalContext *pC); - -static M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel( - M4ENCODER_AdvancedParams* EncParams); -static M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate); -static M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate); -static M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate); - -/** - ********************************************************************** - * External function used only by VideoEditor and that does not appear - * in the API - ********************************************************************** - */ - -M4OSA_ERR M4MCS_open_normalMode( M4MCS_Context pContext, - M4OSA_Void *pFileIn, - M4VIDEOEDITING_FileType InputFileType, - M4OSA_Void *pFileOut, - M4OSA_Void *pTempFile ); - -/* All errors are fatal in the MCS */ -#define M4ERR_CHECK_RETURN(err) if(M4NO_ERROR!=err) return err; - -/* A define used with SSRC 1.04 and above to avoid taking blocks smaller - * that the minimal block size - */ -#define M4MCS_SSRC_MINBLOCKSIZE 100 - -static M4OSA_UChar Tab_MCS[8] = -{ - 17, 5, 3, 3, 1, 1, 1, 1 -}; - -M4OSA_ERR H264MCS_Getinstance( NSWAVC_MCS_t ** instance ) -{ - NSWAVC_MCS_t *p_bs = M4OSA_NULL; - M4OSA_ERR err = M4NO_ERROR; - p_bs = (NSWAVC_MCS_t *)M4OSA_32bitAlignedMalloc(sizeof(NSWAVC_MCS_t), M4MCS, - (M4OSA_Char *)"NSWAVC_MCS_t"); - - if( M4OSA_NULL == p_bs ) - { - M4OSA_TRACE1_0("H264MCS_Getinstance: allocation error"); - return M4ERR_ALLOC; - } - - p_bs->prev_frame_num = 0; - p_bs->cur_frame_num = 0; - p_bs->log2_max_frame_num_minus4 = 0; - p_bs->prev_new_frame_num = 0; - p_bs->is_done = 0; - p_bs->is_first = 1; - - p_bs->m_pDecoderSpecificInfo = M4OSA_NULL; - p_bs->m_decoderSpecificInfoSize = 0; - - p_bs->m_pEncoderSPS = M4OSA_NULL; - p_bs->m_encoderSPSSize = 0; - - p_bs->m_pEncoderPPS = M4OSA_NULL; - p_bs->m_encoderPPSSize = 0; - - p_bs->m_pFinalDSI = M4OSA_NULL; - p_bs->m_pFinalDSISize = 0; - - p_bs->p_clip_sps = M4OSA_NULL; - p_bs->m_encoder_SPS_Cnt = 0; - - p_bs->p_clip_pps = M4OSA_NULL; - p_bs->m_encoder_PPS_Cnt = 0; - - p_bs->p_encoder_sps = M4OSA_NULL; - p_bs->p_encoder_pps = M4OSA_NULL; - - p_bs->encoder_pps.slice_group_id = M4OSA_NULL; - - *instance = (NSWAVC_MCS_t *)p_bs; - return err; -} - -M4OSA_UInt32 H264MCS_getBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits ) -{ - M4OSA_UInt32 ui32RetBits; - M4OSA_UInt8 *pbs; - M4OSA_Int32 bcnt; - p_bs->i8BitCnt -= numBits; - bcnt = p_bs->i8BitCnt; - - /* Measure the quantity of bits to be read in ui32TempBuff */ - ui32RetBits = p_bs->ui32TempBuff >> (32 - numBits); - - /* Read numBits in ui32TempBuff */ - p_bs->ui32TempBuff <<= numBits; - p_bs->bitPos += numBits; - - if( bcnt > 24 ) - { - return (ui32RetBits); - } - else - { /* at least one byte can be buffered in ui32TempBuff */ - pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr; - - if( bcnt < (int)(p_bs->numBitsInBuffer - p_bs->bitPos) ) - { /* not enough remaining bits in ui32TempBuff: need to be filled */ - do - { - /* On the fly detection of EPB byte */ - if( ( *(pbs) == 0x03) - && (!(( pbs[-1]) - | (pbs[-2])))) //(p_bs->ui32LastTwoBytes & 0x0000FFFF) == 0) - { - /* EPB byte found: skip it and update bitPos accordingly */ - (pbs)++; - p_bs->bitPos += 8; - } - - p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt); - bcnt += 8; - } while ( bcnt <= 24 ); - - p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs; - p_bs->i8BitCnt = bcnt; - return (ui32RetBits); - } - } - - if( p_bs->bitPos <= p_bs->numBitsInBuffer ) - { - return (ui32RetBits); - } - else - { - return (0); - } -} - -M4OSA_Void H264MCS_flushBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits ) -{ - M4OSA_UInt8 *pbs; - M4OSA_UInt32 bcnt; - p_bs->i8BitCnt -= numBits; - bcnt = p_bs->i8BitCnt; - - p_bs->ui32TempBuff <<= numBits; - p_bs->bitPos += numBits; - - if( bcnt > 24 ) - { - return; - } - else - { /* at least one byte can be buffered in ui32TempBuff */ - pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr; - - if( bcnt < (p_bs->numBitsInBuffer - p_bs->bitPos) ) - { /* Not enough remaining bits in ui32TempBuff: need to be filled */ - do - { - /* On the fly detection of EPB byte */ - if( ( *(pbs) == 0x03) && (!(( pbs[-1]) | (pbs[-2]))) ) - { /* JC: EPB byte found: skip it and update bitPos accordingly */ - (pbs)++; - p_bs->bitPos += 8; - } - p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt); - bcnt += 8; - } while ( bcnt <= 24 ); - - p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs; - p_bs->i8BitCnt = bcnt; - } - } - - return; -} - -M4OSA_UInt32 H264MCS_DecVLCReadExpGolombCode( ComBitStreamMCS_t *p_bs ) -{ - M4OSA_UInt32 code, l0 = 0, l1; - /* Reading 32 Bits from local cache buffer of Bitstream structure*/ - code = p_bs->ui32TempBuff; - - /* Checking in first 3 bits*/ - if( code >> 29 ) - { - l0 = Tab_MCS[(code >> 29)]; - code = code >> (32 - l0); - H264MCS_flushBits(p_bs, l0); - } - else - { - if( code ) - { - code <<= 3; - - for ( l0 = 3; code < 0x80000000; code <<= 1, l0++ ); - - if( l0 < 16 ) /*all useful bits are inside the 32 bits read */ - { - code = code >> (31 - l0); - H264MCS_flushBits(p_bs, 2 * l0 + 1); - } - else - { /* Read the useful bits in 2 parts */ - l1 = ( l0 << 1) - 31; - code >>= l0; - H264MCS_flushBits(p_bs, 32); - code = ( code << l1) | H264MCS_getBits(p_bs, l1); - } - } - else - { - H264MCS_flushBits(p_bs, 32); - - if( H264MCS_getBits(p_bs, 1) ) - { - /* if number of leading 0's is 32, the only code allowed is 1 followed - by 32 0's */ - - /*reading 32 more bits from bitstream buffer*/ - code = H264MCS_getBits(p_bs, 32); - - if( code == 0 ) - { - return (code - 1); - } - } - /*if number of leading 0's is >32, then symbol is >32 bits, - which is an error */ - //p_bs->state = _BS_ERR; - //p_bs->flags |= _BF_SYM_ERR; - return (0); - } - } - - if( 1 ) //(p_bs->state == _BS_OK) - { - return (code - 1); - } - else - { - return (0); - } - } - -M4OSA_Int32 H264MCS_DecVLCReadSignedExpGolombCode( ComBitStreamMCS_t *p_bs ) -{ - M4OSA_Int32 codeNo, ret; - - /* read the unsigned code number */ - codeNo = H264MCS_DecVLCReadExpGolombCode(p_bs); - - /* map to the signed value, if value is odd then it's positive, - if even then it's negative, formula is (-1)^(k+1)*CEIL(k/2) */ - - ret = (codeNo & 0x01) ? (( codeNo + 1) >> 1) : (( -codeNo) >> 1); - - return ret; -} - -M4OSA_Void DecBitStreamReset_MCS( ComBitStreamMCS_t *p_bs, - M4OSA_UInt32 bytes_read ) -{ - p_bs->bitPos = 0; - - p_bs->lastTotalBits = 0; - p_bs->numBitsInBuffer = bytes_read << 3; - p_bs->readableBytesInBuffer = bytes_read; - //p_bs->state = M4NO_ERROR;//_BS_OK; - //p_bs->flags = 0; - - p_bs->ui32TempBuff = 0; - p_bs->i8BitCnt = 0; - p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer; - p_bs->ui32LastTwoBytes = 0xFFFFFFFF; - H264MCS_getBits(p_bs, 0); -} - -M4OSA_ERR NSWAVCMCS_initBitstream( NSWAVC_bitStream_t_MCS *bS ) -{ - bS->bitPos = 0; - bS->byteCnt = 0; - bS->currBuff = 0; - bS->prevByte = 0xff; - bS->prevPrevByte = 0xff; - - return M4NO_ERROR; -} - -M4OSA_ERR NSWAVCMCS_putBits( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value, - M4OSA_UInt8 length ) -{ - M4OSA_UInt32 maskedValue = 0, temp = 0; - M4OSA_UInt8 byteOne; - - M4OSA_UInt32 len1 = (length == 32) ? 31 : length; - - if( !(length) ) - { - /* Length = 0, return OK*/ - return M4NO_ERROR; - } - - maskedValue = (M4OSA_UInt32)(value &(( 1 << len1) - 1)); - - if( 32 > (length + bS->bitPos) ) - { - bS->bitPos += length; - bS->currBuff |= maskedValue << (32 - bS->bitPos); - } - else - { - temp = (( bS->bitPos + length) - 32); - - bS->currBuff |= (maskedValue >> (temp)); - - byteOne = - bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)((bS->currBuff) &0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - - bS->currBuff = 0; - - bS->currBuff |= ( maskedValue &(( 1 << temp) - 1)) << (32 - temp); - - bS->bitPos = temp; - } - - return M4NO_ERROR; -} - -M4OSA_ERR NSWAVCMCS_putBit( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value ) -{ - M4OSA_UInt32 maskedValue = 0, temp = 0; - M4OSA_UInt8 byteOne; - - maskedValue = (value ? 1 : 0); - - if( 32 > (1 + bS->bitPos) ) - { - bS->bitPos += 1; - bS->currBuff |= maskedValue << (32 - bS->bitPos); - } - else - { - temp = 0; - - bS->currBuff |= (maskedValue); - - /* writing it to memory*/ - byteOne = - bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(bS->currBuff >> 24); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - byteOne = bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)((bS->currBuff) &0xff); - - if( (( bS->prevPrevByte - == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) ) - { - bS->byteCnt -= 1; - bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03; - bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne; - } - else - { - bS->prevPrevByte = bS->prevByte; - bS->prevByte = byteOne; - } - bS->currBuff = 0; - bS->bitPos = 0; - } - - return M4NO_ERROR; -} - -M4OSA_Int32 NSWAVCMCS_putRbspTbits( NSWAVC_bitStream_t_MCS *bS ) -{ - M4OSA_UInt8 trailBits = 0; - M4OSA_UInt8 byteCnt = 0; - - trailBits = (M4OSA_UInt8)(bS->bitPos % 8); - - /* Already in the byte aligned position, - RBSP trailing bits will be 1000 0000 */ - if( 0 == trailBits ) - { - trailBits = (1 << 7); - NSWAVCMCS_putBits(bS, trailBits, 8); - } - else - { - trailBits = (8 - trailBits); - NSWAVCMCS_putBit(bS, 1); - trailBits--; - - if( trailBits ) - { /* put trailBits times zeros */ - NSWAVCMCS_putBits(bS, 0, trailBits); - } - } - - /* For writting the currBuff in streamBuff 4byte alignment is required*/ - byteCnt = (M4OSA_UInt8)(( bS->bitPos + 4) / 8); - - switch( byteCnt ) - { - case 1: - bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24); - break; - - case 2: - bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24); - bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff); - break; - - case 3: - bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24); - bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff); - bS->streamBuffer[bS->byteCnt++] = - (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff); - - break; - - default: - /* It will not come here */ - break; - } - - // bS->bitPos =0; - // bS->currBuff = 0; - - return M4NO_ERROR; -} - -M4OSA_ERR NSWAVCMCS_uExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum ) -{ - - M4OSA_Int32 loop, temp; - M4OSA_Int32 data = 0; - M4OSA_UInt8 codeLen = 0; - - /* The codeNum cannot be less than zero for this ue(v) */ - if( codeNum < 0 ) - { - return 0; - } - - /* Implementation for Encoding of the Table 9-1 in the Standard */ - temp = codeNum + 1; - - for ( loop = 0; temp != 0; loop++ ) - { - temp /= 2; - } - - codeLen = (( loop * 2) - 1); - - data = codeNum + 1; - - NSWAVCMCS_putBits(bS, data, codeLen); - - return M4NO_ERROR; -} - -M4OSA_ERR NSWAVCMCS_sExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum ) -{ - - M4OSA_Int32 loop, temp1, temp2; - M4OSA_Int32 data = 0; - M4OSA_UInt8 codeLen = 0, isPositive = 0; - M4OSA_UInt32 abscodeNum; - - if( codeNum > 0 ) - { - isPositive = 1; - } - - if( codeNum > 0 ) - { - abscodeNum = codeNum; - } - else - { - abscodeNum = -codeNum; - } - - temp1 = ( ( ( abscodeNum) << 1) - isPositive) + 1; - temp2 = temp1; - - for ( loop = 0; loop < 16 && temp2 != 0; loop++ ) - { - temp2 /= 2; - } - - codeLen = ( loop * 2) - 1; - - data = temp1; - - NSWAVCMCS_putBits(bS, data, codeLen); - - return M4NO_ERROR; -} - -M4OSA_ERR H264MCS_ProcessEncodedNALU( M4OSA_Void *ainstance, - M4OSA_UInt8 *inbuff, - M4OSA_Int32 inbuf_size, - M4OSA_UInt8 *outbuff, - M4OSA_Int32 *outbuf_size ) -{ - ComBitStreamMCS_t *p_bs, bs; - NSWAVC_MCS_t *instance; - M4OSA_UInt8 nalu_info; - M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type; - M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num; - M4OSA_Int32 seq_parameter_set_id; - M4OSA_UInt8 temp1, temp2, temp3, temp4; - M4OSA_Int32 temp_frame_num; - M4OSA_Int32 bitstoDiacard, bytes; - M4OSA_UInt32 mask_bits = 0xFFFFFFFF; - M4OSA_Int32 new_bytes, init_bit_pos; - M4OSA_UInt32 nal_size; - M4OSA_UInt32 cnt; - M4OSA_UInt32 outbuffpos = 0; - M4OSA_UInt32 nal_size_low16, nal_size_high16; - M4OSA_UInt32 frame_size = 0; - M4OSA_UInt32 temp = 0; - - // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it - M4OSA_Int8 *pTmpBuff1 = M4OSA_NULL; - M4OSA_Int8 *pTmpBuff2 = M4OSA_NULL; - - p_bs = &bs; - instance = (NSWAVC_MCS_t *)ainstance; - - M4OSA_TRACE1_2( - "In H264MCS_ProcessEncodedNALU with FrameSize = %d inBuf_Size=%d", - frame_size, inbuf_size); - - // StageFright codecs may add a start code, make sure it is not present - - if( !memcmp((void *)inbuff, - "\x00\x00\x00\x01", 4) ) - { - M4OSA_TRACE1_3( - "H264MCS_ProcessNALU ERROR : NALU start code has not been removed %d " - "0x%X 0x%X", inbuf_size, ((M4OSA_UInt32 *)inbuff)[0], - ((M4OSA_UInt32 *)inbuff)[1]); - - return M4ERR_PARAMETER; - } - - // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it - pTmpBuff1 = (M4OSA_Int8 *)M4OSA_32bitAlignedMalloc(inbuf_size + 4, M4MCS, - (M4OSA_Char *)"tmpNALU"); - memcpy((void *)(pTmpBuff1 + 4), (void *)inbuff, - inbuf_size); - pTmpBuff1[3] = ( (M4OSA_UInt32)inbuf_size) & 0x000000FF; - pTmpBuff1[2] = ( (M4OSA_UInt32)inbuf_size >> 8) & 0x000000FF; - pTmpBuff1[1] = ( (M4OSA_UInt32)inbuf_size >> 16) & 0x000000FF; - pTmpBuff1[0] = ( (M4OSA_UInt32)inbuf_size >> 24) & 0x000000FF; - pTmpBuff2 = (M4OSA_Int8 *)inbuff; - inbuff = (M4OSA_UInt8 *)pTmpBuff1; - inbuf_size += 4; - - // Make sure the available size was set - if( inbuf_size >= *outbuf_size ) - { - M4OSA_TRACE1_1( - "!!! H264MCS_ProcessNALU ERROR : specified available size is incorrect %d ", - *outbuf_size); - return M4ERR_PARAMETER; - } - - - - while( (M4OSA_Int32)frame_size < inbuf_size ) - { - mask_bits = 0xFFFFFFFF; - p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size); - - // Use unsigned value to fix errors due to bit sign extension, this fix should be generic - - nal_size_high16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[0] << 8) - + ((M4OSA_UInt8 *)p_bs->Buffer)[1]; - nal_size_low16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[2] << 8) - + ((M4OSA_UInt8 *)p_bs->Buffer)[3]; - - nalu_info = (unsigned char)p_bs->Buffer[4]; - - outbuff[outbuffpos] = p_bs->Buffer[4]; - - p_bs->Buffer = p_bs->Buffer + 5; - - p_bs->bitPos = 0; - p_bs->lastTotalBits = 0; - p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3; - p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5; - - p_bs->ui32TempBuff = 0; - p_bs->i8BitCnt = 0; - p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer; - p_bs->ui32LastTwoBytes = 0xFFFFFFFF; - - H264MCS_getBits(p_bs, 0); - - nal_size = ( nal_size_high16 << 16) + nal_size_low16; - - frame_size += nal_size + 4; - - forbidden_bit = ( nalu_info >> 7) & 1; - nal_ref_idc = ( nalu_info >> 5) & 3; - nal_unit_type = (nalu_info) &0x1f; - - NSWAVCMCS_initBitstream(&instance->encbs); - - instance->encbs.streamBuffer = outbuff + outbuffpos + 1; - - if( nal_unit_type == 8 ) - { - M4OSA_TRACE1_0("Error : PPS"); - return 0; - } - - if( nal_unit_type == 7 ) - { - /*SPS Packet */ - M4OSA_TRACE1_0("Error : SPS"); - return 0; - } - - if( (nal_unit_type == 5) ) - { - instance->frame_count = 0; - instance->POC_lsb = 0; - } - - if( ( nal_unit_type == 1) || (nal_unit_type == 5) ) - { - first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs); - slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs); - pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs); - - /* First MB in slice */ - NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice); - - /* Slice Type */ - NSWAVCMCS_uExpVLC(&instance->encbs, slice_type); - - /* Picture Parameter set Id */ - pic_parameter_set_id = instance->encoder_pps.pic_parameter_set_id; - NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id); - - temp = H264MCS_getBits(p_bs, - instance->encoder_sps.log2_max_frame_num_minus4 + 4); - NSWAVCMCS_putBits(&instance->encbs, instance->frame_count, - instance->clip_sps.log2_max_frame_num_minus4 + 4); - - // In Baseline Profile: frame_mbs_only_flag should be ON - if( nal_unit_type == 5 ) - { - temp = H264MCS_DecVLCReadExpGolombCode(p_bs); - NSWAVCMCS_uExpVLC(&instance->encbs, temp); - } - - if( instance->encoder_sps.pic_order_cnt_type == 0 ) - { - temp = H264MCS_getBits(p_bs, - instance->encoder_sps.log2_max_pic_order_cnt_lsb_minus4 - + 4); - - // in baseline profile field_pic_flag should be off. - if( instance->encoder_pps.pic_order_present_flag ) - { - temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - } - } - - if( ( instance->encoder_sps.pic_order_cnt_type == 1) - && (instance->encoder_sps.delta_pic_order_always_zero_flag) ) - { - temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - - // in baseline profile field_pic_flag should be off. - if( instance->encoder_pps.pic_order_present_flag ) - { - temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - } - } - - if( instance->clip_sps.pic_order_cnt_type == 0 ) - { - NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb, - instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4); - - // in baseline profile field_pic_flag should be off. - if( instance->encoder_pps.pic_order_present_flag ) - { - NSWAVCMCS_sExpVLC(&instance->encbs, 0); - } - } - - if( ( instance->clip_sps.pic_order_cnt_type == 1) - && (instance->clip_sps.delta_pic_order_always_zero_flag) ) - { - NSWAVCMCS_sExpVLC(&instance->encbs, 0); - - // in baseline profile field_pic_flag should be off. - if( instance->encoder_pps.pic_order_present_flag ) - { - NSWAVCMCS_sExpVLC(&instance->encbs, 0); - } - } - - cnt = p_bs->bitPos & 0x7; - - if( cnt ) - { - cnt = 8 - cnt; - temp = H264MCS_getBits(p_bs, cnt); - NSWAVCMCS_putBits(&instance->encbs, temp, cnt); - } - - cnt = p_bs->bitPos >> 3; - - while( cnt < (nal_size - 2) ) - { - temp = H264MCS_getBits(p_bs, 8); - NSWAVCMCS_putBits(&instance->encbs, temp, 8); - cnt = p_bs->bitPos >> 3; - } - - temp = H264MCS_getBits(p_bs, 8); - - if( temp != 0 ) - { - cnt = 0; - - while( ( temp & 0x1) == 0 ) - { - cnt++; - temp = temp >> 1; - } - cnt++; - temp = temp >> 1; - - if( 8 - cnt ) - { - NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt)); - } - - NSWAVCMCS_putRbspTbits(&instance->encbs); - } - else - { - - M4OSA_TRACE1_1( - "H264MCS_ProcessEncodedNALU : 13 temp = 0 trailing bits = %d", - instance->encbs.bitPos % 8); - - if( instance->encbs.bitPos % 8 ) - { - NSWAVCMCS_putBits(&instance->encbs, 0, - (8 - instance->encbs.bitPos % 8)); - } - } - - temp = instance->encbs.byteCnt; - temp = temp + 1; - - outbuffpos = outbuffpos + temp; - } - } - - *outbuf_size = outbuffpos; - - instance->POC_lsb = instance->POC_lsb + 1; - - if( instance->POC_lsb == instance->POC_lsb_mod ) - { - instance->POC_lsb = 0; - } - instance->frame_count = instance->frame_count + 1; - - if( instance->frame_count == instance->frame_mod_count ) - { - instance->frame_count = 0; - } - - // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it - - free(pTmpBuff1); - pTmpBuff1 = M4OSA_NULL; - inbuff = (M4OSA_UInt8 *)pTmpBuff2; - - return M4NO_ERROR; -} - -M4OSA_Int32 DecSPSMCS( ComBitStreamMCS_t *p_bs, - ComSequenceParameterSet_t_MCS *sps ) -{ - M4OSA_UInt32 i; - M4OSA_Int32 temp_max_dpb_size; - M4OSA_Int32 nb_ignore_bits; - M4OSA_Int32 error; - M4OSA_UInt8 profile_idc, level_idc, reserved_zero_4bits, - seq_parameter_set_id; - M4OSA_UInt8 constraint_set0_flag, constraint_set1_flag, - constraint_set2_flag, constraint_set3_flag; - - sps->profile_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8); - sps->constraint_set0_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - sps->constraint_set1_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - sps->constraint_set2_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - sps->constraint_set3_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - reserved_zero_4bits = (M4OSA_UInt8)H264MCS_getBits(p_bs, 4); - sps->level_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8); - sps->seq_parameter_set_id = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->log2_max_frame_num_minus4 = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - sps->pic_order_cnt_type = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - - if (sps->pic_order_cnt_type == 0) - { - sps->log2_max_pic_order_cnt_lsb_minus4 = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->MaxPicOrderCntLsb = - 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); - } - else if( sps->pic_order_cnt_type == 1 ) - { - sps->delta_pic_order_always_zero_flag = - (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - // This fix should be generic to remove codec dependency - - sps->offset_for_non_ref_pic = - H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - sps->offset_for_top_to_bottom_field = - H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - - - /*num_ref_frames_in_pic_order_cnt_cycle must be in the range 0, 255*/ - - sps->num_ref_frames_in_pic_order_cnt_cycle = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - - /* compute deltaPOC */ - sps->expectedDeltaPerPicOrderCntCycle = 0; - - for ( i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++ ) - { - // This fix should be generic to remove codec dependency - sps->offset_for_ref_frame[i] = - H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - - sps->expectedDeltaPerPicOrderCntCycle += - sps->offset_for_ref_frame[i]; - } - } - - /* num_ref_frames must be in the range 0,16 */ - sps->num_ref_frames = (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->gaps_in_frame_num_value_allowed_flag = - (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - sps->pic_width_in_mbs_minus1 = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->pic_height_in_map_units_minus1 = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - - sps->frame_mbs_only_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - if (!sps->frame_mbs_only_flag) - { - sps->mb_adaptive_frame_field_flag = - (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - } - else - { - sps->mb_adaptive_frame_field_flag = 0; - } - - sps->PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1; - sps->FrameHeightInMbs = ( 2 - sps->frame_mbs_only_flag) * \ - (sps->pic_height_in_map_units_minus1 + 1); -#ifdef _CAP_FMO_ - - sps->NumSliceGroupMapUnits = - sps->PicWidthInMbs * (sps->pic_height_in_map_units_minus1 + 1); - sps->MaxPicSizeInMbs = sps->PicWidthInMbs * sps->FrameHeightInMbs; - -#endif /*_CAP_FMO_*/ - - sps->direct_8x8_inference_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - if( sps->frame_mbs_only_flag == 0 ) - sps->direct_8x8_inference_flag = 1; - - sps->frame_cropping_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - if( sps->frame_cropping_flag ) - { - sps->frame_crop_left_offset = H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->frame_crop_right_offset = H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->frame_crop_top_offset = H264MCS_DecVLCReadExpGolombCode(p_bs); - sps->frame_crop_bottom_offset = H264MCS_DecVLCReadExpGolombCode(p_bs); - } - else - { - sps->frame_crop_left_offset = 0; - sps->frame_crop_right_offset = 0; - sps->frame_crop_top_offset = 0; - sps->frame_crop_bottom_offset = 0; - } - - sps->vui_parameters_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - if (sps->vui_parameters_present_flag) { - /* no error message as stream can be decoded without VUI messages */ - } - - return M4NO_ERROR; -} - -M4OSA_Int32 DecPPSMCS( ComBitStreamMCS_t *p_bs, - ComPictureParameterSet_t_MCS *pps ) -{ - M4OSA_Int32 error; - M4OSA_UInt32 pic_parameter_set_id; - -#ifdef _CAP_FMO_ - M4OSA_UInt32 i, length, v; -#endif - - M4OSA_Int32 nb_ignore_bits; - - pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs); - pps->pic_parameter_set_id = (M4OSA_UInt8)pic_parameter_set_id; - - pps->seq_parameter_set_id = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - - /* entropy_coding_mode_flag must be 0 or 1 */ - pps->entropy_coding_mode_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - pps->pic_order_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - pps->num_slice_groups_minus1 = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - -#ifdef _CAP_FMO_ - /* FMO stuff begins here */ - - pps->map_initialized = FALSE; - - if( pps->num_slice_groups_minus1 > 0 ) - { - pps->slice_group_map_type = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - - switch( pps->slice_group_map_type ) - { - case 0: - for ( i = 0; i <= pps->num_slice_groups_minus1; i++ ) - { - pps->run_length_minus1[i] = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - } - break; - - case 2: - for ( i = 0; i < pps->num_slice_groups_minus1; i++ ) - { - pps->top_left[i] = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - pps->bottom_right[i] = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - } - break; - - case 3: - case 4: - case 5: - pps->slice_group_change_direction_flag = - (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - pps->slice_group_change_rate_minus1 = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - break; - - case 6: - pps->pic_size_in_map_units_minus1 = - (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs); - - pps->slice_group_id = (H264UInt8 - *)M4H264Dec_malloc((pps->pic_size_in_map_units_minus1 - + 1), M4H264_COREID, (M4OSA_Char *)"PPS"); - - if (M4OSA_NULL == pps->slice_group_id) - { - M4OSA_TRACE1_0("DecPPSMCS: allocation error"); - return M4ERR_ALLOC; - } - - for ( length = 0, v = pps->num_slice_groups_minus1 + 1; v != 0; - v >>= 1, length++ ); - - for ( i = 0; i <= pps->pic_size_in_map_units_minus1; i++ ) - { - pps->slice_group_id[i] = - (M4OSA_UInt8)getBits(p_vlc_engine->p_bs, length); - } - break; - } - } - else - { - pps->slice_group_map_type = 0; - } - /* End of FMO stuff */ - -#else - -#endif /* _CAP_FMO_ */ - - /* num_ref_idx_l0_active_minus1 must be in the range 0, 31 */ - - pps->num_ref_idx_l0_active_minus1 = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - /* num_ref_idx_l1_active_minus1 must be in the range 0, 31 */ - pps->num_ref_idx_l1_active_minus1 = - (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs); - pps->weighted_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - /* weighted_bipred_idc must be in the range 0,2 */ - pps->weighted_bipred_idc = (M4OSA_Bool)H264MCS_getBits(p_bs, 2); - - /* pic_init_qp_minus26 must be in the range -26,25 */ - pps->pic_init_qp_minus26 = - (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - - /* pic_init_qs_minus26 must be in the range -26,25 */ - pps->pic_init_qs_minus26 = - (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - - /* chroma_qp_index_offset must be in the range -12,+12 */ - pps->chroma_qp_index_offset = - (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - pps->deblocking_filter_control_present_flag = - (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - pps->constrained_intra_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - pps->redundant_pic_cnt_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1); - - return M4NO_ERROR; -} - -M4OSA_ERR H264MCS_ProcessSPS_PPS( NSWAVC_MCS_t *instance, M4OSA_UInt8 *inbuff, - M4OSA_Int32 inbuf_size ) -{ - ComBitStreamMCS_t *p_bs, bs; - ComBitStreamMCS_t *p_bs1, bs1; - - M4OSA_UInt8 nalu_info = 0; - M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type; - M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id = 0, - frame_num; - M4OSA_Int32 seq_parameter_set_id; - M4OSA_UInt8 temp1, temp2, temp3, temp4; - M4OSA_Int32 temp_frame_num; - M4OSA_Int32 bitstoDiacard, bytes; - M4OSA_UInt32 mask_bits = 0xFFFFFFFF; - M4OSA_Int32 new_bytes, init_bit_pos; - M4OSA_UInt32 nal_size = 0; - M4OSA_UInt32 cnt, cnt1; - M4OSA_UInt32 outbuffpos = 0; - M4OSA_UInt32 nal_size_low16, nal_size_high16; - M4OSA_UInt32 frame_size = 0; - M4OSA_UInt32 temp = 0; - M4OSA_UInt8 *lClipDSI; - M4OSA_UInt8 *lClipDSI_PPS_start; - M4OSA_UInt32 lClipDSI_PPS_offset = 0; - - M4OSA_UInt8 *lPPS_Buffer = M4OSA_NULL; - M4OSA_UInt32 lPPS_Buffer_Size = 0; - - M4OSA_UInt32 lSize, lSize1; - M4OSA_UInt32 lActiveSPSID_Clip; - M4OSA_UInt32 lClipPPSRemBits = 0; - - M4OSA_UInt32 lEncoder_SPSID = 0; - M4OSA_UInt32 lEncoder_PPSID = 0; - M4OSA_UInt32 lEncoderPPSRemBits = 0; - M4OSA_UInt32 lFound = 0; - M4OSA_UInt32 size; - - M4OSA_UInt8 Clip_SPSID[32] = { 0 }; - M4OSA_UInt8 Clip_UsedSPSID[32] = { 0 }; - M4OSA_UInt8 Clip_PPSID[256] = { 0 }; - M4OSA_UInt8 Clip_SPSID_in_PPS[256] = { 0 }; - M4OSA_UInt8 Clip_UsedPPSID[256] = { 0 }; - M4OSA_ERR err = M4NO_ERROR; - - p_bs = &bs; - p_bs1 = &bs1; - - /* Find the active SPS ID */ - M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER, - "H264MCS_ProcessSPS_PPS: instance is M4OSA_NULL"); - - instance->m_Num_Bytes_NALUnitLength = - (instance->m_pDecoderSpecificInfo[4] & 0x03) + 1; - - instance->m_encoder_SPS_Cnt = instance->m_pDecoderSpecificInfo[5] & 0x1F; - - lClipDSI = instance->m_pDecoderSpecificInfo + 6; - - lClipDSI_PPS_offset = 6; - - for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ ) - { - lSize = ( lClipDSI[0] << 8) + lClipDSI[1]; - lClipDSI = lClipDSI + 2; - - p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 4); - DecBitStreamReset_MCS(p_bs, lSize - 4); - - Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs); - Clip_UsedSPSID[Clip_SPSID[cnt]] = 1; - - lClipDSI = lClipDSI + lSize; - lClipDSI_PPS_offset = lClipDSI_PPS_offset + 2 + lSize; - } - - instance->m_encoder_PPS_Cnt = lClipDSI[0]; - lClipDSI = lClipDSI + 1; - - lClipDSI_PPS_start = lClipDSI; - - for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ ) - { - lSize = ( lClipDSI[0] << 8) + lClipDSI[1]; - lClipDSI = lClipDSI + 2; - - p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1); - DecBitStreamReset_MCS(p_bs, lSize - 1); - - Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs); - Clip_UsedPPSID[Clip_PPSID[cnt]] = 1; - Clip_SPSID_in_PPS[Clip_PPSID[cnt]] = - H264MCS_DecVLCReadExpGolombCode(p_bs); - - lClipDSI = lClipDSI + lSize; - } - - /* Find the clip SPS ID used at the cut start frame */ - while( ( (M4OSA_Int32)frame_size) < inbuf_size ) - { - mask_bits = 0xFFFFFFFF; - p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size); - - switch( instance->m_Num_Bytes_NALUnitLength ) - { - case 1: - nal_size = (unsigned char)p_bs->Buffer[0]; - nalu_info = (unsigned char)p_bs->Buffer[1]; - p_bs->Buffer = p_bs->Buffer + 2; - - break; - - case 2: - nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1]; - nal_size = nal_size_high16; - nalu_info = (unsigned char)p_bs->Buffer[2]; - p_bs->Buffer = p_bs->Buffer + 3; - - break; - - case 4: - nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1]; - nal_size_low16 = ( p_bs->Buffer[2] << 8) + p_bs->Buffer[3]; - nal_size = ( nal_size_high16 << 16) + nal_size_low16; - nalu_info = (unsigned char)p_bs->Buffer[4]; - p_bs->Buffer = p_bs->Buffer + 5; - - break; - } - - if (nal_size == 0) { - M4OSA_TRACE1_1("0 size nal unit at line %d", __LINE__); - frame_size += instance->m_Num_Bytes_NALUnitLength; - continue; - } - - p_bs->bitPos = 0; - p_bs->lastTotalBits = 0; - p_bs->numBitsInBuffer = - ( inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1) - << 3; - p_bs->readableBytesInBuffer = - inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1; - - p_bs->ui32TempBuff = 0; - p_bs->i8BitCnt = 0; - p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer; - p_bs->ui32LastTwoBytes = 0xFFFFFFFF; - - H264MCS_getBits(p_bs, 0); - - frame_size += nal_size + instance->m_Num_Bytes_NALUnitLength; - - forbidden_bit = ( nalu_info >> 7) & 1; - nal_ref_idc = ( nalu_info >> 5) & 3; - nal_unit_type = (nalu_info) &0x1f; - - if( nal_unit_type == 8 ) - { - M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: PPS"); - return err; - } - - if( nal_unit_type == 7 ) - { - /*SPS Packet */ - M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: SPS"); - return err; - } - - if( ( nal_unit_type == 1) || (nal_unit_type == 5) ) - { - first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs); - slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs); - pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs); - break; - } - } - - lActiveSPSID_Clip = Clip_SPSID_in_PPS[pic_parameter_set_id]; - - instance->final_SPS_ID = lActiveSPSID_Clip; - /* Do we need to add encoder PPS to clip PPS */ - - lClipDSI = lClipDSI_PPS_start; - - for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ ) - { - lSize = ( lClipDSI[0] << 8) + lClipDSI[1]; - lClipDSI = lClipDSI + 2; - - if( lActiveSPSID_Clip == Clip_SPSID_in_PPS[Clip_PPSID[cnt]] ) - { - lPPS_Buffer = lClipDSI + 1; - lPPS_Buffer_Size = lSize - 1; - - p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1); - DecBitStreamReset_MCS(p_bs, lSize - 1); - - Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs); - Clip_UsedPPSID[Clip_SPSID[cnt]] = 1; - Clip_SPSID_in_PPS[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs); - lClipPPSRemBits = ( lSize - 1) << 3; - lClipPPSRemBits -= p_bs->bitPos; - - temp = lClipDSI[lSize - 1]; - - cnt1 = 0; - - while( ( temp & 0x1) == 0 ) - { - cnt1++; - temp = temp >> 1; - } - cnt1++; - lClipPPSRemBits -= cnt1; - - lSize1 = instance->m_encoderPPSSize - 1; - p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1); - DecBitStreamReset_MCS(p_bs1, lSize1); - - lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1); - lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1); - - lEncoderPPSRemBits = ( lSize1) << 3; - lEncoderPPSRemBits -= p_bs1->bitPos; - - temp = instance->m_pEncoderPPS[lSize1]; - - cnt1 = 0; - - while( ( temp & 0x1) == 0 ) - { - cnt1++; - temp = temp >> 1; - } - cnt1++; - lEncoderPPSRemBits -= cnt1; - - if( lEncoderPPSRemBits == lClipPPSRemBits ) - { - while( lEncoderPPSRemBits > 8 ) - { - temp1 = H264MCS_getBits(p_bs, 8); - temp2 = H264MCS_getBits(p_bs1, 8); - lEncoderPPSRemBits = lEncoderPPSRemBits - 8; - - if( temp1 != temp2 ) - { - break; - } - } - - if( lEncoderPPSRemBits < 8 ) - { - if( lEncoderPPSRemBits ) - { - temp1 = H264MCS_getBits(p_bs, lEncoderPPSRemBits); - temp2 = H264MCS_getBits(p_bs1, lEncoderPPSRemBits); - - if( temp1 == temp2 ) - { - lFound = 1; - } - } - else - { - lFound = 1; - } - } - break; - } - } - - lClipDSI = lClipDSI + lSize; - } - - /* Form the final SPS and PPS data */ - - if( lFound == 1 ) - { - /* No need to add PPS */ - instance->final_PPS_ID = Clip_PPSID[cnt]; - - instance->m_pFinalDSI = - (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(instance->m_decoderSpecificInfoSize, - M4MCS, (M4OSA_Char *)"instance->m_pFinalDSI"); - - if( instance->m_pFinalDSI == M4OSA_NULL ) - { - M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error"); - return M4ERR_ALLOC; - } - - instance->m_pFinalDSISize = instance->m_decoderSpecificInfoSize; - memcpy((void *)instance->m_pFinalDSI, - (void *)instance->m_pDecoderSpecificInfo, - instance->m_decoderSpecificInfoSize); - } - else - { - /* ADD PPS */ - /* find the free PPS ID */ - - cnt = 0; - - while( Clip_UsedPPSID[cnt] ) - { - cnt++; - } - instance->final_PPS_ID = cnt; - - size = instance->m_decoderSpecificInfoSize + instance->m_encoderPPSSize - + 10; - - instance->m_pFinalDSI = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(size, M4MCS, - (M4OSA_Char *)"instance->m_pFinalDSI"); - - if( instance->m_pFinalDSI == M4OSA_NULL ) - { - M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error"); - return M4ERR_ALLOC; - } - - memcpy((void *)instance->m_pFinalDSI, - (void *)instance->m_pDecoderSpecificInfo, - instance->m_decoderSpecificInfoSize); - - temp = instance->m_pFinalDSI[lClipDSI_PPS_offset]; - temp = temp + 1; - instance->m_pFinalDSI[lClipDSI_PPS_offset] = temp; - - //temp = instance->m_pEncoderPPS[0]; - lSize1 = instance->m_encoderPPSSize - 1; - p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1); - DecBitStreamReset_MCS(p_bs1, lSize1); - - lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1); - lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1); - - lEncoderPPSRemBits = ( lSize1) << 3; - lEncoderPPSRemBits -= p_bs1->bitPos; - - temp = instance->m_pEncoderPPS[lSize1]; - - cnt1 = 0; - - while( ( temp & 0x1) == 0 ) - { - cnt1++; - temp = temp >> 1; - } - cnt1++; - lEncoderPPSRemBits -= cnt1; - - instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 2] = - instance->m_pEncoderPPS[0]; - - NSWAVCMCS_initBitstream(&instance->encbs); - instance->encbs.streamBuffer = - &(instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 3]); - lPPS_Buffer = instance->encbs.streamBuffer; - - NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_PPS_ID); - NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_SPS_ID); - - while( lEncoderPPSRemBits > 8 ) - { - temp = H264MCS_getBits(p_bs1, 8); - NSWAVCMCS_putBits(&instance->encbs, temp, 8); - lEncoderPPSRemBits = lEncoderPPSRemBits - 8; - } - - if( lEncoderPPSRemBits ) - { - temp = H264MCS_getBits(p_bs1, lEncoderPPSRemBits); - NSWAVCMCS_putBits(&instance->encbs, temp, lEncoderPPSRemBits); - } - NSWAVCMCS_putRbspTbits(&instance->encbs); - - temp = instance->encbs.byteCnt; - lPPS_Buffer_Size = temp; - temp = temp + 1; - - instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize] = - ( temp >> 8) & 0xFF; - instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 1] = - (temp) &0xFF; - instance->m_pFinalDSISize = - instance->m_decoderSpecificInfoSize + 2 + temp; - } - - /* Decode the clip SPS */ - - lClipDSI = instance->m_pDecoderSpecificInfo + 6; - - lClipDSI_PPS_offset = 6; - - for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ ) - { - lSize = ( lClipDSI[0] << 8) + lClipDSI[1]; - lClipDSI = lClipDSI + 2; - - if( Clip_SPSID[cnt] == instance->final_SPS_ID ) - { - p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1); - DecBitStreamReset_MCS(p_bs, lSize - 1); - - err = DecSPSMCS(p_bs, &instance->clip_sps); - if(err != M4NO_ERROR) { - return M4ERR_PARAMETER; - } - - //Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs); - //Clip_UsedSPSID[Clip_SPSID[cnt]] = 1; - break; - } - - lClipDSI = lClipDSI + lSize; - } - - /* Decode encoder SPS */ - p_bs->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderSPS + 1); - DecBitStreamReset_MCS(p_bs, instance->m_encoderSPSSize - 1); - err = DecSPSMCS(p_bs, &instance->encoder_sps); - if(err != M4NO_ERROR) { - return M4ERR_PARAMETER; - } - - if( instance->encoder_sps.num_ref_frames - > instance->clip_sps.num_ref_frames ) - { - return 100; //not supported - } - - p_bs->Buffer = (M4OSA_UInt8 *)lPPS_Buffer; - DecBitStreamReset_MCS(p_bs, lPPS_Buffer_Size); - DecPPSMCS(p_bs, &instance->encoder_pps); - - instance->frame_count = 0; - instance->frame_mod_count = - 1 << (instance->clip_sps.log2_max_frame_num_minus4 + 4); - - instance->POC_lsb = 0; - instance->POC_lsb_mod = - 1 << (instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4); - - return M4NO_ERROR; -} - -M4OSA_ERR H264MCS_ProcessNALU( NSWAVC_MCS_t *ainstance, M4OSA_UInt8 *inbuff, - M4OSA_Int32 inbuf_size, M4OSA_UInt8 *outbuff, - M4OSA_Int32 *outbuf_size ) -{ - ComBitStreamMCS_t *p_bs, bs; - NSWAVC_MCS_t *instance; - M4OSA_UInt8 nalu_info; - M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type; - M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num; - M4OSA_Int32 seq_parameter_set_id; - M4OSA_UInt8 temp1, temp2, temp3, temp4; - M4OSA_Int32 temp_frame_num; - M4OSA_Int32 bitstoDiacard, bytes; - M4OSA_UInt32 mask_bits = 0xFFFFFFFF; - M4OSA_Int32 new_bytes, init_bit_pos; - M4OSA_UInt32 nal_size; - M4OSA_UInt32 cnt; - M4OSA_UInt32 outbuffpos = 0; - //#ifndef DGR_FIX // + new - M4OSA_UInt32 nal_size_low16, nal_size_high16; - //#endif // + end new - M4OSA_UInt32 frame_size = 0; - M4OSA_UInt32 temp = 0; - M4OSA_ERR err = M4NO_ERROR; - M4OSA_UInt8 *buff; - - p_bs = &bs; - instance = (NSWAVC_MCS_t *)ainstance; - M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER, - "H264MCS_ProcessNALU: instance is M4OSA_NULL"); - - if( instance->is_done ) - return err; - - inbuff[0] = 0x00; - inbuff[1] = 0x00; - inbuff[2] = 0x00; - inbuff[3] = 0x01; - - - while( (M4OSA_Int32)frame_size < inbuf_size ) - { - mask_bits = 0xFFFFFFFF; - p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size); - - - nalu_info = (unsigned char)p_bs->Buffer[4]; - - outbuff[outbuffpos] = p_bs->Buffer[0]; - outbuff[outbuffpos + 1] = p_bs->Buffer[1]; - outbuff[outbuffpos + 2] = p_bs->Buffer[2]; - outbuff[outbuffpos + 3] = p_bs->Buffer[3]; - outbuff[outbuffpos + 4] = p_bs->Buffer[4]; - - p_bs->Buffer = p_bs->Buffer + 5; - - p_bs->bitPos = 0; - p_bs->lastTotalBits = 0; - p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3; - p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5; - - p_bs->ui32TempBuff = 0; - p_bs->i8BitCnt = 0; - p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer; - p_bs->ui32LastTwoBytes = 0xFFFFFFFF; - - H264MCS_getBits(p_bs, 0); - - - - nal_size = inbuf_size - frame_size - 4; - buff = inbuff + frame_size + 4; - - while( nal_size > 4 ) - { - if( ( buff[0] == 0x00) && (buff[1] == 0x00) && (buff[2] == 0x00) - && (buff[3] == 0x01) ) - { - break; - } - buff = buff + 1; - nal_size = nal_size - 1; - } - - if( nal_size <= 4 ) - { - nal_size = 0; - } - nal_size = ( inbuf_size - frame_size - 4) - nal_size; - - // M4OSA_TRACE1_3("H264MCS_ProcessNALU frame input buff size = %d current position - //= %d nal size = %d", - // inbuf_size, frame_size, nal_size + 4); - frame_size += nal_size + 4; - - - - forbidden_bit = ( nalu_info >> 7) & 1; - nal_ref_idc = ( nalu_info >> 5) & 3; - nal_unit_type = (nalu_info) &0x1f; - - if( nal_unit_type == 5 ) - { - /*IDR/PPS Packet - Do nothing*/ - instance->is_done = 1; - return err; - } - - NSWAVCMCS_initBitstream(&instance->encbs); - instance->encbs.streamBuffer = outbuff + outbuffpos + 5; - - if( nal_unit_type == 8 ) - { - M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: PPS"); - return err; - } - - if( nal_unit_type == 7 ) - { - /*SPS Packet */ - M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: SPS"); - return 0; - } - - if( (nal_unit_type == 5) ) - { - instance->frame_count = 0; - instance->POC_lsb = 0; - } - - if( (nal_unit_type == 1) ) - { - first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs); - NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice); - - slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs); - NSWAVCMCS_uExpVLC(&instance->encbs, slice_type); - - pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs); - NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id); - - temp = H264MCS_getBits(p_bs, - instance->clip_sps.log2_max_frame_num_minus4 + 4); - NSWAVCMCS_putBits(&instance->encbs, instance->frame_count, - instance->clip_sps.log2_max_frame_num_minus4 + 4); - - // In Baseline Profile: frame_mbs_only_flag should be ON - - if( nal_unit_type == 5 ) - { - temp = H264MCS_DecVLCReadExpGolombCode(p_bs); - NSWAVCMCS_uExpVLC(&instance->encbs, temp); - } - - if( instance->clip_sps.pic_order_cnt_type == 0 ) - { - temp = H264MCS_getBits(p_bs, - instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 - + 4); - NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb, - instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4); - } - - if( ( instance->clip_sps.pic_order_cnt_type == 1) - && (instance->clip_sps.delta_pic_order_always_zero_flag) ) - { - temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs); - NSWAVCMCS_sExpVLC(&instance->encbs, temp); - } - - cnt = p_bs->bitPos & 0x7; - - if( cnt ) - { - cnt = 8 - cnt; - temp = H264MCS_getBits(p_bs, cnt); - NSWAVCMCS_putBits(&instance->encbs, temp, cnt); - } - - cnt = p_bs->bitPos >> 3; - - while( cnt < (nal_size - 2) ) - { - temp = H264MCS_getBits(p_bs, 8); - NSWAVCMCS_putBits(&instance->encbs, temp, 8); - cnt = p_bs->bitPos >> 3; - } - - temp = H264MCS_getBits(p_bs, 8); - - if( temp != 0 ) - { - cnt = 0; - - while( ( temp & 0x1) == 0 ) - { - cnt++; - temp = temp >> 1; - } - cnt++; - temp = temp >> 1; - - if( 8 - cnt ) - { - NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt)); - } - - NSWAVCMCS_putRbspTbits(&instance->encbs); - } - else - { - if( instance->encbs.bitPos % 8 ) - { - NSWAVCMCS_putBits(&instance->encbs, 0, - (8 - instance->encbs.bitPos % 8)); - } - } - - temp = instance->encbs.byteCnt; - temp = temp + 1; - - outbuff[outbuffpos] = (M4OSA_UInt8)(( temp >> 24) & 0xFF); - outbuff[outbuffpos + 1] = (M4OSA_UInt8)(( temp >> 16) & 0xFF); - outbuff[outbuffpos + 2] = (M4OSA_UInt8)(( temp >> 8) & 0xFF); - outbuff[outbuffpos + 3] = (M4OSA_UInt8)((temp) &0xFF); - outbuffpos = outbuffpos + temp + 4; - } - else - { - p_bs->Buffer = p_bs->Buffer - 5; - memcpy((void *) &outbuff[outbuffpos], - (void *)p_bs->Buffer, nal_size + 4); - - outbuff[outbuffpos] = (M4OSA_UInt8)((nal_size >> 24)& 0xFF); - outbuff[outbuffpos + 1] = (M4OSA_UInt8)((nal_size >> 16)& 0xFF);; - outbuff[outbuffpos + 2] = (M4OSA_UInt8)((nal_size >> 8)& 0xFF);; - outbuff[outbuffpos + 3] = (M4OSA_UInt8)((nal_size)& 0xFF);; - - outbuffpos = outbuffpos + nal_size + 4; - } - } - - *outbuf_size = outbuffpos; - - instance->POC_lsb = instance->POC_lsb + 1; - - if( instance->POC_lsb == instance->POC_lsb_mod ) - { - instance->POC_lsb = 0; - } - instance->frame_count = instance->frame_count + 1; - - if( instance->frame_count == instance->frame_mod_count ) - { - instance->frame_count = 0; - } - return M4NO_ERROR; -} - -M4OSA_ERR M4MCS_convetFromByteStreamtoNALStream( M4OSA_UInt8 *inbuff, - M4OSA_UInt32 inbuf_size ) -{ - M4OSA_ERR err = M4NO_ERROR; - M4OSA_UInt32 framesize = 0; - M4OSA_UInt32 nal_size =0; - M4OSA_UInt8 *buff; - - - while(framesize < inbuf_size) - { - nal_size = inbuf_size - framesize - 4; - buff = inbuff + framesize + 4; - - while(nal_size > 4){ - if((buff[0] == 0x00) && - (buff[1] == 0x00) && - (buff[2] == 0x00) && - (buff[3] == 0x01)){ - break; - } - buff = buff + 1; - nal_size = nal_size -1; - } - - if(nal_size <= 4){ - nal_size = 0; - } - nal_size = (inbuf_size - framesize - 4) - nal_size; - - inbuff[framesize + 0] = (M4OSA_UInt8)((nal_size >> 24)& 0xFF); - inbuff[framesize + 1] = (M4OSA_UInt8)((nal_size >> 16)& 0xFF); - inbuff[framesize + 2] = (M4OSA_UInt8)((nal_size >> 8)& 0xFF); - inbuff[framesize + 3] = (M4OSA_UInt8)((nal_size )& 0xFF); - framesize += nal_size + 4; - - M4OSA_TRACE1_2("M4MCS_convetFromByteStreamtoNALStream framesize = %x nalsize = %x", - framesize, nal_size) - } - - return err; -} - - -M4OSA_ERR H264MCS_Freeinstance( NSWAVC_MCS_t *instance ) -{ - M4OSA_ERR err = M4NO_ERROR; - M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER, - "H264MCS_Freeinstance: instance is M4OSA_NULL"); - - if( M4OSA_NULL != instance->encoder_pps.slice_group_id ) - { - free(instance->encoder_pps.slice_group_id); - } - - if( M4OSA_NULL != instance->p_encoder_sps ) - { - free(instance->p_encoder_sps); - instance->p_encoder_sps = M4OSA_NULL; - } - - if( M4OSA_NULL != instance->p_encoder_pps ) - { - free(instance->p_encoder_pps); - instance->p_encoder_pps = M4OSA_NULL; - } - - if( M4OSA_NULL != instance->m_pFinalDSI ) - { - free(instance->m_pFinalDSI); - instance->m_pFinalDSI = M4OSA_NULL; - } - - if( M4OSA_NULL != instance ) - { - free(instance); - instance = M4OSA_NULL; - } - - return err; -} -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_getVersion(M4_VersionInfo* pVersionInfo); - * @brief Get the MCS version. - * @note Can be called anytime. Do not need any context. - * @param pVersionInfo (OUT) Pointer to a version info structure - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pVersionInfo is M4OSA_NULL (If Debug Level >= 2) - ****************************************************************************** - */ -M4OSA_ERR M4MCS_getVersion( M4_VersionInfo *pVersionInfo ) -{ - M4OSA_TRACE3_1("M4MCS_getVersion called with pVersionInfo=0x%x", - pVersionInfo); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pVersionInfo), M4ERR_PARAMETER, - "M4MCS_getVersion: pVersionInfo is M4OSA_NULL"); - - pVersionInfo->m_major = M4MCS_VERSION_MAJOR; - pVersionInfo->m_minor = M4MCS_VERSION_MINOR; - pVersionInfo->m_revision = M4MCS_VERSION_REVISION; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_getVersion(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * @brief Initializes the MCS (allocates an execution context). - * @note - * @param pContext (OUT) Pointer on the MCS context to allocate - * @param pFileReadPtrFct (IN) Pointer to OSAL file reader functions - * @param pFileWritePtrFct (IN) Pointer to OSAL file writer functions - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (If Debug Level >= 2) - * @return M4ERR_ALLOC: There is no more available memory - ****************************************************************************** - */ - -M4OSA_ERR M4MCS_init( M4MCS_Context *pContext, - M4OSA_FileReadPointer *pFileReadPtrFct, - M4OSA_FileWriterPointer *pFileWritePtrFct ) -{ - M4MCS_InternalContext *pC = M4OSA_NULL; - M4OSA_ERR err; - - M4OSA_TRACE3_3( - "M4MCS_init called with pContext=0x%x, pFileReadPtrFct=0x%x, pFileWritePtrFct=0x%x", - pContext, pFileReadPtrFct, pFileWritePtrFct); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_init: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER, - "M4MCS_init: pFileReadPtrFct is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWritePtrFct), M4ERR_PARAMETER, - "M4MCS_init: pFileWritePtrFct is M4OSA_NULL"); - - /** - * Allocate the MCS context and return it to the user */ - pC = (M4MCS_InternalContext *)M4OSA_32bitAlignedMalloc(sizeof(M4MCS_InternalContext), - M4MCS, (M4OSA_Char *)"M4MCS_InternalContext"); - *pContext = pC; - - if( M4OSA_NULL == pC ) - { - M4OSA_TRACE1_0( - "M4MCS_init(): unable to allocate M4MCS_InternalContext, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /** - * Init the context. All pointers must be initialized to M4OSA_NULL - * because CleanUp() can be called just after Init(). */ - pC->State = M4MCS_kState_CREATED; - pC->pOsaFileReadPtr = pFileReadPtrFct; - pC->pOsaFileWritPtr = pFileWritePtrFct; - pC->VideoState = M4MCS_kStreamState_NOSTREAM; - pC->AudioState = M4MCS_kStreamState_NOSTREAM; - pC->noaudio = M4OSA_FALSE; - pC->novideo = M4OSA_FALSE; - pC->uiProgress = 0; - - /** - * Reader stuff */ - pC->pInputFile = M4OSA_NULL; - pC->InputFileType = M4VIDEOEDITING_kFileType_Unsupported; - pC->bFileOpenedInFastMode = M4OSA_FALSE; - pC->pReaderContext = M4OSA_NULL; - pC->pReaderVideoStream = M4OSA_NULL; - pC->pReaderAudioStream = M4OSA_NULL; - pC->bUnsupportedVideoFound = M4OSA_FALSE; - pC->bUnsupportedAudioFound = M4OSA_FALSE; - pC->iAudioCtsOffset = 0; - /* First temporary video AU to have more precise end video cut*/ - pC->ReaderVideoAU1.m_structSize = 0; - /* Second temporary video AU to have more precise end video cut*/ - pC->ReaderVideoAU2.m_structSize = 0; - pC->ReaderAudioAU1.m_structSize = 0; - pC->ReaderAudioAU2.m_structSize = 0; - pC->m_audioAUDuration = 0; - pC->m_pDataAddress1 = M4OSA_NULL; - pC->m_pDataAddress2 = M4OSA_NULL; - /* First temporary video AU data to have more precise end video cut*/ - pC->m_pDataVideoAddress1 = M4OSA_NULL; - /* Second temporary video AU data to have more precise end video cut*/ - pC->m_pDataVideoAddress2 = M4OSA_NULL; - - /** - * Video decoder stuff */ - pC->pViDecCtxt = M4OSA_NULL; - pC->dViDecStartingCts = 0.0; - pC->iVideoBeginDecIncr = 0; - pC->dViDecCurrentCts = 0.0; - pC->dCtsIncrement = 0.0; - pC->isRenderDup = M4OSA_FALSE; - - /** - * Video encoder stuff */ - pC->pViEncCtxt = M4OSA_NULL; - pC->pPreResizeFrame = M4OSA_NULL; - pC->uiEncVideoBitrate = 0; - pC->encoderState = M4MCS_kNoEncoder; - - /** - * Audio decoder stuff */ - pC->pAudioDecCtxt = M4OSA_NULL; - pC->AudioDecBufferIn.m_dataAddress = M4OSA_NULL; - pC->AudioDecBufferIn.m_bufferSize = 0; - pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; - pC->AudioDecBufferOut.m_bufferSize = 0; - pC->pPosInDecBufferOut = M4OSA_NULL; - /** - * Ssrc stuff */ - pC->pSsrcBufferIn = M4OSA_NULL; - pC->pSsrcBufferOut = M4OSA_NULL; - pC->pPosInSsrcBufferIn = M4OSA_NULL; - pC->pPosInSsrcBufferOut = M4OSA_NULL; - pC->iSsrcNbSamplIn = 0; - pC->iSsrcNbSamplOut = 0; - pC->SsrcScratch = M4OSA_NULL; - pC->pLVAudioResampler = M4OSA_NULL; - /** - * Audio encoder */ - pC->pAudioEncCtxt = M4OSA_NULL; - pC->pAudioEncDSI.infoSize = 0; - pC->pAudioEncDSI.pInfo = M4OSA_NULL; - pC->pAudioEncoderBuffer = M4OSA_NULL; - pC->pPosInAudioEncoderBuffer = M4OSA_NULL; - pC->audioEncoderGranularity = 0; - - /** - * Writer stuff */ - pC->pOutputFile = M4OSA_NULL; - pC->pTemporaryFile = M4OSA_NULL; - pC->pWriterContext = M4OSA_NULL; - pC->uiVideoAUCount = 0; - pC->uiVideoMaxAuSize = 0; - pC->uiVideoMaxChunckSize = 0; - pC->uiAudioAUCount = 0; - pC->uiAudioMaxAuSize = 0; - - pC->uiAudioCts = 0; - pC->b_isRawWriter = M4OSA_FALSE; - pC->pOutputPCMfile = M4OSA_NULL; - - /* Encoding config */ - pC->EncodingVideoFormat = M4ENCODER_kNULL; /**< No format set yet */ - pC->EncodingWidth = 0; /**< No size set yet */ - pC->EncodingHeight = 0; /**< No size set yet */ - pC->EncodingVideoFramerate = 0; /**< No framerate set yet */ - - pC->uiBeginCutTime = 0; /**< No begin cut */ - pC->uiEndCutTime = 0; /**< No end cut */ - pC->uiMaxFileSize = 0; /**< No limit */ - pC->uiAudioBitrate = - M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */ - pC->uiVideoBitrate = - M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */ - - pC->WriterVideoStream.streamType = M4SYS_kVideoUnknown; - pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL; - pC->WriterAudioStream.streamType = M4SYS_kAudioUnknown; - - pC->outputVideoTimescale = 0; - - /*FB 2008/10/20: add media rendering parameter and AIR context to keep media aspect ratio*/ - pC->MediaRendering = M4MCS_kResizing; - pC->m_air_context = M4OSA_NULL; - /**/ - - /** - * FlB 2009.03.04: add audio Effects*/ - pC->pEffects = M4OSA_NULL; - pC->nbEffects = 0; - pC->pActiveEffectNumber = -1; - /**/ - - /* - * Reset pointers for media and codecs interfaces */ - err = M4MCS_clearInterfaceTables(pC); - M4ERR_CHECK_RETURN(err); - - /* - * Call the media and codecs subscription module */ - err = M4MCS_subscribeMediaAndCodec(pC); - M4ERR_CHECK_RETURN(err); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - /** - * Initialize the Still picture part of MCS*/ - - err = M4MCS_stillPicInit(pC, pFileReadPtrFct, pFileWritePtrFct); - M4ERR_CHECK_RETURN(err); - - pC->m_bIsStillPicture = M4OSA_FALSE; - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - pC->m_pInstance = M4OSA_NULL; - pC->H264MCSTempBuffer = M4OSA_NULL; - pC->H264MCSTempBufferSize = 0; - pC->H264MCSTempBufferDataSize = 0; - pC->bH264Trim = M4OSA_FALSE; - - /* Flag to get the last decoded frame cts */ - pC->bLastDecodedFrameCTS = M4OSA_FALSE; - - if( pC->m_pInstance == M4OSA_NULL ) - { - err = H264MCS_Getinstance(&pC->m_pInstance); - } - pC->bExtOMXAudDecoder = M4OSA_FALSE; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_init(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_open(M4MCS_Context pContext, M4OSA_Void* pFileIn, - * M4OSA_Void* pFileOut, M4OSA_Void* pTempFile); - * @brief Set the MCS input and output files. - * @note It opens the input file, but the output file is not created yet. - * @param pContext (IN) MCS context - * @param pFileIn (IN) Input file to transcode (The type of this parameter - * (URL, pipe...) depends on the OSAL implementation). - * @param mediaType (IN) Container type (.3gp,.amr,mp3 ...) of input file. - * @param pFileOut (IN) Output file to create (The type of this parameter - * (URL, pipe...) depends on the OSAL implementation). - * @param pTempFile (IN) Temporary file for the constant memory writer to - * store metadata ("moov.bin"). - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4ERR_ALLOC: There is no more available memory - * @return M4ERR_FILE_NOT_FOUND: The input file has not been found - * @return M4MCS_ERR_INVALID_INPUT_FILE: The input file is not a valid file, or is corrupted - * @return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM: The input file contains no - * supported audio or video stream - ****************************************************************************** - */ -M4OSA_ERR M4MCS_open( M4MCS_Context pContext, M4OSA_Void *pFileIn, - M4VIDEOEDITING_FileType InputFileType, M4OSA_Void *pFileOut, - M4OSA_Void *pTempFile ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4OSA_ERR err; - - M4READER_MediaFamily mediaFamily; - M4_StreamHandler *pStreamHandler; - - M4OSA_TRACE2_3( - "M4MCS_open called with pContext=0x%x, pFileIn=0x%x, pFileOut=0x%x", - pContext, pFileIn, pFileOut); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_open: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn), M4ERR_PARAMETER, - "M4MCS_open: pFileIn is M4OSA_NULL"); - - if( ( InputFileType == M4VIDEOEDITING_kFileType_JPG) - || (InputFileType == M4VIDEOEDITING_kFileType_PNG) - || (InputFileType == M4VIDEOEDITING_kFileType_GIF) - || (InputFileType == M4VIDEOEDITING_kFileType_BMP) ) - { -#ifdef M4MCS_SUPPORT_STILL_PICTURE - /** - * Indicate that we must use the still picture functions*/ - - pC->m_bIsStillPicture = M4OSA_TRUE; - - /** - * Call the still picture MCS functions*/ - return M4MCS_stillPicOpen(pC, pFileIn, InputFileType, pFileOut); - -#else - - M4OSA_TRACE1_0( - "M4MCS_open: Still picture is not supported with this version of MCS"); - return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - } - - /** - * Check state automaton */ - if( M4MCS_kState_CREATED != pC->State ) - { - M4OSA_TRACE1_1("M4MCS_open(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Copy function input parameters into our context */ - pC->pInputFile = pFileIn; - pC->InputFileType = InputFileType; - pC->pOutputFile = pFileOut; - pC->pTemporaryFile = pTempFile; - pC->uiProgress = 0; - - /***********************************/ - /* Open input file with the reader */ - /***********************************/ - - err = M4MCS_setCurrentReader(pContext, pC->InputFileType); - M4ERR_CHECK_RETURN(err); - - /** - * Reset reader related variables */ - pC->VideoState = M4MCS_kStreamState_NOSTREAM; - pC->AudioState = M4MCS_kStreamState_NOSTREAM; - pC->pReaderVideoStream = M4OSA_NULL; - pC->pReaderAudioStream = M4OSA_NULL; - - /*******************************************************/ - /* Initializes the reader shell and open the data file */ - /*******************************************************/ - err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctCreate returns 0x%x", - err); - return err; - } - - /** - * Link the reader interface to the reader context */ - pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext; - - /** - * Set the reader shell file access functions */ - err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, - M4READER_kOptionID_SetOsaFileReaderFctsPtr, - (M4OSA_DataOption)pC->pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctSetOption returns 0x%x", - err); - return err; - } - -#ifdef M4MCS_WITH_FAST_OPEN - - if( M4OSA_FALSE == pC->bFileOpenedInFastMode ) - { - M4OSA_Bool trueValue = M4OSA_TRUE; - - /* For first call use fast open mode */ - err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, - M4READER_3GP_kOptionID_FastOpenMode, &trueValue); - - if( M4NO_ERROR == err ) - { - pC->bFileOpenedInFastMode = M4OSA_TRUE; - } - else - { - M4OSA_TRACE1_1( - "M4MCS_open(): M4READER_3GP_kOptionID_FastOpenMode returns 0x%x", - err); - - if( ( ( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) == err) - || (( (M4OSA_UInt32)M4ERR_PARAMETER) == err) ) - { - /* Not fatal, some readers may not support fast open mode */ - pC->bFileOpenedInFastMode = M4OSA_FALSE; - } - else - return err; - } - } - else - { - M4OSA_Bool falseValue = M4OSA_FALSE; - - /* For second call use normal open mode */ - err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, - M4READER_3GP_kOptionID_FastOpenMode, &falseValue); - } - -#endif /* M4MCS_WITH_FAST_OPEN */ - - /** - * Open the input file */ - - err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile); - - if( M4NO_ERROR != err ) - { - M4OSA_UInt32 uiDummy, uiCoreId; - M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctOpen returns 0x%x", err); - - /** - * If the error is from the core reader, we change it to a public VXS error */ - M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); - - if( M4MP4_READER == uiCoreId ) - { - M4OSA_TRACE1_0( - "M4MCS_open(): returning M4MCS_ERR_INVALID_INPUT_FILE"); - return M4MCS_ERR_INVALID_INPUT_FILE; - } - return err; - } - - /** - * Get the streams from the input file */ - while( M4NO_ERROR == err ) - { - err = - pC->m_pReader->m_pFctGetNextStream( pC->pReaderContext, - &mediaFamily, - &pStreamHandler); - - /** - * In case we found a BIFS stream or something else...*/ - if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) - || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) ) - { - err = M4NO_ERROR; - continue; - } - - if( M4NO_ERROR == err ) /**< One stream found */ - { - /** - * Found the first video stream */ - if( ( M4READER_kMediaFamilyVideo == mediaFamily) - && (M4OSA_NULL == pC->pReaderVideoStream) ) - { - if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType) - || (M4DA_StreamTypeVideoMpeg4 - == pStreamHandler->m_streamType) - || (M4DA_StreamTypeVideoMpeg4Avc - == pStreamHandler->m_streamType) ) - { - M4OSA_TRACE3_0( - "M4MCS_open(): Found a H263 or MPEG-4 video stream in input 3gpp clip"); - - /** - * Keep pointer to the video stream */ - pC->pReaderVideoStream = - (M4_VideoStreamHandler *)pStreamHandler; - pC->bUnsupportedVideoFound = M4OSA_FALSE; - pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; - - /** - * Init our video stream state variable */ - pC->VideoState = M4MCS_kStreamState_STARTED; - - /** - * Reset the stream reader */ - err = pC->m_pReader->m_pFctReset(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open():\ - m_pReader->m_pFctReset(video) returns 0x%x", - err); - return err; - } - - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - pStreamHandler, &pC->ReaderVideoAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open():\ - m_pReader->m_pFctFillAuStruct(video) returns 0x%x", - err); - return err; - } - } - else /**< Not H263 or MPEG-4 (H264, etc.) */ - { - M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported video stream (0x%x) in\ - input 3gpp clip", - pStreamHandler->m_streamType); - - pC->bUnsupportedVideoFound = M4OSA_TRUE; - pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; - } - /* +CRLV6775 -H.264 Trimming */ - if( M4DA_StreamTypeVideoMpeg4Avc - == pStreamHandler->m_streamType ) - { - - // SPS and PPS are storead as per the 3gp file format - pC->m_pInstance->m_pDecoderSpecificInfo = - pStreamHandler->m_pH264DecoderSpecificInfo; - pC->m_pInstance->m_decoderSpecificInfoSize = - pStreamHandler->m_H264decoderSpecificInfoSize; - } - /* -CRLV6775 -H.264 Trimming */ - } - /** - * Found the first audio stream */ - else if( ( M4READER_kMediaFamilyAudio == mediaFamily) - && (M4OSA_NULL == pC->pReaderAudioStream) ) - { - if( ( M4DA_StreamTypeAudioAmrNarrowBand - == pStreamHandler->m_streamType) - || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType) - || (M4DA_StreamTypeAudioMp3 - == pStreamHandler->m_streamType) - || (M4DA_StreamTypeAudioEvrc - == pStreamHandler->m_streamType) ) - { - M4OSA_TRACE3_0( - "M4MCS_open(): Found an AMR-NB, AAC or MP3 audio stream in input clip"); - - /** - * Keep pointer to the audio stream */ - pC->pReaderAudioStream = - (M4_AudioStreamHandler *)pStreamHandler; - pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; - pC->bUnsupportedAudioFound = M4OSA_FALSE; - - /** - * Init our audio stream state variable */ - pC->AudioState = M4MCS_kStreamState_STARTED; - - /** - * Reset the stream reader */ - err = pC->m_pReader->m_pFctReset(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open():\ - m_pReader->m_pFctReset(audio) returns 0x%x", - err); - return err; - } - - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - pStreamHandler, &pC->ReaderAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open():\ - m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", - err); - return err; - } - - /** - * Output max AU size is equal to input max AU size (this value - * will be changed if there is audio transcoding) */ - pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize; - } - else - { - /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */ - M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported audio stream (0x%x) in \ - input 3gpp clip", pStreamHandler->m_streamType); - - pC->bUnsupportedAudioFound = M4OSA_TRUE; - pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; - } - } - } - } /**< end of while (M4NO_ERROR == err) */ - - /** - * Check we found at least one supported stream */ - if( ( M4OSA_NULL == pC->pReaderVideoStream) - && (M4OSA_NULL == pC->pReaderAudioStream) ) - { - M4OSA_TRACE1_0( - "M4MCS_open(): returning M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM"); - return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; - } - - if( pC->VideoState == M4MCS_kStreamState_STARTED ) - { - err = M4MCS_setCurrentVideoDecoder(pContext, - pC->pReaderVideoStream->m_basicProperties.m_streamType); - /*FB 2009-02-09: the error is check and returned only if video codecs are compiled, - else only audio is used, that is why the editing process can continue*/ -#ifndef M4MCS_AUDIOONLY - - M4ERR_CHECK_RETURN(err); - -#else - - if( ( M4NO_ERROR != err) && (M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED != err) ) - { - M4ERR_CHECK_RETURN(err); - } - -#endif /*M4MCS_AUDIOONLY*/ - - } - - if( pC->AudioState == M4MCS_kStreamState_STARTED ) - { - //EVRC - if( M4DA_StreamTypeAudioEvrc - != pStreamHandler-> - m_streamType ) /* decoder not supported yet, but allow to do null encoding */ - { - err = M4MCS_setCurrentAudioDecoder(pContext, - pC->pReaderAudioStream->m_basicProperties.m_streamType); - M4ERR_CHECK_RETURN(err); - } - } - - /** - * Get the audio and video stream properties */ - err = M4MCS_intGetInputClipProperties(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open(): M4MCS_intGetInputClipProperties returns 0x%x", err); - return err; - } - - /** - * Set the begin cut decoding increment according to the input frame rate */ - if( 0. != pC->InputFileProperties.fAverageFrameRate ) /**< sanity check */ - { - pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. - / pC->InputFileProperties. - fAverageFrameRate); /**< about 3 frames */ - } - else - { - pC->iVideoBeginDecIncr = - 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/ - } - - /** - * Update state automaton */ - pC->State = M4MCS_kState_OPENED; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_open(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_step(M4MCS_Context pContext, M4OSA_UInt8 *pProgress); - * @brief Perform one step of trancoding. - * @note - * @param pContext (IN) MCS context - * @param pProgress (OUT) Progress percentage (0 to 100) of the transcoding - * @note pProgress must be a valid address. - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: One of the parameters is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4MCS_WAR_TRANSCODING_DONE: Transcoding is over, user should now call M4MCS_close() - * @return M4MCS_ERR_AUDIO_CONVERSION_FAILED: The audio conversion (AAC to AMR-NB or MP3) failed - * @return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY: The input file contains an AAC audio track - * with an invalid sampling frequency (should never happen) - ****************************************************************************** - */ -M4OSA_ERR M4MCS_step( M4MCS_Context pContext, M4OSA_UInt8 *pProgress ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - M4OSA_TRACE3_1("M4MCS_step called with pContext=0x%x", pContext); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_step: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER, - "M4MCS_step: pProgress is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the still picture MCS functions*/ - return M4MCS_stillPicStep(pC, pProgress); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - switch( pC->State ) - { - case M4MCS_kState_READY: - *pProgress = 0; - return M4MCS_intStepSet(pC); - break; - - case M4MCS_kState_BEGINVIDEOJUMP: - *pProgress = pC->uiProgress; - return M4MCS_intStepBeginVideoJump(pC); - break; - - case M4MCS_kState_BEGINVIDEODECODE: - *pProgress = pC->uiProgress; - return M4MCS_intStepBeginVideoDecode(pC); - break; - - case M4MCS_kState_PROCESSING: - { - M4OSA_ERR err = M4NO_ERROR; - err = M4MCS_intStepEncoding(pC, pProgress); - /* Save progress info in case of pause */ - pC->uiProgress = *pProgress; - return err; - } - break; - - default: /**< State error */ - M4OSA_TRACE1_1( - "M4MCS_step(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_pause(M4MCS_Context pContext); - * @brief Pause the transcoding i.e. release the (external hardware) video decoder. - * @note This function is not needed if no hardware accelerators are used. - * In that case, pausing the MCS is simply achieved by temporarily suspending - * the M4MCS_step function calls. - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4MCS_pause( M4MCS_Context pContext ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4OSA_ERR err; - - M4OSA_TRACE2_1("M4MCS_pause called with pContext=0x%x", pContext); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_pause: pContext is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicPause(pC); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - switch( pC->State ) - { - case M4MCS_kState_BEGINVIDEOJUMP: /**< the video decoder has been created, - we must destroy it */ - case M4MCS_kState_BEGINVIDEODECODE: /**< the video is being used, we must destroy it */ - case M4MCS_kState_PROCESSING: /**< the video is being used, we must destroy it */ - /**< OK, nothing to do here */ - break; - - default: /**< State error */ - M4OSA_TRACE1_1( - "M4MCS_pause(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /** - * Set the CTS at which we will resume the decoding */ - if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) - { - /** - * We passed the starting CTS, so the resume target is the current CTS */ - pC->dViDecStartingCts = pC->dViDecCurrentCts; - } - else { - /** - * We haven't passed the starting CTS yet, so the resume target is still the starting CTS - * --> nothing to do in the else block */ - } - - /** - * Free video decoder stuff */ - if( M4OSA_NULL != pC->pViDecCtxt ) - { - err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); - pC->pViDecCtxt = M4OSA_NULL; - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_pause: m_pVideoDecoder->pFctDestroy returns 0x%x", err); - return err; - } - } - - /** - * State transition */ - pC->State = M4MCS_kState_PAUSED; - - M4OSA_TRACE3_0("M4MCS_pause(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_resume(M4MCS_Context pContext); - * @brief Resume the transcoding after a pause (see M4MCS_pause). - * @note This function is not needed if no hardware accelerators are used. - * In that case, resuming the MCS is simply achieved by calling - * the M4MCS_step function. - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4MCS_resume( M4MCS_Context pContext ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4OSA_ERR err; - - M4OSA_TRACE2_1("M4MCS_resume called with pContext=0x%x", pContext); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_resume: pContext is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicResume(pC); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - switch( pC->State ) - { - case M4MCS_kState_PAUSED: /**< OK, nothing to do here */ - break; - - default: /**< State error */ - M4OSA_TRACE1_1( - "M4MCS_resume(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - break; - } - - /** - * Prepare the video decoder */ - err = M4MCS_intPrepareVideoDecoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_resume(): M4MCS_intPrepareVideoDecoder() returns 0x%x", err); - return err; - } - - /** - * State transition */ - if( 0.0 == pC->dViDecStartingCts ) - { - /** - * We are still at the beginning of the decoded stream, no need to jump, we can proceed */ - pC->State = M4MCS_kState_PROCESSING; - } - else - { - /** - * Jumping */ - pC->State = M4MCS_kState_BEGINVIDEOJUMP; - } - - M4OSA_TRACE3_0("M4MCS_resume(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_close(M4MCS_Context pContext); - * @brief Finish the MCS transcoding. - * @note The output 3GPP file is ready to be played after this call - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4MCS_close( M4MCS_Context pContext ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4ENCODER_Header *encHeader; - M4SYS_StreamIDmemAddr streamHeader; - - M4OSA_ERR err = M4NO_ERROR, err2; - - M4OSA_TRACE2_1("M4MCS_close called with pContext=0x%x", pContext); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_close: pContext is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Indicate that current file is no longer a still picture*/ - pC->m_bIsStillPicture = M4OSA_FALSE; - - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicClose(pC); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - if( M4MCS_kState_FINISHED != pC->State ) - { - M4OSA_TRACE1_1("M4MCS_close(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Close the encoder before the writer to be certain all the AUs have been written and we can - get the DSI. */ - - /* Has the encoder actually been started? Don't stop it if that's not the case. */ - if( M4MCS_kEncoderRunning == pC->encoderState ) - { - if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL ) - { - err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_close: pVideoEncoderGlobalFcts->pFctStop returns 0x%x", - err); - /* Well... how the heck do you handle a failed cleanup? */ - } - } - - pC->encoderState = M4MCS_kEncoderStopped; - } - - /* Has the encoder actually been opened? Don't close it if that's not the case. */ - if( M4MCS_kEncoderStopped == pC->encoderState ) - { - err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_close: pVideoEncoderGlobalFcts->pFctClose returns 0x%x", - err); - /* Well... how the heck do you handle a failed cleanup? */ - } - - pC->encoderState = M4MCS_kEncoderClosed; - } - - /**********************************/ - /******** Close the writer ********/ - /**********************************/ - if( M4OSA_NULL != pC->pWriterContext ) /* happens in state _SET */ - { - /* HW encoder: fetch the DSI from the shell video encoder, and feed it to the writer before - closing it. */ - - if( pC->novideo != M4OSA_TRUE ) - { - if( ( M4ENCODER_kMPEG4 == pC->EncodingVideoFormat) - || (M4ENCODER_kH264 == pC->EncodingVideoFormat) ) - { - err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt, - M4ENCODER_kOptionID_EncoderHeader, - (M4OSA_DataOption) &encHeader); - - if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) - { - M4OSA_TRACE1_1( - "M4MCS_close: failed to get the encoder header (err 0x%x)", - err); - /**< no return here, we still have stuff to deallocate after close, even - if it fails. */ - } - else - { - /* set this header in the writer */ - streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; - streamHeader.size = encHeader->Size; - streamHeader.addr = (M4OSA_MemAddr32)encHeader->pBuf; - } - - M4OSA_TRACE1_0("calling set option"); - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - M4WRITER_kDSI, &streamHeader); - M4OSA_TRACE1_0("set option done"); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_close: failed to set the DSI in the writer (err 0x%x)", - err); - } - } - - if( ( M4OSA_TRUE == pC->bH264Trim) - && (M4ENCODER_kNULL == pC->EncodingVideoFormat) ) - { - if(pC->uiBeginCutTime == 0) - { - M4OSA_TRACE1_1("Decoder specific info size = %d", - pC->m_pInstance->m_decoderSpecificInfoSize); - pC->m_pInstance->m_pFinalDSISize = - pC->m_pInstance->m_decoderSpecificInfoSize; - M4OSA_TRACE1_1("Decoder specific info pointer = %d", - (M4OSA_MemAddr8)pC->m_pInstance->m_pDecoderSpecificInfo); - - pC->m_pInstance->m_pFinalDSI = - (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->m_pInstance-> \ - m_decoderSpecificInfoSize, M4MCS, - (M4OSA_Char *)"instance->m_pFinalDSI"); - - if( pC->m_pInstance->m_pFinalDSI == M4OSA_NULL ) - { - M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error"); - return M4ERR_ALLOC; - } - memcpy((void *)pC->m_pInstance->m_pFinalDSI, - (void *)pC-> \ - m_pInstance->m_pDecoderSpecificInfo, - pC->m_pInstance->m_decoderSpecificInfoSize); - } - streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; - streamHeader.size = pC->m_pInstance->m_pFinalDSISize; - streamHeader.addr = - (M4OSA_MemAddr32)pC->m_pInstance->m_pFinalDSI; - M4OSA_TRACE1_0("calling set option"); - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - M4WRITER_kDSI, &streamHeader); - M4OSA_TRACE1_0("set option done"); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_close: failed to set the DSI in the writer (err 0x%x)", - err); - } - } - } - /* Write and close the 3GP output file */ - err2 = pC->pWriterGlobalFcts->pFctCloseWrite(pC->pWriterContext); - pC->pWriterContext = M4OSA_NULL; - - if( M4NO_ERROR != err2 ) - { - M4OSA_TRACE1_1( - "M4MCS_close: pWriterGlobalFcts->pFctCloseWrite returns 0x%x", - err2); - - if( M4NO_ERROR == err ) - err = err2; - /**< no return here, we still have stuff to deallocate after close, even if it fails.*/ - } - } - - /* Close output PCM file if needed */ - if( pC->pOutputPCMfile != M4OSA_NULL ) - { - pC->pOsaFileWritPtr->closeWrite(pC->pOutputPCMfile); - pC->pOutputPCMfile = M4OSA_NULL; - } - - /*FlB 2009.03.04: add audio effects, - free effects list*/ - if( M4OSA_NULL != pC->pEffects ) - { - free(pC->pEffects); - pC->pEffects = M4OSA_NULL; - } - pC->nbEffects = 0; - pC->pActiveEffectNumber = -1; - - /** - * State transition */ - pC->State = M4MCS_kState_CLOSED; - - if( M4OSA_NULL != pC->H264MCSTempBuffer ) - { - free(pC->H264MCSTempBuffer); - } - - M4OSA_TRACE3_0("M4MCS_close(): returning M4NO_ERROR"); - return err; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_cleanUp(M4MCS_Context pContext); - * @brief Free all resources used by the MCS. - * @note The context is no more valid after this call - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4MCS_cleanUp( M4MCS_Context pContext ) -{ - M4OSA_ERR err = M4NO_ERROR; - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - M4OSA_TRACE3_1("M4MCS_cleanUp called with pContext=0x%x", pContext); - -#ifdef MCS_DUMP_PCM_TO_FILE - - if( file_au_reader ) - { - fclose(file_au_reader); - file_au_reader = NULL; - } - - if( file_pcm_decoder ) - { - fclose(file_pcm_decoder); - file_pcm_decoder = NULL; - } - - if( file_pcm_encoder ) - { - fclose(file_pcm_encoder); - file_pcm_encoder = NULL; - } - -#endif - - /** - * Check input parameter */ - - if( M4OSA_NULL == pContext ) - { - M4OSA_TRACE1_0( - "M4MCS_cleanUp: pContext is M4OSA_NULL, returning M4ERR_PARAMETER"); - return M4ERR_PARAMETER; - } - - /** - * Check state automaton */ - if( M4MCS_kState_CLOSED != pC->State ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - if( M4OSA_NULL != pC->m_pInstance ) - { - err = H264MCS_Freeinstance(pC->m_pInstance); - pC->m_pInstance = M4OSA_NULL; - } - - /* ----- Free video encoder stuff, if needed ----- */ - - if( ( M4OSA_NULL != pC->pViEncCtxt) - && (M4OSA_NULL != pC->pVideoEncoderGlobalFcts) ) - { - err = pC->pVideoEncoderGlobalFcts->pFctCleanup(pC->pViEncCtxt); - pC->pViEncCtxt = M4OSA_NULL; - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: pVideoEncoderGlobalFcts->pFctCleanup returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - pC->encoderState = M4MCS_kNoEncoder; - } - - /** - * In the H263 case, we allocated our own DSI buffer */ - if( ( M4ENCODER_kH263 == pC->EncodingVideoFormat) - && (M4OSA_NULL != pC->WriterVideoStreamInfo.Header.pBuf) ) - { - free(pC->WriterVideoStreamInfo.Header.pBuf); - pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pPreResizeFrame ) - { - if( M4OSA_NULL != pC->pPreResizeFrame[0].pac_data ) - { - free(pC->pPreResizeFrame[0].pac_data); - pC->pPreResizeFrame[0].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pPreResizeFrame[1].pac_data ) - { - free(pC->pPreResizeFrame[1].pac_data); - pC->pPreResizeFrame[1].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pPreResizeFrame[2].pac_data ) - { - free(pC->pPreResizeFrame[2].pac_data); - pC->pPreResizeFrame[2].pac_data = M4OSA_NULL; - } - free(pC->pPreResizeFrame); - pC->pPreResizeFrame = M4OSA_NULL; - } - - /* ----- Free the ssrc stuff ----- */ - - if( M4OSA_NULL != pC->SsrcScratch ) - { - free(pC->SsrcScratch); - pC->SsrcScratch = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pSsrcBufferIn ) - { - free(pC->pSsrcBufferIn); - pC->pSsrcBufferIn = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pSsrcBufferOut ) - { - free(pC->pSsrcBufferOut); - pC->pSsrcBufferOut = M4OSA_NULL; - } - - if (pC->pLVAudioResampler != M4OSA_NULL) - { - LVDestroy(pC->pLVAudioResampler); - pC->pLVAudioResampler = M4OSA_NULL; - } - - /* ----- Free the audio encoder stuff ----- */ - - if( M4OSA_NULL != pC->pAudioEncCtxt ) - { - err = pC->pAudioEncoderGlobalFcts->pFctClose(pC->pAudioEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - err = pC->pAudioEncoderGlobalFcts->pFctCleanUp(pC->pAudioEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - pC->pAudioEncCtxt = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->pAudioEncoderBuffer ) - { - free(pC->pAudioEncoderBuffer); - pC->pAudioEncoderBuffer = M4OSA_NULL; - } - - /* ----- Free all other stuff ----- */ - - /** - * Free the readers and the decoders */ - M4MCS_intCleanUp_ReadersDecoders(pC); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - /** - * Free the still picture resources */ - - M4MCS_stillPicCleanUp(pC); - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Free the shells interfaces */ - - M4MCS_unRegisterAllWriters(pContext); - M4MCS_unRegisterAllEncoders(pContext); - M4MCS_unRegisterAllReaders(pContext); - M4MCS_unRegisterAllDecoders(pContext); - - /** - * Free the context itself */ - free(pC); - pC = M4OSA_NULL; - - M4OSA_TRACE3_0("M4MCS_cleanUp(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_abort(M4MCS_Context pContext); - * @brief Finish the MCS transcoding and free all resources used by the MCS - * whatever the state is. - * @note The context is no more valid after this call - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - ****************************************************************************** - */ -M4OSA_ERR M4MCS_abort( M4MCS_Context pContext ) -{ - M4OSA_ERR err = M4NO_ERROR; - M4OSA_ERR err1 = M4NO_ERROR; - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - if( M4OSA_NULL == pContext ) - { - return M4NO_ERROR; - } - - if( ( pC->State == M4MCS_kState_CREATED) - || (pC->State == M4MCS_kState_CLOSED) ) - { - pC->State = M4MCS_kState_CLOSED; - - err = M4MCS_cleanUp(pContext); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err); - } - } - else - { -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Cancel the ongoing processes if any*/ - err = M4MCS_stillPicCancel(pC); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4MCS_abort : M4MCS_stillPicCancel fails err = 0x%x", err); - } - /*Still picture process is now stopped; Carry on with close and cleanup*/ - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - pC->State = M4MCS_kState_FINISHED; - - err = M4MCS_close(pContext); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1("M4MCS_abort : M4MCS_close fails err = 0x%x", err); - err1 = err; - } - - err = M4MCS_cleanUp(pContext); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err); - } - } - err = (err1 == M4NO_ERROR) ? err : err1; - return err; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_getInputFileProperties(M4MCS_Context pContext, - * M4VIDEOEDITING_ClipProperties* pFileProperties); - * @brief Retrieves the properties of the audio and video streams from the input file. - * @param pContext (IN) MCS context - * @param pProperties (OUT) Pointer on an allocated M4VIDEOEDITING_ClipProperties -structure which is filled with the input stream properties. - * @note The structure pProperties must be allocated and further de-allocated -by the application. The function must be called in the opened state. - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4MCS_getInputFileProperties( M4MCS_Context pContext, - M4VIDEOEDITING_ClipProperties *pFileProperties ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - M4OSA_TRACE2_2("M4MCS_getInputFileProperties called with pContext=0x%x, \ - pFileProperties=0x%x", pContext, pFileProperties); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_getInputFileProperties: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileProperties), M4ERR_PARAMETER, - "M4MCS_getInputFileProperties: pProperties is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicGetInputFileProperties(pC, pFileProperties); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - if( M4MCS_kState_OPENED != pC->State ) - { - M4OSA_TRACE1_1( - "M4MCS_getInputFileProperties(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /** - * Copy previously computed properties into given structure */ - memcpy((void *)pFileProperties, - (void *) &pC->InputFileProperties, - sizeof(M4VIDEOEDITING_ClipProperties)); - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_setOutputParams(M4MCS_Context pContext, M4MCS_OutputParams* pParams); - * @brief Set the MCS video output parameters. - * @note Must be called after M4MCS_open. Must be called before M4MCS_step. - * @param pContext (IN) MCS context - * @param pParams (IN/OUT) Transcoding parameters - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 : Output video frame size parameter is - * incompatible with H263 encoding - * @return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 : Output video frame size parameter is - * incompatible with H263 encoding - * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT : Undefined output video format parameter - * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE : Undefined output video frame size - * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE : Undefined output video frame rate - * @return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT : Undefined output audio format parameter - * @return M4MCS_ERR_DURATION_IS_NULL : Specified output parameters define a null duration stream - * (no audio and video) - ****************************************************************************** - */ -M4OSA_ERR M4MCS_setOutputParams( M4MCS_Context pContext, - M4MCS_OutputParams *pParams ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4OSA_UInt32 uiFrameWidth; - M4OSA_UInt32 uiFrameHeight; - M4OSA_ERR err; - - M4OSA_TRACE2_2( - "M4MCS_setOutputParams called with pContext=0x%x, pParams=0x%x", - pContext, pParams); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_setOutputParams: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pParams), M4ERR_PARAMETER, - "M4MCS_setOutputParams: pParam is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicSetOutputParams(pC, pParams); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - if( M4MCS_kState_OPENED != pC->State ) - { - M4OSA_TRACE1_1( - "M4MCS_setOutputParams(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Ignore audio or video stream if the output do not need it, */ - /* or if the input file does not have any audio or video stream */ - /*FlB 26.02.2009: add mp3 as mcs output format*/ - if( ( pParams->OutputVideoFormat == M4VIDEOEDITING_kNoneVideo) - || (pC->VideoState == M4MCS_kStreamState_NOSTREAM) - || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_AMR) - || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP3) ) - { - pC->novideo = M4OSA_TRUE; - } - - if( ( pParams->OutputAudioFormat == M4VIDEOEDITING_kNoneAudio) - || (pC->AudioState == M4MCS_kStreamState_NOSTREAM) ) - { - pC->noaudio = M4OSA_TRUE; - } - - if( pC->noaudio && pC->novideo ) - { - M4OSA_TRACE1_0( - "!!! M4MCS_setOutputParams : clip is NULL, there is no audio, no video"); - return M4MCS_ERR_DURATION_IS_NULL; - } - - /* Set writer */ - err = M4MCS_setCurrentWriter(pContext, pParams->OutputFileType); - M4ERR_CHECK_RETURN(err); - - /* Set video parameters */ - if( pC->novideo == M4OSA_FALSE ) - { - /** - * Check Video Format correctness */ - - switch( pParams->OutputVideoFormat ) - { - case M4VIDEOEDITING_kH263: - if( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4 ) - return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE; - - pC->EncodingVideoFormat = M4ENCODER_kH263; - err = M4MCS_setCurrentVideoEncoder(pContext, - pParams->OutputVideoFormat); - M4ERR_CHECK_RETURN(err); - break; - - case M4VIDEOEDITING_kMPEG4: - - pC->EncodingVideoFormat = M4ENCODER_kMPEG4; - err = M4MCS_setCurrentVideoEncoder(pContext, - pParams->OutputVideoFormat); - M4ERR_CHECK_RETURN(err); - break; - - case M4VIDEOEDITING_kH264: - - pC->EncodingVideoFormat = M4ENCODER_kH264; - err = M4MCS_setCurrentVideoEncoder(pContext, - pParams->OutputVideoFormat); - M4ERR_CHECK_RETURN(err); - break; - - case M4VIDEOEDITING_kNullVideo: - if( ( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4) - && (pC->InputFileProperties.VideoStreamType - == M4VIDEOEDITING_kH263) ) - return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE; - - - /* Encoder needed for begin cut to generate an I-frame */ - pC->EncodingVideoFormat = M4ENCODER_kNULL; - err = M4MCS_setCurrentVideoEncoder(pContext, - pC->InputFileProperties.VideoStreamType); - M4ERR_CHECK_RETURN(err); - break; - - default: - M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output video format (%d),\ - returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", - pParams->OutputVideoFormat); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; - } - - /** - * Check Video frame size correctness */ - if( M4VIDEOEDITING_kNullVideo == pParams->OutputVideoFormat ) - { - uiFrameWidth = - pC->EncodingWidth = pC->InputFileProperties.uiVideoWidth; - uiFrameHeight = - pC->EncodingHeight = pC->InputFileProperties.uiVideoHeight; - - /** - * Set output video profile and level */ - pC->encodingVideoProfile = pC->InputFileProperties.uiVideoProfile; - /** Set the target video level, because input 3gp file may - * have wrong video level value (some encoders do not respect - * level restrictions like video resolution when content is created). - **/ - pC->encodingVideoLevel = pParams->outputVideoLevel; - - // Clip's original width and height may not be - // multiple of 16. - // Ensure encoding width and height are multiple of 16 - - uint32_t remainder = pC->EncodingWidth % 16; - if (remainder != 0) { - if (remainder >= 8) { - // Roll forward - pC->EncodingWidth = - pC->EncodingWidth + (16-remainder); - } else { - // Roll backward - pC->EncodingWidth = - pC->EncodingWidth - remainder; - } - uiFrameWidth = pC->EncodingWidth; - } - - remainder = pC->EncodingHeight % 16; - if (remainder != 0) { - if (remainder >= 8) { - // Roll forward - pC->EncodingHeight = - pC->EncodingHeight + (16-remainder); - } else { - // Roll backward - pC->EncodingHeight = - pC->EncodingHeight - remainder; - } - uiFrameHeight = pC->EncodingHeight; - } - - } - else - { - /** - * Set output video profile and level */ - pC->encodingVideoProfile = pParams->outputVideoProfile; - pC->encodingVideoLevel = pParams->outputVideoLevel; - - switch( pParams->OutputVideoFrameSize ) - { - case M4VIDEOEDITING_kSQCIF: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height; - break; - - case M4VIDEOEDITING_kQQVGA: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height; - break; - - case M4VIDEOEDITING_kQCIF: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height; - break; - - case M4VIDEOEDITING_kQVGA: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height; - break; - - case M4VIDEOEDITING_kCIF: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height; - break; - - case M4VIDEOEDITING_kVGA: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height; - break; - /* +PR LV5807 */ - case M4VIDEOEDITING_kWVGA: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height; - break; - - case M4VIDEOEDITING_kNTSC: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width; - uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height; - break; - /* -PR LV5807*/ - /* +CR Google */ - case M4VIDEOEDITING_k640_360: - uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_640_360_Height; - break; - - case M4VIDEOEDITING_k854_480: - uiFrameWidth = - pC->EncodingWidth = M4ENCODER_854_480_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_854_480_Height; - break; - - case M4VIDEOEDITING_k1280_720: - uiFrameWidth = - pC->EncodingWidth = M4ENCODER_1280_720_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_1280_720_Height; - break; - - case M4VIDEOEDITING_k1080_720: - uiFrameWidth = - pC->EncodingWidth = M4ENCODER_1080_720_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_1080_720_Height; - break; - - case M4VIDEOEDITING_k960_720: - uiFrameWidth = - pC->EncodingWidth = M4ENCODER_960_720_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_960_720_Height; - break; - - case M4VIDEOEDITING_k1920_1080: - uiFrameWidth = - pC->EncodingWidth = M4ENCODER_1920_1080_Width; - uiFrameHeight = - pC->EncodingHeight = M4ENCODER_1920_1080_Height; - break; - /* -CR Google */ - default: - M4OSA_TRACE1_1( - "M4MCS_setOutputParams: Undefined output video frame size \ - (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE", - pParams->OutputVideoFrameSize); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; - } - } - - /** - * Compute video max au size and max chunck size. - * We do it here because it depends on the frame size only, and - * because we need it for the file size/video bitrate estimations */ - pC->uiVideoMaxAuSize = - (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \ - *M4MCS_VIDEO_MIN_COMPRESSION_RATIO); - pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize \ - * - M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */ - - if( 0 == pC->uiVideoMaxAuSize ) - { - /* Size may be zero in case of null encoding with unrecognized stream */ - M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\ - M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE"); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; - } - - - /** - * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */ - - if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) - { - switch( pParams->OutputVideoFrameSize ) - { - case M4VIDEOEDITING_kSQCIF: - case M4VIDEOEDITING_kQCIF: - case M4VIDEOEDITING_kCIF: - /* OK */ - break; - - default: - M4OSA_TRACE1_0( - "M4MCS_setOutputParams():\ - returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263"); - return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263; - } - } - - /** - * Check Video Frame rate correctness */ - if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat ) - { - switch( pParams->OutputVideoFrameRate ) - { - case M4VIDEOEDITING_k5_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k5_FPS; - break; - - case M4VIDEOEDITING_k7_5_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS; - break; - - case M4VIDEOEDITING_k10_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k10_FPS; - break; - - case M4VIDEOEDITING_k12_5_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS; - break; - - case M4VIDEOEDITING_k15_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k15_FPS; - break; - - case M4VIDEOEDITING_k20_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k20_FPS; - break; - - case M4VIDEOEDITING_k25_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k25_FPS; - break; - - case M4VIDEOEDITING_k30_FPS: - pC->EncodingVideoFramerate = M4ENCODER_k30_FPS; - break; - - default: - M4OSA_TRACE1_1( - "M4MCS_setOutputParams: Undefined output video frame rate\ - (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", - pParams->OutputVideoFrameRate); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; - } - } - - /** - * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */ - if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) - { - switch( pC->EncodingVideoFramerate ) - { - case M4ENCODER_k5_FPS: - case M4ENCODER_k7_5_FPS: - case M4ENCODER_k10_FPS: - case M4ENCODER_k15_FPS: - case M4ENCODER_k30_FPS: - /* OK */ - break; - - default: - M4OSA_TRACE1_0( - "M4MCS_setOutputParams():\ - returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263"); - return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263; - } - } - } - - /* Set audio parameters */ - if( pC->noaudio == M4OSA_FALSE ) - { - /** - * Check Audio Format correctness */ - switch( pParams->OutputAudioFormat ) - { - case M4VIDEOEDITING_kAMR_NB: - - err = M4MCS_setCurrentAudioEncoder(pContext, - pParams->OutputAudioFormat); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kAMRNB; - pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; - pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; - pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID; - break; - - case M4VIDEOEDITING_kAAC: - - err = M4MCS_setCurrentAudioEncoder(pContext, - pParams->OutputAudioFormat); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kAAC; - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - - switch( pParams->OutputAudioSamplingFrequency ) - { - case M4VIDEOEDITING_k8000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; - break; - - case M4VIDEOEDITING_k16000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - break; - - case M4VIDEOEDITING_k22050_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; - break; - - case M4VIDEOEDITING_k24000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; - break; - - case M4VIDEOEDITING_k32000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; - break; - - case M4VIDEOEDITING_k44100_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; - break; - - case M4VIDEOEDITING_k48000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; - break; - - case M4VIDEOEDITING_k11025_ASF: - case M4VIDEOEDITING_k12000_ASF: - case M4VIDEOEDITING_kDefault_ASF: - break; - } - pC->AudioEncParams.ChannelNum = - (pParams->bAudioMono == M4OSA_TRUE) ? \ - M4ENCODER_kMono : M4ENCODER_kStereo; - pC->AudioEncParams.SpecifParam.AacParam.Regulation = - M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir - /* unused */ - pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE; - /* TODO change into highspeed asap */ - pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = - M4OSA_FALSE; - break; - - /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ - case M4VIDEOEDITING_kMP3: - err = M4MCS_setCurrentAudioEncoder(pContext, - pParams->OutputAudioFormat); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kMP3; - pC->AudioEncParams.ChannelNum = - (pParams->bAudioMono == M4OSA_TRUE) ? \ - M4ENCODER_kMono : M4ENCODER_kStereo; - - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - - switch( pParams->OutputAudioSamplingFrequency ) - { - case M4VIDEOEDITING_k8000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; - break; - - case M4VIDEOEDITING_k11025_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz; - break; - - case M4VIDEOEDITING_k12000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz; - break; - - case M4VIDEOEDITING_k16000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - break; - - case M4VIDEOEDITING_k22050_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; - break; - - case M4VIDEOEDITING_k24000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; - break; - - case M4VIDEOEDITING_k32000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; - break; - - case M4VIDEOEDITING_k44100_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; - break; - - case M4VIDEOEDITING_k48000_ASF: - pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; - break; - - case M4VIDEOEDITING_kDefault_ASF: - break; - } - - break; - - case M4VIDEOEDITING_kNullAudio: - if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 ) - { - /* no encoder needed */ - pC->AudioEncParams.Format = M4ENCODER_kAudioNULL; - pC->AudioEncParams.Frequency = - pC->pReaderAudioStream->m_samplingFrequency; - pC->AudioEncParams.ChannelNum = - (pC->pReaderAudioStream->m_nbChannels == 1) ? \ - M4ENCODER_kMono : M4ENCODER_kStereo; - } - else - { - pC->AudioEncParams.Frequency = - pC->pReaderAudioStream->m_samplingFrequency; - pC->AudioEncParams.ChannelNum = - (pC->pReaderAudioStream->m_nbChannels == 1) ? \ - M4ENCODER_kMono : M4ENCODER_kStereo; - - switch( pC->InputFileProperties.AudioStreamType ) - { - case M4VIDEOEDITING_kAMR_NB: - M4OSA_TRACE3_0( - "M4MCS_setOutputParams calling \ - M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR"); - err = M4MCS_setCurrentAudioEncoder(pContext, - pC->InputFileProperties.AudioStreamType); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kAMRNB; - pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; - pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; - - if( pC->pReaderAudioStream->m_samplingFrequency - != 8000 ) - { - pC->AudioEncParams.Format = M4ENCODER_kAMRNB; - } - pC->AudioEncParams.SpecifParam.AmrSID = - M4ENCODER_kAmrNoSID; - break; - - case M4VIDEOEDITING_kAAC: - M4OSA_TRACE3_0( - "M4MCS_setOutputParams calling \ - M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC"); - err = M4MCS_setCurrentAudioEncoder(pContext, - pC->InputFileProperties.AudioStreamType); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kAAC; - pC->AudioEncParams.SpecifParam.AacParam.Regulation = - M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - - switch( pC->pReaderAudioStream-> - m_samplingFrequency ) - { - case 16000: - pC->AudioEncParams.Frequency = - M4ENCODER_k16000Hz; - break; - - case 22050: - pC->AudioEncParams.Frequency = - M4ENCODER_k22050Hz; - break; - - case 24000: - pC->AudioEncParams.Frequency = - M4ENCODER_k24000Hz; - break; - - case 32000: - pC->AudioEncParams.Frequency = - M4ENCODER_k32000Hz; - break; - - case 44100: - pC->AudioEncParams.Frequency = - M4ENCODER_k44100Hz; - break; - - case 48000: - pC->AudioEncParams.Frequency = - M4ENCODER_k48000Hz; - break; - - default: - pC->AudioEncParams.Format = M4ENCODER_kAAC; - break; - } - /* unused */ - pC->AudioEncParams.SpecifParam.AacParam.bIS = - M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bMS = - M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bPNS = - M4OSA_FALSE; - pC->AudioEncParams.SpecifParam.AacParam.bTNS = - M4OSA_FALSE; - /* TODO change into highspeed asap */ - pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = - M4OSA_FALSE; - break; - - case M4VIDEOEDITING_kMP3: - M4OSA_TRACE3_0( - "M4MCS_setOutputParams calling\ - M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3"); - err = M4MCS_setCurrentAudioEncoder(pContext, - pC->InputFileProperties.AudioStreamType); - M4ERR_CHECK_RETURN(err); - - pC->AudioEncParams.Format = M4ENCODER_kMP3; - pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; - - switch( pC->pReaderAudioStream-> - m_samplingFrequency ) - { - case 8000: - pC->AudioEncParams.Frequency = - M4ENCODER_k8000Hz; - break; - - case 16000: - pC->AudioEncParams.Frequency = - M4ENCODER_k16000Hz; - break; - - case 22050: - pC->AudioEncParams.Frequency = - M4ENCODER_k22050Hz; - break; - - case 24000: - pC->AudioEncParams.Frequency = - M4ENCODER_k24000Hz; - break; - - case 32000: - pC->AudioEncParams.Frequency = - M4ENCODER_k32000Hz; - break; - - case 44100: - pC->AudioEncParams.Frequency = - M4ENCODER_k44100Hz; - break; - - case 48000: - pC->AudioEncParams.Frequency = - M4ENCODER_k48000Hz; - break; - - default: - pC->AudioEncParams.Format = M4ENCODER_kMP3; - break; - } - break; - - case M4VIDEOEDITING_kEVRC: - case M4VIDEOEDITING_kUnsupportedAudio: - default: - M4OSA_TRACE1_1( - "M4MCS_setOutputParams: Output audio format (%d) is\ - incompatible with audio effects, returning \ - M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", - pC->InputFileProperties.AudioStreamType); - return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; - } - } - break; - /* EVRC - // case M4VIDEOEDITING_kEVRC: - // - // err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\ - // OutputAudioFormat); - // M4ERR_CHECK_RETURN(err); - // - // pC->AudioEncParams.Format = M4ENCODER_kEVRC; - // pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; - // pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; - // break; */ - - default: - M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\ - returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", - pParams->OutputAudioFormat); - return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; - } - } - - if( pParams->pOutputPCMfile != M4OSA_NULL ) - { - pC->pOutputPCMfile = pParams->pOutputPCMfile; - - /* Open output PCM file */ - pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile), - pParams->pOutputPCMfile, M4OSA_kFileWrite); - } - else - { - pC->pOutputPCMfile = M4OSA_NULL; - } - - /*Store media rendering parameter into the internal context*/ - pC->MediaRendering = pParams->MediaRendering; - - /* Add audio effects*/ - /*Copy MCS effects structure into internal context*/ - if( pParams->nbEffects > 0 ) - { - M4OSA_UInt32 j = 0; - pC->nbEffects = pParams->nbEffects; - pC->pEffects = (M4MCS_EffectSettings *)M4OSA_32bitAlignedMalloc(pC->nbEffects \ - *sizeof(M4MCS_EffectSettings), M4MCS, - (M4OSA_Char *)"Allocation of effects list"); - - if( pC->pEffects == M4OSA_NULL ) - { - M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error"); - return M4ERR_ALLOC; - } - - for ( j = 0; j < pC->nbEffects; j++ ) - { - /* Copy effect to "local" structure */ - memcpy((void *) &(pC->pEffects[j]), - (void *) &(pParams->pEffects[j]), - sizeof(M4MCS_EffectSettings)); - - switch( pC->pEffects[j].AudioEffectType ) - { - case M4MCS_kAudioEffectType_None: - M4OSA_TRACE3_1( - "M4MCS_setOutputParams(): effect type %i is None", j); - pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; - pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL; - break; - - case M4MCS_kAudioEffectType_FadeIn: - M4OSA_TRACE3_1( - "M4MCS_setOutputParams(): effect type %i is FadeIn", j); - pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; - pC->pEffects[j].ExtAudioEffectFct = - M4MCS_editAudioEffectFct_FadeIn; - break; - - case M4MCS_kAudioEffectType_FadeOut: - M4OSA_TRACE3_1( - "M4MCS_setOutputParams(): effect type %i is FadeOut", - j); - pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; - pC->pEffects[j].ExtAudioEffectFct = - M4MCS_editAudioEffectFct_FadeOut; - break; - - case M4MCS_kAudioEffectType_External: - M4OSA_TRACE3_1( - "M4MCS_setOutputParams(): effect type %i is External", - j); - - if( pParams->pEffects != M4OSA_NULL ) - { - if( pParams->pEffects[j].ExtAudioEffectFct - == M4OSA_NULL ) - { - M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\ - associated to external effect number %i", j); - return M4ERR_PARAMETER; - } - pC->pEffects[j].pExtAudioEffectFctCtxt = - pParams->pEffects[j].pExtAudioEffectFctCtxt; - - pC->pEffects[j].ExtAudioEffectFct = - pParams->pEffects[j].ExtAudioEffectFct; - } - - break; - - default: - M4OSA_TRACE1_0( - "M4MCS_setOutputParams(): effect type not recognized"); - return M4ERR_PARAMETER; - } - } - } - else - { - pC->nbEffects = 0; - pC->pEffects = M4OSA_NULL; - } - - /** - * Update state automaton */ - pC->State = M4MCS_kState_SET; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) - * @brief Set the values of the encoding parameters - * @note Must be called before M4MCS_checkParamsAndStart(). - * @param pContext (IN) MCS context - * @param pRates (IN) Transcoding parameters - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps) - * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2 - * for amr, 8 for mp3) - * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals - * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip - * duration - * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time - * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given - * bitrates - * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps) - * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: Video bitrate too low - ****************************************************************************** - */ -M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext, - M4MCS_EncodingParams *pRates ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4OSA_UInt32 j = 0; - - M4OSA_TRACE2_2( - "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x", - pContext, pRates); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_setEncodingParams: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER, - "M4MCS_setEncodingParams: pRates is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicSetEncodingParams(pC, pRates); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - if( M4MCS_kState_SET != pC->State ) - { - M4OSA_TRACE1_1( - "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Set given values */ - pC->uiVideoBitrate = pRates->OutputVideoBitrate; - pC->uiAudioBitrate = pRates->OutputAudioBitrate; - pC->uiBeginCutTime = pRates->BeginCutTime; - pC->uiEndCutTime = pRates->EndCutTime; - pC->uiMaxFileSize = pRates->OutputFileSize; - - /** - * Check begin cut time validity */ - if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration ) - { - M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\ - returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION", - pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration); - return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION; - } - - /** - * If end cut time is too large, we set it to the clip duration */ - if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration ) - { - pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; - } - - /** - * Check end cut time validity */ - if( pC->uiEndCutTime > 0 ) - { - if( pC->uiEndCutTime < pC->uiBeginCutTime ) - { - M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \ - returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT", - pC->uiBeginCutTime, pC->uiEndCutTime); - return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT; - } - - if( pC->uiEndCutTime == pC->uiBeginCutTime ) - { - M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\ - returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT", - pC->uiBeginCutTime, pC->uiEndCutTime); - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - } - - /** - * FlB 2009.03.04: check audio effects start time and duration validity*/ - for ( j = 0; j < pC->nbEffects; j++ ) - { - M4OSA_UInt32 outputEndCut = pC->uiEndCutTime; - - if( pC->uiEndCutTime == 0 ) - { - outputEndCut = pC->InputFileProperties.uiClipDuration; - } - - if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) ) - { - M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\ - duration (%d,%d), returning M4ERR_PARAMETER", - pC->pEffects[j].uiStartTime, - (pC->uiEndCutTime - pC->uiBeginCutTime)); - return M4ERR_PARAMETER; - } - - if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \ - (outputEndCut - pC->uiBeginCutTime) ) - { - /* Re-adjust the effect duration until the end of the output clip*/ - pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \ - pC->pEffects[j].uiStartTime; - } - } - - /* Check audio bitrate consistency */ - if( ( pC->noaudio == M4OSA_FALSE) - && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) ) - { - if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) - { - if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) - { - if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS ) - return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - - if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - //EVRC - // else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) - // { - // if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS) - // return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - // if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS) - // return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - // } - /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ - else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) - { - if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz ) - { - /*Mpeg layer 1*/ - if( pC->uiAudioBitrate > 320000 ) - return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - - if( pC->uiAudioBitrate < 32000 ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz ) - { - /*Mpeg layer 2*/ - if( pC->uiAudioBitrate > 160000 ) - return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - - if( ( pC->uiAudioBitrate < 8000 - && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) - || (pC->uiAudioBitrate < 16000 - && pC->AudioEncParams.ChannelNum - == M4ENCODER_kStereo) ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz - || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz - || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz ) - { - /*Mpeg layer 2.5*/ - if( pC->uiAudioBitrate > 64000 ) - return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - - if( ( pC->uiAudioBitrate < 8000 - && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) - || (pC->uiAudioBitrate < 16000 - && pC->AudioEncParams.ChannelNum - == M4ENCODER_kStereo) ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - else - { - M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\ - (%d)", pC->AudioEncParams.Frequency); - return M4ERR_PARAMETER; - } - } - else - { - if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS ) - return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; - - if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono ) - { - if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - else - { - if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS ) - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - } - } - } - else - { - /* NULL audio : copy input file bitrate */ - pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate; - } - - /* Check video bitrate consistency */ - if( ( pC->novideo == M4OSA_FALSE) - && (pC->EncodingVideoFormat != M4ENCODER_kNULL) ) - { - if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate ) - { - if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS ) - return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH; - - if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS ) - return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; - } - } - else - { - /* NULL video : copy input file bitrate */ - pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate; - } - - if( pRates->OutputVideoTimescale <= 30000 - && pRates->OutputVideoTimescale > 0 ) - { - pC->outputVideoTimescale = pRates->OutputVideoTimescale; - } - - /* Check file size */ - return M4MCS_intCheckMaxFileSize(pC); -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) - * @brief Get the extended values of the encoding parameters - * @note Could be called after M4MCS_setEncodingParams. - * @param pContext (IN) MCS context - * @param pRates (OUT) Transcoding parameters - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration - * clip = encoding is impossible - ****************************************************************************** - */ -M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext, - M4MCS_EncodingParams *pRates ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - M4OSA_Int32 minaudiobitrate; - M4OSA_Int32 minvideobitrate; - M4OSA_Int32 maxcombinedbitrate; - - M4OSA_Int32 calcbitrate; - - M4OSA_UInt32 maxduration; - M4OSA_UInt32 calcduration; - - M4OSA_Bool fixed_audio = M4OSA_FALSE; - M4OSA_Bool fixed_video = M4OSA_FALSE; - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - pRates->OutputVideoBitrate = - M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0); - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0); - pRates->BeginCutTime = pC->uiBeginCutTime; - pRates->EndCutTime = pC->uiEndCutTime; - pRates->OutputFileSize = pC->uiMaxFileSize; - - /** - * Check state automaton */ - if( M4MCS_kState_SET != pC->State ) - { - M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\ - returning M4ERR_STATE", pC->State); - return M4ERR_STATE; - } - - /* Compute min audio bitrate */ - if( pC->noaudio ) - { - fixed_audio = M4OSA_TRUE; - pRates->OutputAudioBitrate = 0; - minaudiobitrate = 0; - } - else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) - { - fixed_audio = M4OSA_TRUE; - pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate; - minaudiobitrate = pC->InputFileProperties.uiAudioBitrate; - } - else - { - if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) - { - fixed_audio = M4OSA_TRUE; - pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS; - minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS; - } - //EVRC - // if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) - // { - // fixed_audio = M4OSA_TRUE; - // pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS; - // minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS; - // } - /*FlB 26.02.2009: add mp3 as mcs output format*/ - else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) - { - minaudiobitrate = - M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1, - for both mono and stereo channels*/ - } - else - { - minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) - ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; - } - } - - /* Check audio bitrate is in the correct range */ - if( fixed_audio == M4OSA_FALSE ) - { - if( ( pC->uiAudioBitrate > 0) - && (pRates->OutputAudioBitrate < minaudiobitrate) ) - { - pRates->OutputAudioBitrate = minaudiobitrate; - } - - if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) - { - pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; - } - } - - /* Compute min video bitrate */ - if( pC->novideo ) - { - fixed_video = M4OSA_TRUE; - pRates->OutputVideoBitrate = 0; - minvideobitrate = 0; - } - else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) - { - fixed_video = M4OSA_TRUE; - pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate; - minvideobitrate = pC->InputFileProperties.uiVideoBitrate; - } - else - { - minvideobitrate = M4VIDEOEDITING_k16_KBPS; - } - - /* Check video bitrate is in the correct range */ - if( fixed_video == M4OSA_FALSE ) - { - if( ( pC->uiVideoBitrate > 0) - && (pRates->OutputVideoBitrate < minvideobitrate) ) - { - pRates->OutputVideoBitrate = minvideobitrate; - } - /*+ New Encoder bitrates */ - if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) - { - pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; - } - /*- New Encoder bitrates */ - } - - /* Check cut times are in correct range */ - if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration) - || (( pRates->BeginCutTime >= pRates->EndCutTime) - && (pRates->EndCutTime > 0)) ) - { - pRates->BeginCutTime = 0; - pRates->EndCutTime = 0; - } - - if( pRates->EndCutTime == 0 ) - calcduration = - pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; - else - calcduration = pRates->EndCutTime - pRates->BeginCutTime; - - /* priority 1 : max file size */ - if( pRates->OutputFileSize == 0 ) - { - /* we can put maximum values for all undefined parameters */ - if( pRates->EndCutTime == 0 ) - { - pRates->EndCutTime = pC->InputFileProperties.uiClipDuration; - } - - if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) - && (fixed_audio == M4OSA_FALSE) ) - { - pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; - } - - if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) - && (fixed_video == M4OSA_FALSE) ) - { - /*+ New Encoder bitrates */ - pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; - /*- New Encoder bitrates */ - } - } - else - { - /* compute max duration */ - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (minvideobitrate + minaudiobitrate) * 8000.0); - - if( maxduration - + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) - { - maxduration = - pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; - } - - /* priority 2 : cut times */ - if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) ) - { - if( calcduration > maxduration ) - { - calcduration = maxduration; - } - - if( calcduration == 0 ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - - maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0)); - - /* audio and video bitrates */ - if( ( pRates->OutputAudioBitrate - == M4VIDEOEDITING_kUndefinedBitrate) - && (pRates->OutputVideoBitrate - == M4VIDEOEDITING_kUndefinedBitrate) ) - { - /* set audio = 1/3 and video = 2/3 */ - if( fixed_audio == M4OSA_FALSE ) - { - if( pC->novideo ) - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0); - else - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3, - 0); - - if( pRates->OutputAudioBitrate < minaudiobitrate ) - pRates->OutputAudioBitrate = minaudiobitrate; - - if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) - pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; - } - - if( fixed_video == M4OSA_FALSE ) - { - pRates->OutputVideoBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate - - pRates->OutputAudioBitrate, 0); - - if( pRates->OutputVideoBitrate < minvideobitrate ) - pRates->OutputVideoBitrate = minvideobitrate; - - if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) - pRates->OutputVideoBitrate = - M4VIDEOEDITING_k8_MBPS; /*+ New Encoder - bitrates */ - } - } - else - { - /* priority 3 : audio bitrate */ - if( pRates->OutputAudioBitrate - != M4VIDEOEDITING_kUndefinedBitrate ) - { - while( ( fixed_audio == M4OSA_FALSE) - && (pRates->OutputAudioBitrate >= minaudiobitrate) - && (pRates->OutputAudioBitrate - + minvideobitrate > maxcombinedbitrate) ) - { - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate( - pRates->OutputAudioBitrate, -1); - } - - if( ( fixed_audio == M4OSA_FALSE) - && (pRates->OutputAudioBitrate < minaudiobitrate) ) - { - pRates->OutputAudioBitrate = minaudiobitrate; - } - - calcbitrate = M4MCS_intGetNearestBitrate( - maxcombinedbitrate - - pRates->OutputAudioBitrate, 0); - - if( calcbitrate < minvideobitrate ) - calcbitrate = minvideobitrate; - - if( calcbitrate > M4VIDEOEDITING_k8_MBPS ) - calcbitrate = M4VIDEOEDITING_k8_MBPS; - - if( ( fixed_video == M4OSA_FALSE) - && (( pRates->OutputVideoBitrate - == M4VIDEOEDITING_kUndefinedBitrate) - || (pRates->OutputVideoBitrate > calcbitrate)) ) - { - pRates->OutputVideoBitrate = calcbitrate; - } - } - else - { - /* priority 4 : video bitrate */ - if( pRates->OutputVideoBitrate - != M4VIDEOEDITING_kUndefinedBitrate ) - { - while( ( fixed_video == M4OSA_FALSE) - && (pRates->OutputVideoBitrate >= minvideobitrate) - && (pRates->OutputVideoBitrate - + minaudiobitrate > maxcombinedbitrate) ) - { - pRates->OutputVideoBitrate = - M4MCS_intGetNearestBitrate( - pRates->OutputVideoBitrate, -1); - } - - if( ( fixed_video == M4OSA_FALSE) - && (pRates->OutputVideoBitrate < minvideobitrate) ) - { - pRates->OutputVideoBitrate = minvideobitrate; - } - - calcbitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate - - pRates->OutputVideoBitrate, 0); - - if( calcbitrate < minaudiobitrate ) - calcbitrate = minaudiobitrate; - - if( calcbitrate > M4VIDEOEDITING_k96_KBPS ) - calcbitrate = M4VIDEOEDITING_k96_KBPS; - - if( ( fixed_audio == M4OSA_FALSE) - && (( pRates->OutputAudioBitrate - == M4VIDEOEDITING_kUndefinedBitrate) - || (pRates->OutputAudioBitrate > calcbitrate)) ) - { - pRates->OutputAudioBitrate = calcbitrate; - } - } - } - } - } - else - { - /* priority 3 : audio bitrate */ - if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) - { - /* priority 4 : video bitrate */ - if( pRates->OutputVideoBitrate - != M4VIDEOEDITING_kUndefinedBitrate ) - { - /* compute max duration */ - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (pRates->OutputVideoBitrate - + pRates->OutputAudioBitrate) * 8000.0); - - if( maxduration + pRates->BeginCutTime - > pC->InputFileProperties.uiClipDuration ) - { - maxduration = pC->InputFileProperties.uiClipDuration - - pRates->BeginCutTime; - } - - if( calcduration > maxduration ) - { - calcduration = maxduration; - } - - if( calcduration == 0 ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - } - else - { - /* start with min video bitrate */ - pRates->OutputVideoBitrate = minvideobitrate; - - /* compute max duration */ - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (pRates->OutputVideoBitrate - + pRates->OutputAudioBitrate) * 8000.0); - - if( maxduration + pRates->BeginCutTime - > pC->InputFileProperties.uiClipDuration ) - { - maxduration = pC->InputFileProperties.uiClipDuration - - pRates->BeginCutTime; - } - - if( calcduration > maxduration ) - { - calcduration = maxduration; - } - - if( calcduration == 0 ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - - /* search max possible video bitrate */ - maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (calcduration / 8000.0)); - - while( ( fixed_video == M4OSA_FALSE) - && (pRates->OutputVideoBitrate - < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */ - { - calcbitrate = M4MCS_intGetNearestBitrate( - pRates->OutputVideoBitrate, +1); - - if( calcbitrate - + pRates->OutputAudioBitrate <= maxcombinedbitrate ) - pRates->OutputVideoBitrate = calcbitrate; - else - break; - } - } - } - else - { - /* priority 4 : video bitrate */ - if( pRates->OutputVideoBitrate - != M4VIDEOEDITING_kUndefinedBitrate ) - { - /* start with min audio bitrate */ - pRates->OutputAudioBitrate = minaudiobitrate; - - /* compute max duration */ - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (pRates->OutputVideoBitrate - + pRates->OutputAudioBitrate) * 8000.0); - - if( maxduration + pRates->BeginCutTime - > pC->InputFileProperties.uiClipDuration ) - { - maxduration = pC->InputFileProperties.uiClipDuration - - pRates->BeginCutTime; - } - - if( calcduration > maxduration ) - { - calcduration = maxduration; - } - - if( calcduration == 0 ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - - /* search max possible audio bitrate */ - maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (calcduration / 8000.0)); - - while( ( fixed_audio == M4OSA_FALSE) - && (pRates->OutputAudioBitrate - < M4VIDEOEDITING_k96_KBPS) ) - { - calcbitrate = M4MCS_intGetNearestBitrate( - pRates->OutputAudioBitrate, +1); - - if( calcbitrate - + pRates->OutputVideoBitrate <= maxcombinedbitrate ) - pRates->OutputAudioBitrate = calcbitrate; - else - break; - } - } - else - { - /* compute max duration */ - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (minvideobitrate + minaudiobitrate) * 8000.0); - - if( maxduration + pRates->BeginCutTime - > pC->InputFileProperties.uiClipDuration ) - { - maxduration = pC->InputFileProperties.uiClipDuration - - pRates->BeginCutTime; - } - - if( calcduration > maxduration ) - { - calcduration = maxduration; - } - - if( calcduration == 0 ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - - /* set audio = 1/3 and video = 2/3 */ - maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (calcduration / 8000.0)); - - if( fixed_audio == M4OSA_FALSE ) - { - if( pC->novideo ) - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate, - 0); - else - pRates->OutputAudioBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate - / 3, 0); - - if( pRates->OutputAudioBitrate < minaudiobitrate ) - pRates->OutputAudioBitrate = minaudiobitrate; - - if( pRates->OutputAudioBitrate - > M4VIDEOEDITING_k96_KBPS ) - pRates->OutputAudioBitrate = - M4VIDEOEDITING_k96_KBPS; - } - - if( fixed_video == M4OSA_FALSE ) - { - pRates->OutputVideoBitrate = - M4MCS_intGetNearestBitrate(maxcombinedbitrate - - pRates->OutputAudioBitrate, 0); - - if( pRates->OutputVideoBitrate < minvideobitrate ) - pRates->OutputVideoBitrate = minvideobitrate; - - if( pRates->OutputVideoBitrate - > M4VIDEOEDITING_k8_MBPS ) - pRates->OutputVideoBitrate = - M4VIDEOEDITING_k8_MBPS; /*+ New Encoder - bitrates */ - } - } - } - } - } - - /* recompute max duration with final bitrates */ - if( pRates->OutputFileSize > 0 ) - { - maxduration = (M4OSA_UInt32)(pRates->OutputFileSize - / M4MCS_MOOV_OVER_FILESIZE_RATIO - / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) - * 8000.0); - } - else - { - maxduration = pC->InputFileProperties.uiClipDuration; - } - - if( maxduration - + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) - { - maxduration = - pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; - } - - if( pRates->EndCutTime == 0 ) - { - pRates->EndCutTime = pRates->BeginCutTime + maxduration; - } - else - { - calcduration = pRates->EndCutTime - pRates->BeginCutTime; - - if( calcduration > maxduration ) - { - pRates->EndCutTime = pRates->BeginCutTime + maxduration; - } - } - - /* Should never happen : constraints are too strong */ - if( pRates->EndCutTime == pRates->BeginCutTime ) - { - return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; - } - - /* estimated resulting file size */ - pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO - * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) - * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0)); - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext) - * @brief Check parameters to start - * @note - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for - * this function to be called - * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: - * Audio bitrate too high (we limit to 96 kbps) - * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: - * Audio bitrate is too low (16 kbps min for aac, - * 12.2 for amr, 8 for mp3) - * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: - * Begin cut and End cut are equals - * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: - * Begin cut time is larger than the input - * clip duration - * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: - * End cut time is smaller than begin cut time - * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: - * Not enough space to store whole output - * file at given bitrates - * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: - * Video bitrate too high (we limit to 800 kbps) - * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: - * Video bitrate too low - ****************************************************************************** - */ -M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - M4MCS_EncodingParams VerifyRates; - M4OSA_ERR err; - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL"); - -#ifdef M4MCS_SUPPORT_STILL_PICTURE - - if( pC->m_bIsStillPicture ) - { - /** - * Call the corresponding still picture MCS function*/ - return M4MCS_stillPicCheckParamsAndStart(pC); - } - -#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ - - /** - * Check state automaton */ - - if( M4MCS_kState_SET != pC->State ) - { - M4OSA_TRACE1_1( - "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Audio bitrate should not stay undefined at this point */ - if( ( pC->noaudio == M4OSA_FALSE) - && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) - && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) - { - M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate"); - return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; - } - - /* Video bitrate should not stay undefined at this point */ - if( ( pC->novideo == M4OSA_FALSE) - && (pC->EncodingVideoFormat != M4ENCODER_kNULL) - && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) - { - M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate"); - return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; - } - - /* Set end cut time if necessary (not an error) */ - if( pC->uiEndCutTime == 0 ) - { - pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; - } - - /* Force a re-set to check validity of parameters */ - VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate; - VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate; - VerifyRates.BeginCutTime = pC->uiBeginCutTime; - VerifyRates.EndCutTime = pC->uiEndCutTime; - VerifyRates.OutputFileSize = pC->uiMaxFileSize; - VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale; - - err = M4MCS_setEncodingParams(pContext, &VerifyRates); - - /** - * Check parameters consistency */ - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found"); - return err; - } - - /** - * All is OK : update state automaton */ - pC->uiEncVideoBitrate = pC->uiVideoBitrate; - pC->AudioEncParams.Bitrate = pC->uiAudioBitrate; - -#ifdef M4MCS_WITH_FAST_OPEN - /** - * Remake the open if it was done in fast mode */ - - if( M4OSA_TRUE == pC->bFileOpenedInFastMode ) - { - /* Close the file opened in fast mode */ - M4MCS_intCleanUp_ReadersDecoders(pC); - - pC->State = M4MCS_kState_CREATED; - - /* Reopen it in normal mode */ - err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType, - pC->pOutputFile, pC->pTemporaryFile); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err); - return err; - } - } - -#endif /* M4MCS_WITH_FAST_OPEN */ - - pC->State = M4MCS_kState_READY; - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC) - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4ENCODER_Header *encHeader; - - /** - * Prepare the video decoder */ - err = M4MCS_intPrepareVideoDecoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x", - err); - return err; - } - - if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) - && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) - { - pC->bH264Trim = M4OSA_TRUE; - } - - /** - * Prepare the video encoder */ - err = M4MCS_intPrepareVideoEncoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x", - err); - return err; - } - - if( ( pC->uiBeginCutTime != 0) - && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) - && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) - { - - err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, - M4ENCODER_kOptionID_H264ProcessNALUContext, - (M4OSA_DataOption)pC->m_pInstance); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", - err); - return err; - } - - err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, - M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr, - (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", - err); - return err; - } - - err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt, - M4ENCODER_kOptionID_EncoderHeader, - (M4OSA_DataOption) &encHeader); - - if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) - { - M4OSA_TRACE1_1( - "M4MCS_close: failed to get the encoder header (err 0x%x)", - err); - /**< no return here, we still have stuff to deallocate after close, even if it fails.*/ - } - else - { - // Handle DSI first bits -#define SPS_START_POS 6 - - pC->m_pInstance->m_encoderSPSSize = - ( encHeader->pBuf[SPS_START_POS] << 8) - + encHeader->pBuf[SPS_START_POS + 1]; - pC->m_pInstance->m_pEncoderSPS = - (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2; - - pC->m_pInstance->m_encoderPPSSize = - ( encHeader->pBuf[SPS_START_POS + 3 - + pC->m_pInstance->m_encoderSPSSize] << 8) - + encHeader->pBuf[SPS_START_POS + 4 - + pC->m_pInstance->m_encoderSPSSize]; - pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5 - + pC->m_pInstance->m_encoderSPSSize; - - /* Check the DSI integrity */ - if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize - + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) ) - { - M4OSA_TRACE1_3( - "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d", - encHeader->Size, pC->m_pInstance->m_encoderSPSSize, - pC->m_pInstance->m_encoderPPSSize); - return M4ERR_PARAMETER; - } - } - } - - /** - * Prepare audio processing */ - err = M4MCS_intPrepareAudioProcessing(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x", - err); - return err; - } - - /** - * Prepare the writer */ - err = M4MCS_intPrepareWriter(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err); - return err; - } - - /** - * Jump the audio stream to the begin cut time (all AUs are RAP) - * Must be done after the 3gpp writer init, because it may write the first - * audio AU in some cases */ - err = M4MCS_intPrepareAudioBeginCut(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x", - err); - return err; - } - - /** - * Update state automaton */ - if( 0 == pC->uiBeginCutTime ) - { - pC->dViDecStartingCts = 0.0; - /** - * No begin cut, do the encoding */ - pC->State = M4MCS_kState_PROCESSING; - } - else - { - /** - * Remember that we must start the decode/encode process at the begin cut time */ - pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime; - - /** - * Jumping */ - pC->State = M4MCS_kState_BEGINVIDEOJUMP; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC); - * @brief Prepare the video decoder. - * @param pC (IN) MCS private context - * @return M4NO_ERROR No error - * @return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED - * @return Any error returned by an underlaying module - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4OSA_Void *decoderUserData; - M4DECODER_OutputFilter FilterOption; - - if( pC->novideo ) - return M4NO_ERROR; - - /** - * Create the decoder, if it has not been created yet (to get video properties for example) */ - if( M4OSA_NULL == pC->pViDecCtxt ) - { -#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS - - decoderUserData = pC->m_pCurrentVideoDecoderUserData; - -#else - - decoderUserData = M4OSA_NULL; - -#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */ - - err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt, - &pC->pReaderVideoStream->m_basicProperties, pC->m_pReader, - pC->m_pReaderDataIt, &pC->ReaderVideoAU, decoderUserData); - - if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err ) - { - /** - * Our decoder is not compatible with H263 profile other than 0. - * So it returns this internal error code. - * We translate it to our own error code */ - M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\ - returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED"); - return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ - m_pVideoDecoder->m_pFctCreate returns 0x%x", err); - return err; - } - - if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType ) - { - FilterOption.m_pFilterFunction = - (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420; - FilterOption.m_pFilterUserData = M4OSA_NULL; - err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt, - M4DECODER_kOptionID_OutputFilter, - (M4OSA_DataOption) &FilterOption); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ - m_pVideoDecoder->m_pFctSetOption returns 0x%x", err); - return err; - } - } - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC); - * @brief Prepare the video encoder. - * @param pC (IN) MCS private context - * @return M4NO_ERROR No error - * @return Any error returned by an underlaying module - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */ - M4ENCODER_Params EncParams1; - M4OSA_Double dFrameRate; /**< tmp variable */ - - if( pC->novideo ) - return M4NO_ERROR; - - if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) - { - /* Approximative cts increment */ - pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate; - - if( pC->uiBeginCutTime == 0 ) - { - M4OSA_TRACE3_0( - "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing."); - return M4NO_ERROR; - } - else - { - M4OSA_TRACE3_0( - "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults."); - - /* Set useful parameters to encode the first I-frame */ - EncParams.InputFormat = M4ENCODER_kIYUV420; - EncParams.videoProfile = pC->encodingVideoProfile; - EncParams.videoLevel= pC->encodingVideoLevel; - - switch( pC->InputFileProperties.VideoStreamType ) - { - case M4VIDEOEDITING_kH263: - EncParams.Format = M4ENCODER_kH263; - break; - - case M4VIDEOEDITING_kMPEG4: - EncParams.Format = M4ENCODER_kMPEG4; - break; - - case M4VIDEOEDITING_kH264: - EncParams.Format = M4ENCODER_kH264; - break; - - default: - M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\ - (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED", - pC->InputFileProperties.VideoStreamType); - return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED; - } - - EncParams.FrameWidth = pC->EncodingWidth; - EncParams.FrameHeight = pC->EncodingHeight; - EncParams.Bitrate = pC->uiEncVideoBitrate; - EncParams.bInternalRegulation = - M4OSA_FALSE; /* do not constrain the I-frame */ - EncParams.FrameRate = pC->EncodingVideoFramerate; - - /* Other encoding settings (quite all dummy...) */ - 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 = 5; /* initial QP = 5 */ - EncParams.bDataPartitioning = - M4OSA_FALSE; /* no data partitioning */ - - /* Rate factor */ - EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale; - EncParams.uiRateFactor = 1; - } - } - else - { - M4OSA_TRACE3_0( - "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config."); - - /** - * Set encoder shell parameters according to MCS settings */ - EncParams.Format = pC->EncodingVideoFormat; - EncParams.InputFormat = M4ENCODER_kIYUV420; - EncParams.videoProfile = pC->encodingVideoProfile; - EncParams.videoLevel= pC->encodingVideoLevel; - - /** - * Video frame size */ - EncParams.FrameWidth = pC->EncodingWidth; - EncParams.FrameHeight = pC->EncodingHeight; - - /** - * Video bitrate has been previously computed */ - EncParams.Bitrate = pC->uiEncVideoBitrate; - - /** - * MCS use the "true" core internal bitrate regulation */ - EncParams.bInternalRegulation = M4OSA_TRUE; - - /** - * Other encoder settings */ - - 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 */ - - - /** - * Video encoder frame rate and rate factor */ - EncParams.FrameRate = pC->EncodingVideoFramerate; - EncParams.uiTimeScale = pC->outputVideoTimescale; - - switch( pC->EncodingVideoFramerate ) - { - case M4ENCODER_k5_FPS: - dFrameRate = 5.0; - break; - - case M4ENCODER_k7_5_FPS: - dFrameRate = 7.5; - break; - - case M4ENCODER_k10_FPS: - dFrameRate = 10.0; - break; - - case M4ENCODER_k12_5_FPS: - dFrameRate = 12.5; - break; - - case M4ENCODER_k15_FPS: - dFrameRate = 15.0; - break; - - case M4ENCODER_k20_FPS: /**< MPEG-4 only */ - dFrameRate = 20.0; - break; - - case M4ENCODER_k25_FPS: /**< MPEG-4 only */ - dFrameRate = 25.0; - break; - - case M4ENCODER_k30_FPS: - dFrameRate = 30.0; - break; - - default: - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\ - (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", - pC->EncodingVideoFramerate); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; - } - - /** - * Compute the number of milliseconds between two frames */ - if( M4ENCODER_kH263 == EncParams.Format ) - { - pC->dCtsIncrement = 1001.0 / dFrameRate; - } - else /**< MPEG4 or H.264 */ - { - pC->dCtsIncrement = 1000.0 / dFrameRate; - } - } - - /** - * Limit the video bitrate according to encoder profile - * and level */ - err = M4MCS_intLimitBitratePerCodecProfileLevel(&EncParams); - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoEncoder: limit bitrate returned err \ - 0x%x", err); - return err; - } - - /** - * Create video encoder */ - err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt, - pC->pWriterDataFcts, \ - M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \ - pC->pCurrentVideoEncoderUserData); - - /**< We put the MCS context in place of the VPP context */ - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x", - err); - return err; - } - - pC->encoderState = M4MCS_kEncoderClosed; - - if( M4OSA_TRUE == pC->bH264Trim ) - //if((M4ENCODER_kNULL == pC->EncodingVideoFormat) - // && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType)) - { - EncParams1.InputFormat = EncParams.InputFormat; - //EncParams1.InputFrameWidth = EncParams.InputFrameWidth; - //EncParams1.InputFrameHeight = EncParams.InputFrameHeight; - EncParams1.FrameWidth = EncParams.FrameWidth; - EncParams1.FrameHeight = EncParams.FrameHeight; - EncParams1.videoProfile= EncParams.videoProfile; - EncParams1.videoLevel= EncParams.videoLevel; - EncParams1.Bitrate = EncParams.Bitrate; - EncParams1.FrameRate = EncParams.FrameRate; - EncParams1.Format = M4ENCODER_kH264; //EncParams.Format; - M4OSA_TRACE1_2("mcs encoder open profile :%d, level %d", - EncParams1.videoProfile, EncParams1.videoLevel); - err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, - &pC->WriterVideoAU, &EncParams1); - } - else - { - M4OSA_TRACE1_2("mcs encoder open Adv profile :%d, level %d", - EncParams.videoProfile, EncParams.videoLevel); - err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, - &pC->WriterVideoAU, &EncParams); - } - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x", - err); - return err; - } - - pC->encoderState = M4MCS_kEncoderStopped; - - if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart ) - { - err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x", - err); - return err; - } - } - - pC->encoderState = M4MCS_kEncoderRunning; - - /******************************/ - /* Video resize management */ - /******************************/ - /** - * Compare video input size and video output size to check if resize is needed */ - if( ( (M4OSA_UInt32)EncParams.FrameWidth - != pC->pReaderVideoStream->m_videoWidth) - || ((M4OSA_UInt32)EncParams.FrameHeight - != pC->pReaderVideoStream->m_videoHeight) ) - { - /** - * Allocate the intermediate video plane that will receive the decoded image before - resizing */ - pC->pPreResizeFrame = - (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3 * sizeof(M4VIFI_ImagePlane), - M4MCS, (M4OSA_Char *)"m_pPreResizeFrame"); - - if( M4OSA_NULL == pC->pPreResizeFrame ) - { - M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\ - unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - pC->pPreResizeFrame[0].pac_data = M4OSA_NULL; - pC->pPreResizeFrame[1].pac_data = M4OSA_NULL; - pC->pPreResizeFrame[2].pac_data = M4OSA_NULL; - - /** - * Allocate the Y plane */ - pC->pPreResizeFrame[0].u_topleft = 0; - pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream-> - m_videoWidth; /**< input width */ - pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream-> - m_videoHeight; /**< input height */ - pC->pPreResizeFrame[0].u_stride = pC-> - pPreResizeFrame[0].u_width; /**< simple case: stride equals width */ - - pC->pPreResizeFrame[0].pac_data = - (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[0].u_stride \ - *pC->pPreResizeFrame[0].u_height, M4MCS, - (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); - - if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoEncoder():\ - unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /** - * Allocate the U plane */ - pC->pPreResizeFrame[1].u_topleft = 0; - pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width - >> 1; /**< U width is half the Y width */ - pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height - >> 1; /**< U height is half the Y height */ - pC->pPreResizeFrame[1].u_stride = pC-> - pPreResizeFrame[1].u_width; /**< simple case: stride equals width */ - - pC->pPreResizeFrame[1].pac_data = - (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[1].u_stride \ - *pC->pPreResizeFrame[1].u_height, M4MCS, - (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); - - if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoEncoder():\ - unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /** - * Allocate the V plane */ - pC->pPreResizeFrame[2].u_topleft = 0; - pC->pPreResizeFrame[2].u_width = pC-> - pPreResizeFrame[1].u_width; /**< V width equals U width */ - pC->pPreResizeFrame[2].u_height = pC-> - pPreResizeFrame[1].u_height; /**< V height equals U height */ - pC->pPreResizeFrame[2].u_stride = pC-> - pPreResizeFrame[2].u_width; /**< simple case: stride equals width */ - - pC->pPreResizeFrame[2].pac_data = - (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[2].u_stride \ - *pC->pPreResizeFrame[2].u_height, M4MCS, - (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); - - if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoEncoder():\ - unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC); - * @brief Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder. - * @param pC (IN) MCS private context - * @return M4NO_ERROR No error - * @return Any error returned by an underlaying module - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - - SSRC_ReturnStatus_en - ReturnStatus; /* Function return status */ - LVM_INT16 NrSamplesMin = - 0; /* Minimal number of samples on the input or on the output */ - LVM_INT32 ScratchSize; /* The size of the scratch memory */ - LVM_INT16 - *pInputInScratch; /* Pointer to input in the scratch buffer */ - LVM_INT16 - *pOutputInScratch; /* Pointer to the output in the scratch buffer */ - SSRC_Params_t ssrcParams; /* Memory for init parameters */ - -#ifdef MCS_DUMP_PCM_TO_FILE - - file_au_reader = fopen("mcs_ReaderOutput.raw", "wb"); - file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb"); - file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb"); - -#endif - - if( pC->noaudio ) - return M4NO_ERROR; - - if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) - { - M4OSA_TRACE3_0( - "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing."); - return M4NO_ERROR; - } - - /* ________________________________ */ - /*| |*/ - /*| Create and "start" the decoder |*/ - /*|________________________________|*/ - - if( M4OSA_NULL == pC->m_pAudioDecoder ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder."); - return M4MCS_ERR_AUDIO_CONVERSION_FAILED; - } - - if( M4OSA_NULL == pC->pAudioDecCtxt ) - { - err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt, - pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", - err); - return err; - } - } - - if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) { - /* AMR DECODER CONFIGURATION */ - - /* nothing specific to do */ - } - else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) { - /* EVRC DECODER CONFIGURATION */ - - /* nothing specific to do */ - } - else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) { - /* MP3 DECODER CONFIGURATION */ - - /* nothing specific to do */ - } - else - { - /* AAC DECODER CONFIGURATION */ - M4_AacDecoderConfig AacDecParam; - - AacDecParam.m_AACDecoderProfile = AAC_kAAC; - AacDecParam.m_DownSamplingMode = AAC_kDS_OFF; - - if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) - { - AacDecParam.m_OutputMode = AAC_kMono; - } - else - { - /* For this version, we encode only in AAC */ - if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) - { - AacDecParam.m_OutputMode = AAC_kMono; - } - else - { - AacDecParam.m_OutputMode = AAC_kStereo; - } - } - - pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); - } - - pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); - - pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); - - if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) - { - /* Not implemented in all decoders */ - err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x", - err); - return err; - } - } - - /** - * Allocate output buffer for the audio decoder */ - pC->InputFileProperties.uiDecodedPcmSize = - pC->pReaderAudioStream->m_byteFrameLength - * pC->pReaderAudioStream->m_byteSampleSize - * pC->pReaderAudioStream->m_nbChannels; - - if( pC->InputFileProperties.uiDecodedPcmSize > 0 ) - { - pC->AudioDecBufferOut.m_bufferSize = - pC->InputFileProperties.uiDecodedPcmSize; - pC->AudioDecBufferOut.m_dataAddress = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->AudioDecBufferOut.m_bufferSize \ - *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize"); - } - - if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoDecoder():\ - unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /* _________________________ */ - /*| |*/ - /*| Set the SSRC parameters |*/ - /*|_________________________|*/ - - switch( pC->pReaderAudioStream->m_samplingFrequency ) - { - case 8000: - ssrcParams.SSRC_Fs_In = LVM_FS_8000; - break; - - case 11025: - ssrcParams.SSRC_Fs_In = LVM_FS_11025; - break; - - case 12000: - ssrcParams.SSRC_Fs_In = LVM_FS_12000; - break; - - case 16000: - ssrcParams.SSRC_Fs_In = LVM_FS_16000; - break; - - case 22050: - ssrcParams.SSRC_Fs_In = LVM_FS_22050; - break; - - case 24000: - ssrcParams.SSRC_Fs_In = LVM_FS_24000; - break; - - case 32000: - ssrcParams.SSRC_Fs_In = LVM_FS_32000; - break; - - case 44100: - ssrcParams.SSRC_Fs_In = LVM_FS_44100; - break; - - case 48000: - ssrcParams.SSRC_Fs_In = LVM_FS_48000; - break; - - default: - M4OSA_TRACE1_1( - "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\ - returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", - pC->pReaderAudioStream->m_samplingFrequency); - return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; - } - - if( 1 == pC->pReaderAudioStream->m_nbChannels ) - { - ssrcParams.SSRC_NrOfChannels = LVM_MONO; - } - else - { - ssrcParams.SSRC_NrOfChannels = LVM_STEREO; - } - - /*FlB 26.02.2009: add mp3 as output format*/ - if( pC->AudioEncParams.Format == M4ENCODER_kAAC - || pC->AudioEncParams.Format == M4ENCODER_kMP3 ) - { - switch( pC->AudioEncParams.Frequency ) - { - case M4ENCODER_k8000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_8000; - break; - - case M4ENCODER_k11025Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_11025; - break; - - case M4ENCODER_k12000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_12000; - break; - - case M4ENCODER_k16000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_16000; - break; - - case M4ENCODER_k22050Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_22050; - break; - - case M4ENCODER_k24000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_24000; - break; - - case M4ENCODER_k32000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_32000; - break; - - case M4ENCODER_k44100Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_44100; - break; - - case M4ENCODER_k48000Hz: - ssrcParams.SSRC_Fs_Out = LVM_FS_48000; - break; - - default: - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \ - (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", - pC->AudioEncParams.Frequency); - return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; - break; - } - } - else - { - ssrcParams.SSRC_Fs_Out = LVM_FS_8000; - } - - - - ReturnStatus = 0; - - switch( ssrcParams.SSRC_Fs_In ) - { - case LVM_FS_8000: - ssrcParams.NrSamplesIn = 320; - break; - - case LVM_FS_11025: - ssrcParams.NrSamplesIn = 441; - break; - - case LVM_FS_12000: - ssrcParams.NrSamplesIn = 480; - break; - - case LVM_FS_16000: - ssrcParams.NrSamplesIn = 640; - break; - - case LVM_FS_22050: - ssrcParams.NrSamplesIn = 882; - break; - - case LVM_FS_24000: - ssrcParams.NrSamplesIn = 960; - break; - - case LVM_FS_32000: - ssrcParams.NrSamplesIn = 1280; - break; - - case LVM_FS_44100: - ssrcParams.NrSamplesIn = 1764; - break; - - case LVM_FS_48000: - ssrcParams.NrSamplesIn = 1920; - break; - - default: - ReturnStatus = -1; - break; - } - - switch( ssrcParams.SSRC_Fs_Out ) - { - case LVM_FS_8000: - ssrcParams.NrSamplesOut = 320; - break; - - case LVM_FS_11025: - ssrcParams.NrSamplesOut = 441; - break; - - case LVM_FS_12000: - ssrcParams.NrSamplesOut = 480; - break; - - case LVM_FS_16000: - ssrcParams.NrSamplesOut = 640; - break; - - case LVM_FS_22050: - ssrcParams.NrSamplesOut = 882; - break; - - case LVM_FS_24000: - ssrcParams.NrSamplesOut = 960; - break; - - case LVM_FS_32000: - ssrcParams.NrSamplesOut = 1280; - break; - - case LVM_FS_44100: - ssrcParams.NrSamplesOut = 1764; - break; - - case LVM_FS_48000: - ssrcParams.NrSamplesOut = 1920; - break; - - default: - ReturnStatus = -1; - break; - } - - - - if( ReturnStatus != SSRC_OK ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioProcessing:\ - Error code %d returned by the SSRC_GetNrSamples function", - ReturnStatus); - return M4MCS_ERR_AUDIO_CONVERSION_FAILED; - } - - NrSamplesMin = - (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut) - ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn); - - while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE ) - { /* Don't take blocks smaller that the minimal block size */ - ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1); - ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1); - NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1); - } - - - pC->iSsrcNbSamplIn = (LVM_INT16)( - ssrcParams. - NrSamplesIn); /* multiplication by NrOfChannels is done below */ - pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut); - - /** - * Allocate buffer for the input of the SSRC */ - pC->pSsrcBufferIn = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplIn * sizeof(short) \ - *pC->pReaderAudioStream->m_nbChannels, M4MCS, - (M4OSA_Char *)"pSsrcBufferIn"); - - if( M4OSA_NULL == pC->pSsrcBufferIn ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoDecoder():\ - unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn; - - /** - * Allocate buffer for the output of the SSRC */ - pC->pSsrcBufferOut = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplOut * sizeof(short) \ - *pC->pReaderAudioStream->m_nbChannels, M4MCS, - (M4OSA_Char *)"pSsrcBufferOut"); - - if( M4OSA_NULL == pC->pSsrcBufferOut ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareVideoDecoder():\ - unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - - pC->pLVAudioResampler = LVAudioResamplerCreate( - 16, /*gInputParams.lvBTChannelCount*/ - (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/, - (M4OSA_Int32)(pC->AudioEncParams.Frequency)/*ssrcParams.SSRC_Fs_Out*/, 1); - - if( M4OSA_NULL == pC->pLVAudioResampler) - { - return M4ERR_ALLOC; - } - - LVAudiosetSampleRate(pC->pLVAudioResampler, - /*gInputParams.lvInSampleRate*/ - /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/ - pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/); - - LVAudiosetVolume(pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */), - (M4OSA_Int16)(0x1000/*0x7fff*/)); - - - /* ________________________ */ - /*| |*/ - /*| Init the audio encoder |*/ - /*|________________________|*/ - - /* Initialise the audio encoder */ - - err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt, - pC->pCurrentAudioEncoderUserData); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x", - err); - return err; - } - - /* Open the audio encoder */ - err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt, - &pC->AudioEncParams, &pC->pAudioEncDSI, - M4OSA_NULL /* no grabbing */); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x", - err); - return err; - } - - /* Allocate the input buffer for the audio encoder */ - switch( pC->AudioEncParams.Format ) - { - case M4ENCODER_kAMRNB: - pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES; - break; - - case M4ENCODER_kAAC: - pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES; - break; - - /*FlB 26.02.2009: add mp3 as output format*/ - case M4ENCODER_kMP3: - pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES; - break; - - default: - break; - } - - if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) - pC->audioEncoderGranularity *= sizeof(short); - else - pC->audioEncoderGranularity *= sizeof(short) * 2; - - pC->pPosInAudioEncoderBuffer = M4OSA_NULL; - pC->pAudioEncoderBuffer = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->audioEncoderGranularity, M4MCS, - (M4OSA_Char *)"pC->pAudioEncoderBuffer"); - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC); - * @brief Prepare the writer. - * @param pC (IN) MCS private context - * @return M4NO_ERROR No error - * @return Any error returned by an underlaying module - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */ - M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */ - M4SYS_StreamIDValue optionValue; /**< For the setoption calls */ - M4OSA_UInt32 TargetedFileSize; - M4OSA_Bool bMULPPSSPS = M4OSA_FALSE; - - /** - * Init the writer */ - err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile, - pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x", - err); - return err; - } - - /** - * Link to the writer context in the writer interface */ - pC->pWriterDataFcts->pWriterContext = pC->pWriterContext; - - /** - * Set the product description string in the written file */ - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS "); - - if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x", - err); - return err; - } - - /** - * Set the product version in the written file */ - uiVersion = - M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 - + M4VIDEOEDITING_VERSION_REVISION; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); - - if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: \ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x", - err); - return err; - } - - /** - * If there is a video input, allocate and fill the video stream structures for the writer */ - if( pC->novideo == M4OSA_FALSE ) - { - /** - * Fill Video properties structure for the AddStream method */ - pC->WriterVideoStreamInfo.height = pC->EncodingHeight; - pC->WriterVideoStreamInfo.width = pC->EncodingWidth; - pC->WriterVideoStreamInfo.fps = - 0; /**< Not used by the shell/core writer */ - pC->WriterVideoStreamInfo.Header.pBuf = - M4OSA_NULL; /**< Will be updated later */ - pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */ - - /** - * Fill Video stream description structure for the AddStream method */ - switch( pC->EncodingVideoFormat ) - { - case M4ENCODER_kMPEG4: - pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; - break; - - case M4ENCODER_kH263: - pC->WriterVideoStream.streamType = M4SYS_kH263; - break; - - case M4ENCODER_kH264: - pC->WriterVideoStream.streamType = M4SYS_kH264; - break; - - case M4ENCODER_kNULL: - switch( pC->InputFileProperties.VideoStreamType ) - { - case M4VIDEOEDITING_kMPEG4: - pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; - break; - - case M4VIDEOEDITING_kH263: - pC->WriterVideoStream.streamType = M4SYS_kH263; - break; - - case M4VIDEOEDITING_kH264: - pC->WriterVideoStream.streamType = M4SYS_kH264; - break; - - default: - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \ - unknown format (0x%x),\ - returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", - pC->EncodingVideoFormat); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; - } - break; - - default: /**< It should never happen, already tested */ - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: unknown format (0x%x),\ - returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", - pC->EncodingVideoFormat); - return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; - } - - /** - * Video bitrate value will be the real value */ - pC->WriterVideoStream.averageBitrate = - (M4OSA_Int32)pC->uiEncVideoBitrate; - pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate; - - /** - * most other parameters are "dummy" */ - pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; - pC->WriterVideoStream.timeScale = - 0; /**< Not used by the shell/core writer */ - pC->WriterVideoStream.profileLevel = - 0; /**< Not used by the shell/core writer */ - pC->WriterVideoStream.duration = - 0; /**< Not used by the shell/core writer */ - pC->WriterVideoStream.decoderSpecificInfoSize = - sizeof(M4WRITER_StreamVideoInfos); - pC->WriterVideoStream.decoderSpecificInfo = - (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo); - - /** - * Update Encoder Header properties for Video stream if needed */ - if( M4ENCODER_kH263 == pC->EncodingVideoFormat ) - { - /** - * Creates the H263 DSI */ - pC->WriterVideoStreamInfo.Header.Size = - 7; /**< H263 output DSI is always 7 bytes */ - pDSI = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(7, M4MCS, (M4OSA_Char - *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)"); - - if( M4OSA_NULL == pDSI ) - { - M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /** - * Vendor is NXP Software: N, X, P, S. */ - pDSI[0] = 'N'; - pDSI[1] = 'X'; - pDSI[2] = 'P'; - pDSI[3] = 'S'; - - /** - * Decoder version is 0 */ - pDSI[4] = 0; - - /** - * Level is the sixth byte of the DSI. */ - switch( pC->EncodingWidth ) - { - case M4ENCODER_SQCIF_Width: - case M4ENCODER_QCIF_Width: - if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) - { - pDSI[5] = 10; - } - else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) - { - pDSI[5] = 45; - } - else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) - { - pDSI[5] = 20; - } - else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) - { - pDSI[5] = 30; - } - else if( ( pC->uiEncVideoBitrate - <= M4ENCODER_k800_KBPS/*2048*/) - && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) - { - pDSI[5] = 40; - } - break; - - case M4ENCODER_CIF_Width: - if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) - { - pDSI[5] = 20; - } - else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) - && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) - { - pDSI[5] = 30; - } - else if( ( pC->uiEncVideoBitrate - <= M4ENCODER_k800_KBPS/*2048*/) - && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) - { - pDSI[5] = 40; - } - break; - - default: - break; - } - - /** - * Profile is the seventh byte of the DSI. */ - pDSI[6] = 0; - - pC->WriterVideoStreamInfo.Header.pBuf = pDSI; - } - else if( M4ENCODER_kNULL == pC->EncodingVideoFormat ) - { - /* If we copy the stream from the input, we copy its DSI */ - - pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream-> - m_basicProperties.m_decoderSpecificInfoSize; - pC->WriterVideoStreamInfo.Header.pBuf = - (M4OSA_MemAddr8)pC->pReaderVideoStream-> - m_basicProperties.m_pDecoderSpecificInfo; - - } - /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */ - - /*+CRLV6775 - H.264 Trimming */ - if( pC->bH264Trim == M4OSA_TRUE ) - { - bMULPPSSPS = M4OSA_TRUE; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS, - (M4OSA_DataOption) &bMULPPSSPS); - - if( ( M4NO_ERROR != err) - && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x", - err); - return err; - } - } - /*-CRLV6775 - H.264 Trimming */ - /** - * Add the video stream */ - err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, - &pC->WriterVideoStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", - err); - return err; - } - - /** - * Update AU properties for video stream */ - pC->WriterVideoAU.stream = &(pC->WriterVideoStream); - pC->WriterVideoAU.dataAddress = M4OSA_NULL; - pC->WriterVideoAU.size = 0; - pC->WriterVideoAU.CTS = 0; /** Reset time */ - pC->WriterVideoAU.DTS = 0; - pC->WriterVideoAU.attribute = AU_RAP; - pC->WriterVideoAU.nbFrag = 0; /** No fragment */ - pC->WriterVideoAU.frag = M4OSA_NULL; - - /** - * Set the writer max video AU size */ - optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; - optionValue.value = pC->uiVideoMaxAuSize; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxAUSize, - (M4OSA_DataOption) &optionValue); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: \ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", - err); - return err; - } - - /** - * Set the writer max video chunk size */ - optionValue.value = pC->uiVideoMaxChunckSize; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxChunckSize, - (M4OSA_DataOption) &optionValue); - - if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", - err); - return err; - } - } - - /** - * If there is an audio input, allocate and fill the audio stream structures for the writer */ - if( pC->noaudio == M4OSA_FALSE ) - { - M4WRITER_StreamAudioInfos streamAudioInfo; - - streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ - streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ - streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ - - pC->WriterAudioStream.averageBitrate = - 0; /**< It is not used by the shell, the DSI is taken into account instead */ - pC->WriterAudioStream.maxBitrate = - 0; /**< Not used by the shell/core writer */ - - /** - * Fill Audio stream description structure for the AddStream method */ - switch( pC->AudioEncParams.Format ) - { - case M4ENCODER_kAMRNB: - pC->WriterAudioStream.streamType = M4SYS_kAMR; - break; - - case M4ENCODER_kAAC: - pC->WriterAudioStream.streamType = M4SYS_kAAC; - pC->WriterAudioStream.averageBitrate = - pC->AudioEncParams.Bitrate; - pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate; - break; - - /*FlB 26.02.2009: add mp3 as output format*/ - case M4ENCODER_kMP3: - pC->WriterAudioStream.streamType = M4SYS_kMP3; - break; - - case M4ENCODER_kAudioNULL: - switch( pC->InputFileProperties.AudioStreamType ) - { - case M4VIDEOEDITING_kAMR_NB: - pC->WriterAudioStream.streamType = M4SYS_kAMR; - break; - /*FlB 26.02.2009: add mp3 as output format*/ - case M4VIDEOEDITING_kMP3: - pC->WriterAudioStream.streamType = M4SYS_kMP3; - break; - - case M4VIDEOEDITING_kAAC: - case M4VIDEOEDITING_kAACplus: - case M4VIDEOEDITING_keAACplus: - pC->WriterAudioStream.streamType = M4SYS_kAAC; - pC->WriterAudioStream.averageBitrate = - pC->AudioEncParams.Bitrate; - pC->WriterAudioStream.maxBitrate = - pC->AudioEncParams.Bitrate; - break; - - case M4VIDEOEDITING_kEVRC: - pC->WriterAudioStream.streamType = M4SYS_kEVRC; - break; - - case M4VIDEOEDITING_kNoneAudio: - case M4VIDEOEDITING_kPCM: - case M4VIDEOEDITING_kNullAudio: - case M4VIDEOEDITING_kUnsupportedAudio: - break; - } - break; - - default: /**< It should never happen, already tested */ - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: \ - unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", - pC->AudioEncParams.Format); - return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; - } - - /** - * MCS produces only AMR-NB output */ - pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; - pC->WriterAudioStream.duration = - 0; /**< Not used by the shell/core writer */ - pC->WriterAudioStream.profileLevel = - 0; /**< Not used by the shell/core writer */ - pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency; - - if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) - { - /* If we copy the stream from the input, we copy its DSI */ - streamAudioInfo.Header.Size = pC->pReaderAudioStream-> - m_basicProperties.m_decoderSpecificInfoSize; - streamAudioInfo.Header.pBuf = - (M4OSA_MemAddr8)pC->pReaderAudioStream-> - m_basicProperties.m_pDecoderSpecificInfo; - } - else - { - if( pC->pAudioEncDSI.pInfo != M4OSA_NULL ) - { - /* Use the DSI given by the encoder open() */ - streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize; - streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo; - } - else - { - /* Writer will put a default Philips DSI */ - streamAudioInfo.Header.Size = 0; - streamAudioInfo.Header.pBuf = M4OSA_NULL; - } - } - - /** - * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos - in the DSI pointer... */ - pC->WriterAudioStream.decoderSpecificInfo = - (M4OSA_MemAddr32) &streamAudioInfo; - - /** - * Add the audio stream to the writer */ - err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, - &pC->WriterAudioStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x", - err); - return err; - } - - /** - * Link the AU and the stream */ - pC->WriterAudioAU.stream = &(pC->WriterAudioStream); - pC->WriterAudioAU.dataAddress = M4OSA_NULL; - pC->WriterAudioAU.size = 0; - pC->WriterAudioAU.CTS = 0; /** Reset time */ - pC->WriterAudioAU.DTS = 0; - pC->WriterAudioAU.attribute = 0; - pC->WriterAudioAU.nbFrag = 0; /** No fragment */ - pC->WriterAudioAU.frag = M4OSA_NULL; - - /** - * Set the writer audio max AU size */ - /* As max bitrate is now 320kbps instead of 128kbps, max AU - * size has to be increased adapt the max AU size according to the stream type and the - * channels numbers*/ - /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite) - */ - //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE; - switch( pC->WriterAudioStream.streamType ) - { - case M4SYS_kAMR: - pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES - * (( pC->InputFileProperties.uiNbChannels - * sizeof(short)) + 3); - break; - - case M4SYS_kMP3: - pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES - * (( pC->InputFileProperties.uiNbChannels - * sizeof(short)) + 3); - break; - - case M4SYS_kAAC: - pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES - * (( pC->InputFileProperties.uiNbChannels - * sizeof(short)) + 3); - break; - /*case M4SYS_kEVRC: - pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES* - ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3); - break;*/ - default: /**< It should never happen, already tested */ - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: unknown format (0x%x),\ - returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", - pC->WriterAudioStream.streamType); - return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; - } - - optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; - optionValue.value = pC->uiAudioMaxAuSize; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxAUSize, - (M4OSA_DataOption) &optionValue); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ - M4WRITER_kMaxAUSize) returns 0x%x", - err); - return err; - } - - optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE; - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxChunckSize, - (M4OSA_DataOption) &optionValue); - - if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ - M4WRITER_kMaxChunckSize) returns 0x%x", - err); - return err; - } - } - - /* - * Set the limitation size of the writer */ - TargetedFileSize = pC->uiMaxFileSize; - /* add 1 kB margin */ - if( TargetedFileSize > 8192 ) - TargetedFileSize -= 1024; - - err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxFileSize, - (M4OSA_DataOption) &TargetedFileSize); - - if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\ - (M4WRITER_kMaxFileSize) returns 0x%x!", - err); - return err; - } - - /** - * Close the stream registering in order to be ready to write data */ - err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x", - err); - return err; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC); - * @brief DO the audio begin cut. - * @param pC (IN) MCS private context - * @return M4NO_ERROR No error - * @return Any error returned by an underlaying module - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4OSA_Int32 iCts; - M4OSA_UInt32 uiFrameSize; - - if( pC->noaudio ) - return M4NO_ERROR; - - /** - * Check if an audio begin cut is needed */ - if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) ) - { - /** - * Return with no error */ - M4OSA_TRACE3_0( - "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)"); - return M4NO_ERROR; - } - - /** - * Jump at the begin cut time */ - iCts = pC->uiBeginCutTime; - err = pC->m_pReader->m_pFctJump(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, &iCts); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!", - err); - return err; - } - - /** - * Remember audio begin cut offset */ - pC->iAudioCtsOffset = iCts; - - /** - * AMR-NB & EVRC: there may be many frames per AU. - * In that case we need to slice the first AU to keep the 20 ms cut precision */ - if( ( M4DA_StreamTypeAudioAmrNarrowBand - == pC->pReaderAudioStream->m_basicProperties.m_streamType) - || (M4DA_StreamTypeAudioEvrc - == pC->pReaderAudioStream->m_basicProperties.m_streamType) ) - { - /** - * If the next frame CTS is lower than the begin cut time, - * we must read the AU and parse its frames to reach the - * nearest to the begin cut */ - if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime ) - { - /** - * Read the first audio AU after the jump */ - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU); - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE1_0( - "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\ - returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR"); - return - M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\ - returns 0x%x", - err); - return err; - } - - /** - * While the next AU has a lower CTS than the begin cut time, we advance to - the next frame */ - while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime ) - { - /** - * Get the size of the frame */ - switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) - { - case M4DA_StreamTypeAudioAmrNarrowBand: - uiFrameSize = M4MCS_intGetFrameSize_AMRNB( - pC->ReaderAudioAU.m_dataAddress); - break; - - case M4DA_StreamTypeAudioEvrc: - uiFrameSize = M4MCS_intGetFrameSize_EVRC( - pC->ReaderAudioAU.m_dataAddress); - break; - - default: - uiFrameSize = 0; - break; - } - - if( 0 == uiFrameSize ) - { - /** - * Corrupted frame! We get out of this mess! - * We don't want to crash here... */ - M4OSA_TRACE1_0( - "M4MCS_intPrepareAudioBeginCut(): \ - M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR"); - return - M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ - } - - /** - * Go to the next frame */ - pC->ReaderAudioAU.m_dataAddress += uiFrameSize; - pC->ReaderAudioAU.m_size -= uiFrameSize; - - /** - * Get the CTS of the next frame */ - iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */ - pC->ReaderAudioAU.m_CTS = iCts; - pC->ReaderAudioAU.m_DTS = iCts; - } - - /** - * Update the audio begin cut offset */ - pC->iAudioCtsOffset = iCts; - } - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress) - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC, - M4OSA_UInt8 *pProgress ) -{ - M4OSA_ERR err; - M4OSA_UInt32 uiAudioStepCount = 0; - - /* ---------- VIDEO TRANSCODING ---------- */ - - if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED - == pC->VideoState) ) /**< If the video encoding is going on */ - { - if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) - { - err = M4MCS_intVideoNullEncoding(pC); - } - else - { - err = M4MCS_intVideoTranscoding(pC); - } - - /** - * No more space, quit properly */ - if( M4WAR_WRITER_STOP_REQ == err ) - { - *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts - - pC->uiBeginCutTime) * 100) - / (pC->uiEndCutTime - pC->uiBeginCutTime)); - - pC->State = M4MCS_kState_FINISHED; - - /* bad file produced on very short 3gp file */ - if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 ) - { - /* Nothing has been encoded -> bad produced file -> error returned */ - M4OSA_TRACE2_0( - "M4MCS_intStepEncoding(): video transcoding returns\ - M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); - return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; - } - else - { -#ifndef M4MCS_AUDIOONLY - /* clean AIR context needed to keep media aspect ratio*/ - - if( M4OSA_NULL != pC->m_air_context ) - { - err = M4AIR_cleanUp(pC->m_air_context); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", - err); - return err; - } - pC->m_air_context = M4OSA_NULL; - } - -#endif /*M4MCS_AUDIOONLY*/ - - M4OSA_TRACE2_0( - "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE"); - return M4MCS_ERR_NOMORE_SPACE; - } - } - - /**< The input plane is null because the input image will be obtained by the - VPP filter from the context */ - if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepEncoding(): video transcoding returns 0x%x!", - err); - return err; - } - } - - /* ---------- AUDIO TRANSCODING ---------- */ - - if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED - == pC->AudioState) ) /**< If there is an audio stream */ - { - while( - /**< If the video encoding is running, encode audio until we reach video time */ - ( ( pC->novideo == M4OSA_FALSE) - && (M4MCS_kStreamState_STARTED == pC->VideoState) - && (pC->ReaderAudioAU.m_CTS - + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) || - /**< If the video encoding is not running, perform 1 step of audio encoding */ - (( M4MCS_kStreamState_STARTED == pC->AudioState) - && (uiAudioStepCount < 1)) ) - { - uiAudioStepCount++; - - /**< check if an adio effect has to be applied*/ - err = M4MCS_intCheckAudioEffects(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x", - err); - return err; - } - - if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) - { - err = M4MCS_intAudioNullEncoding(pC); - } - else /**< Audio transcoding */ - { - err = M4MCS_intAudioTranscoding(pC); - } - - /** - * No more space, quit properly */ - if( M4WAR_WRITER_STOP_REQ == err ) - { - *pProgress = - (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS - - pC->uiBeginCutTime) * 100) - / (pC->uiEndCutTime - pC->uiBeginCutTime)); - - pC->State = M4MCS_kState_FINISHED; - - /* bad file produced on very short 3gp file */ - if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 ) - { - /* Nothing has been encoded -> bad produced file -> error returned */ - M4OSA_TRACE2_0( - "M4MCS_intStepEncoding():\ - audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); - return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; - } - else - { -#ifndef M4MCS_AUDIOONLY - /* clean AIR context needed to keep media aspect ratio*/ - - if( M4OSA_NULL != pC->m_air_context ) - { - err = M4AIR_cleanUp(pC->m_air_context); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", - err); - return err; - } - pC->m_air_context = M4OSA_NULL; - } - -#endif /*M4MCS_AUDIOONLY*/ - - M4OSA_TRACE2_0( - "M4MCS_intStepEncoding(): \ - audio transcoding returns M4MCS_ERR_NOMORE_SPACE"); - return M4MCS_ERR_NOMORE_SPACE; - } - } - - if( M4WAR_NO_MORE_AU == err ) - { - pC->AudioState = M4MCS_kStreamState_FINISHED; - M4OSA_TRACE3_0( - "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU"); - break; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepEncoding(): audio transcoding returns 0x%x", - err); - return err; - } - - /** - * Check for end cut */ - /* We absolutely want to have less or same audio duration as video -> - (2*pC->m_audioAUDuration) */ - if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS - + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime ) - { - pC->AudioState = M4MCS_kStreamState_FINISHED; - break; - } - } - } - - /* ---------- PROGRESS MANAGEMENT ---------- */ - - /** - * Compute progress */ - if( pC->novideo ) - { - if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime ) - { - *pProgress = 0; - } - else - { - *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS - - pC->uiBeginCutTime) * 100) - / (pC->uiEndCutTime - pC->uiBeginCutTime)); - } - //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS); - - } - else - { - if( pC->dViDecCurrentCts < pC->uiBeginCutTime ) - { - *pProgress = 0; - } - else - { - *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts - - pC->uiBeginCutTime) * 100) - / (pC->uiEndCutTime - pC->uiBeginCutTime)); - } - //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts); - } - - /** - * Sanity check */ - if( *pProgress > 99 ) - { - *pProgress = 99; - } - - /** - * Increment CTS for next step */ - if( pC->novideo == M4OSA_FALSE ) - { - if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) - { - pC->dViDecCurrentCts += 1; - } - else - { - pC->dViDecCurrentCts += pC->dCtsIncrement; - } - } - - /** - * The transcoding is finished when no stream is being encoded anymore */ - if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState)) - && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) ) - { - /* the AIR part can only be used when video codecs are compiled*/ -#ifndef M4MCS_AUDIOONLY - /* clean AIR context needed to keep media aspect ratio*/ - - if( M4OSA_NULL != pC->m_air_context ) - { - err = M4AIR_cleanUp(pC->m_air_context); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", - err); - return err; - } - pC->m_air_context = M4OSA_NULL; - } - -#endif /*M4MCS_AUDIOONLY*/ - /**/ - - *pProgress = 100; - pC->State = M4MCS_kState_FINISHED; - M4OSA_TRACE2_0( - "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE"); - return M4MCS_WAR_TRANSCODING_DONE; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC) - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4OSA_Int32 iCts; - - if( pC->novideo ) - { - pC->State = M4MCS_kState_BEGINVIDEODECODE; - return M4NO_ERROR; - } - - /** - * Jump to the previous RAP in the clip (first get the time, then jump) */ - iCts = (M4OSA_Int32)pC->dViDecStartingCts; - err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); - - if( M4WAR_READER_INFORMATION_NOT_PRESENT == err ) - { - /* No RAP table, jump backward and predecode */ - iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT; - - if( iCts < 0 ) - iCts = 0; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!", - err); - return err; - } - - /* + CRLV6775 -H.264 Trimming */ - - if( M4OSA_TRUE == pC->bH264Trim ) - { - - // Save jump time for safety, this fix should be generic - - M4OSA_Int32 iCtsOri = iCts; - - - err = pC->m_pReader->m_pFctJump(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", - err); - return err; - } - - if( pC->ReaderVideoAU1.m_structSize == 0 ) - { - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU1); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", - err); - return err; - } - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU1); - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE2_0( - "M4MCS_intVideoNullEncoding(): \ - m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); - /* The audio transcoding is finished */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", - err); - return err; - } - - pC->ReaderVideoAU1.m_structSize = 0; - } - - err = H264MCS_ProcessSPS_PPS(pC->m_pInstance, - (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!", - err); - return err; - } - - - // Restore jump time for safety, this fix should be generic - - iCts = iCtsOri; - - - } - /* - CRLV6775 -H.264 Trimming */ - - /** - * Decode one step */ - pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr); - - /** - * Be sure we don't decode too far */ - if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) - { - pC->dViDecCurrentCts = pC->dViDecStartingCts; - } - - /** - * Decode at least once with the bJump flag to true */ - M4OSA_TRACE3_1( - "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f", - pC->dViDecCurrentCts); - pC->isRenderDup = M4OSA_FALSE; - err = - pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts, - M4OSA_TRUE, 0); - - if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) - && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err); - return err; - } - - if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) - { - M4OSA_TRACE2_0("Decoding output the same frame as before 1"); - pC->isRenderDup = M4OSA_TRUE; - } - - /** - * Increment decoding cts for the next step */ - pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; - - /** - * Update state automaton */ - if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) - { - /** - * Be sure we don't decode too far */ - pC->dViDecCurrentCts = pC->dViDecStartingCts; - pC->State = M4MCS_kState_PROCESSING; - } - else - { - pC->State = M4MCS_kState_BEGINVIDEODECODE; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC) - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - M4_MediaTime dDecTarget; - - if( pC->novideo ) - { - pC->State = M4MCS_kState_PROCESSING; - return M4NO_ERROR; - } - - /** - * Decode */ - dDecTarget = pC->dViDecCurrentCts; - M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f", - pC->dViDecCurrentCts); - pC->isRenderDup = M4OSA_FALSE; - err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget, - M4OSA_FALSE, 0); - - if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) - && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) - { - M4OSA_TRACE1_1( - "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err); - return err; - } - - if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) - { - M4OSA_TRACE2_0("Decoding output the same frame as before 2"); - pC->isRenderDup = M4OSA_TRUE; - } - - /** - * Increment decoding cts for the next step */ - pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; - - /** - * Update state automaton, if needed */ - if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts) - || (M4WAR_NO_MORE_AU == err) ) - { - /** - * Be sure we don't decode too far */ - pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts; - pC->State = M4MCS_kState_PROCESSING; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/*****************************/ -/* define AMR silence frames */ -/*****************************/ - -#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13 -#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160 - -#ifdef M4VSS3GPP_SILENCE_FRAMES - -const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[ - M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] = - { - 0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00 - }; -#else - -extern -const -M4OSA_UInt8 -M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE]; - -#endif - -/*****************************/ -/* define AAC silence frames */ -/*****************************/ - -#define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE 4 - -#ifdef M4VSS3GPP_SILENCE_FRAMES - -const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[ - M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] = - { - 0x00, 0xC8, 0x20, 0x07 - }; -#else - -extern const M4OSA_UInt8 -M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE]; - -#endif - -#define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE 6 - -#ifdef M4VSS3GPP_SILENCE_FRAMES - -const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[ - M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] = - { - 0x21, 0x10, 0x03, 0x20, 0x54, 0x1C - }; -#else - -extern const -M4OSA_UInt8 -M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE]; - -#endif - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC) - * @return M4NO_ERROR: No error - ****************************************************************************** - */ - -static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; - - if( pC->noaudio ) - return M4NO_ERROR; - - /* Check if all audio frame has been written (happens at begin cut) */ - if( pC->ReaderAudioAU.m_size == 0 ) - { - /** - * Initializes a new AU if needed */ - if( pC->ReaderAudioAU1.m_structSize == 0 ) - { - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU1); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", - err); - return err; - } - - pC->m_pDataAddress1 = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU1.m_maxsize, - M4MCS, (M4OSA_Char *)"Temporary AU1 buffer"); - - if( pC->m_pDataAddress1 == M4OSA_NULL ) - { - M4OSA_TRACE1_0( - "M4MCS_intAudioNullEncoding(): allocation error"); - return M4ERR_ALLOC; - } - - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU1); - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE2_0( - "M4MCS_intAudioNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); - /* The audio transcoding is finished */ - pC->AudioState = M4MCS_kStreamState_FINISHED; - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioNullEncoding(): \ - m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", - err); - return err; - } - /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying , - constant memory reader case*/ - if( pC->ReaderAudioAU1.m_maxsize - > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize); - /* pC->m_pDataAddress1 and - pC->m_pDataAddress2 must be reallocated at the same time */ - /* because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take - maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > - pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true */ - /* and the size of the second buffer is never changed. */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); - /* pC->m_pDataAddress1 and - pC->m_pDataAddress2 must be reallocated at the same time */ - /* Update stream properties */ - pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = - pC->ReaderAudioAU1.m_maxsize; - } - /**/ - memcpy((void *)pC->m_pDataAddress1, - (void *)pC->ReaderAudioAU1.m_dataAddress, - pC->ReaderAudioAU1.m_size); - } - - if( pC->ReaderAudioAU2.m_structSize == 0 ) - { - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU2); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", - err); - return err; - } - pC->m_pDataAddress2 = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU2.m_maxsize, - M4MCS, (M4OSA_Char *)"Temporary AU buffer"); - - if( pC->m_pDataAddress2 == M4OSA_NULL ) - { - M4OSA_TRACE1_0( - "M4MCS_intAudioNullEncoding(): allocation error"); - return M4ERR_ALLOC; - } - } - /** - * Read the next audio AU in the input file */ - if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS ) - { - memcpy((void *) &pC->ReaderAudioAU, - (void *) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit)); - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU1); - - if( pC->ReaderAudioAU1.m_maxsize - > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize); - /* pC->m_pDataAddress1 - * and pC->m_pDataAddress2 must be reallocated at the same time * - * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take - * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > - * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true * - * and the size of the second buffer is never changed. - */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); - /* pC->m_pDataAddress1 and - * pC->m_pDataAddress2 must be reallocated at the same time - * Update stream properties - */ - pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = - pC->ReaderAudioAU1.m_maxsize; - } - /**/ - memcpy((void *)pC->m_pDataAddress1, - (void *)pC->ReaderAudioAU1.m_dataAddress, - pC->ReaderAudioAU1.m_size); - pC->m_audioAUDuration = - pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS; - pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2; - } - else - { - memcpy((void *) &pC->ReaderAudioAU, - (void *) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit)); - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, - &pC->ReaderAudioAU2); - /* Crash in MCS while Audio AU copying , - * constant memory reader case - */ - if( pC->ReaderAudioAU2.m_maxsize - > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize); - /* pC->m_pDataAddress1 and - * pC->m_pDataAddress2 must be reallocated at the same time - * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum - * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream-> - * m_basicProperties.m_maxAUSize)" is never true - * and the size of the second buffer is never changed. - */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize); - /* [ END ] 20091008 JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and - pC->m_pDataAddress2 must be reallocated at the same time */ - /* Update stream properties */ - pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = - pC->ReaderAudioAU2.m_maxsize; - } - /**/ - memcpy((void *)pC->m_pDataAddress2, - (void *)pC->ReaderAudioAU2.m_dataAddress, - pC->ReaderAudioAU2.m_size); - pC->m_audioAUDuration = - pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS; - pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1; - } - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE2_0( - "M4MCS_intAudioNullEncoding(): \ - m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); - /* The audio transcoding is finished */ - pC->AudioState = M4MCS_kStreamState_FINISHED; - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioNullEncoding(): \ - m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", - err); - return err; - } - } - - /** - * Prepare the writer AU */ - err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, - M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", - err); - return err; - } - - if( pC->uiAudioAUCount - == 0 ) /* If it is the first AU, we set it to silence - (else, errors 0x3841, 0x3847 in our AAC decoder) */ - { - if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC - || pC->InputFileProperties.AudioStreamType - == M4VIDEOEDITING_kAACplus - || pC->InputFileProperties.AudioStreamType - == M4VIDEOEDITING_keAACplus ) - { - if( pC->InputFileProperties.uiNbChannels == 1 ) - { - pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; - memcpy((void *)pC->WriterAudioAU.dataAddress, - (void *)M4VSS3GPP_AAC_AU_SILENCE_MONO, - pC->WriterAudioAU.size); - } - else if( pC->InputFileProperties.uiNbChannels == 2 ) - { - pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; - memcpy((void *)pC->WriterAudioAU.dataAddress, - (void *)M4VSS3GPP_AAC_AU_SILENCE_STEREO, - pC->WriterAudioAU.size); - } - else - { - /* Must never happen ...*/ - M4OSA_TRACE1_0( - "M4MCS_intAudioNullEncoding: Bad number of channels in audio input"); - return M4MCS_ERR_INVALID_INPUT_FILE; - } - } - else if( pC->InputFileProperties.AudioStreamType - == M4VIDEOEDITING_kAMR_NB ) - { - pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; - memcpy((void *)pC->WriterAudioAU.dataAddress, - (void *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048, - pC->WriterAudioAU.size); - /* Some remaining AMR AU needs to be copied */ - if( pC->ReaderAudioAU.m_size != 0 ) - { - /* Update Writer AU */ - pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size; - memcpy((void *)(pC->WriterAudioAU.dataAddress - + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE), - (void *)pC->ReaderAudioAU.m_dataAddress, - pC->ReaderAudioAU.m_size); - } - } - else - { - /*MP3 case: copy the AU*/ - M4OSA_TRACE3_1( - "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", - pC->ReaderAudioAU.m_size); - memcpy((void *)pC->WriterAudioAU.dataAddress, - (void *)pC->ReaderAudioAU.m_dataAddress, - pC->ReaderAudioAU.m_size); - pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; - } - } - else - { - /** - * Copy audio data from reader AU to writer AU */ - M4OSA_TRACE3_1( - "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", - pC->ReaderAudioAU.m_size); - memcpy((void *)pC->WriterAudioAU.dataAddress, - (void *)pC->ReaderAudioAU.m_dataAddress, - pC->ReaderAudioAU.m_size); - pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; - } - - /** - * Convert CTS unit from milliseconds to timescale */ - pC->WriterAudioAU.CTS = - (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset) - * (pC->WriterAudioStream.timeScale / 1000.0))); - - if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB - && pC->uiAudioAUCount == 0 ) - { - pC->iAudioCtsOffset -= - 20; /* Duration of a silence AMR AU, to handle the duration of the added - silence frame */ - } - pC->WriterAudioAU.nbFrag = 0; - M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms", - pC->WriterAudioAU.CTS); - - /** - * Write it to the output file */ - pC->uiAudioAUCount++; - err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, - M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", - err); - return err; - } - - /* All the audio has been written */ - pC->ReaderAudioAU.m_size = 0; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * @brief Init Audio Transcoding - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err; /**< General error */ - - M4OSA_UInt32 - uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */ - M4OSA_UInt32 - uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */ - - int ssrcErr; /**< Error while ssrc processing */ - M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */ - M4OSA_UInt32 - uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */ - M4OSA_MemAddr8 - pSsrcInput; /**< Pointer to the good buffer location for ssrc input */ - M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */ - M4OSA_UInt32 - uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */ - - M4OSA_UInt8 - needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */ - M4OSA_UInt32 - uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo - <-> mono conversion is applied */ - M4OSA_MemAddr8 pChannelConvertorInput = - M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */ - M4OSA_UInt32 uiChannelConvertorNbSamples = - 0; /**< Nb of pcm samples to convert in channel convertor */ - M4OSA_MemAddr8 pChannelConvertorOutput = - M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */ - - M4OSA_Time - frameTimeDelta; /**< Duration of the encoded (then written) data */ - M4OSA_UInt32 - uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */ - M4OSA_UInt32 - uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */ - M4OSA_MemAddr8 - pEncoderInput; /**< Pointer to the good buffer location for encoder input */ - M4ENCODER_AudioBuffer pEncInBuffer; /**< Encoder input buffer for api */ - M4ENCODER_AudioBuffer pEncOutBuffer; /**< Encoder output buffer for api */ - - M4OSA_Int16 *tempBuffOut = M4OSA_NULL; - /*FlB 2009.03.04: apply audio effects if an effect is active*/ - M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber); - - uint32_t errCode = M4NO_ERROR; - - if( pC->noaudio ) - return M4NO_ERROR; - - /* _________________ */ - /*| |*/ - /*| READ AND DECODE |*/ - /*|_________________|*/ - - /* Check if we have to empty the decoder out buffer first */ - if( M4OSA_NULL != pC->pPosInDecBufferOut ) - { - goto m4mcs_intaudiotranscoding_feed_resampler; - } - - err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, - M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE); - - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x", - err); - return err; - } - -#ifdef MCS_DUMP_PCM_TO_FILE - - fwrite(pC->AudioDecBufferOut.m_dataAddress, - pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder); - -#endif - - pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode); - - if ( M4WAR_NO_MORE_AU == errCode ) { - pC->AudioState = M4MCS_kStreamState_FINISHED; - M4OSA_TRACE2_0( - "M4MCS_intAudioTranscoding():\ - m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); - return errCode; - } - - /* Set the current position in the decoder out buffer */ - pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress; - - /* ________________ */ - /*| |*/ - /*| FEED RESAMPLER |*/ - /*|________________|*/ - -m4mcs_intaudiotranscoding_feed_resampler: - - /* Check if we have to empty the ssrc out buffer first */ - if( M4OSA_NULL != pC->pPosInSsrcBufferOut ) - { - goto m4mcs_intaudiotranscoding_prepare_input_buffer; - } - - /* Compute number of bytes remaining in the decoder buffer */ - uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short) - * pC->pReaderAudioStream->m_nbChannels; - uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress - + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut; - - /* Check if we can feed directly the Ssrc with the decoder out buffer */ - if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn) - && (uiBytesDec >= uiSsrcInSize) ) - { - pSsrcInput = pC->pPosInDecBufferOut; - - /* update data consumed into decoder buffer after resampling */ - if( uiBytesDec == uiSsrcInSize ) - pC->pPosInDecBufferOut = M4OSA_NULL; - else - pC->pPosInDecBufferOut += uiSsrcInSize; - - goto m4mcs_intaudiotranscoding_do_resampling; - } - - /** - * Compute remaining space in Ssrc buffer in */ - uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn; - - /** - * Nb of bytes copied is the minimum between nb of bytes remaining in - * decoder out buffer and space remaining in ssrc in buffer */ - uiDecoder2Ssrc_NbBytes = - (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec; - - /** - * Copy from the decoder out buffer into the Ssrc in buffer */ - memcpy((void *)pC->pPosInSsrcBufferIn, (void *)pC->pPosInDecBufferOut, - uiDecoder2Ssrc_NbBytes); - - /** - * Update the position in the decoder out buffer */ - pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes; - - /** - * Update the position in the Ssrc in buffer */ - pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes; - - /** - * Check if the decoder buffer out is empty */ - if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress) - == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize ) - { - pC->pPosInDecBufferOut = M4OSA_NULL; - } - - /* Check if the Ssrc in buffer is ready (= full) */ - if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn) - < (M4OSA_Int32)uiSsrcInSize ) - { - goto m4mcs_intaudiotranscoding_end; - } - - pSsrcInput = pC->pSsrcBufferIn; - - /* update data consumed into ssrc buffer in after resampling (empty) */ - pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn; - - /* ___________________ */ - /*| |*/ - /*| DO THE RESAMPLING |*/ - /*|___________________|*/ - -m4mcs_intaudiotranscoding_do_resampling: - - /** - * No need for memcopy, we can feed Ssrc directly with the data in the audio - decoder out buffer*/ - - ssrcErr = 0; - - if( pC->pReaderAudioStream->m_nbChannels == 1 ) - { - tempBuffOut = - (short *)M4OSA_32bitAlignedMalloc((pC->iSsrcNbSamplOut * sizeof(short) * 2 - * ((*pC).InputFileProperties).uiNbChannels), - M4VSS3GPP,(M4OSA_Char *) "tempBuffOut"); - memset((void *)tempBuffOut, 0,(pC->iSsrcNbSamplOut * sizeof(short) * 2 - * ((*pC).InputFileProperties).uiNbChannels)); - - LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput, - pC->iSsrcNbSamplOut, pC->pLVAudioResampler); - } - else - { - memset((void *)pC->pSsrcBufferOut, 0, (pC->iSsrcNbSamplOut * sizeof(short) - * ((*pC).InputFileProperties).uiNbChannels)); - - LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut, - (short *)pSsrcInput, pC->iSsrcNbSamplOut, pC->pLVAudioResampler); - } - - if( pC->pReaderAudioStream->m_nbChannels == 1 ) - { - From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut, - (short)pC->iSsrcNbSamplOut); - free(tempBuffOut); - } - - - if( 0 != ssrcErr ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \ - returning M4MCS_ERR_AUDIO_CONVERSION_FAILED", - ssrcErr); - return M4MCS_ERR_AUDIO_CONVERSION_FAILED; - } - - pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut; - - /* ______________________ */ - /*| |*/ - /*| PREPARE INPUT BUFFER |*/ - /*|______________________|*/ - -m4mcs_intaudiotranscoding_prepare_input_buffer: - - /* Set the flag for channel conversion requirement */ - if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) - && (pC->pReaderAudioStream->m_nbChannels == 2) ) - { - needChannelConversion = 1; - uiChannelConvertorCoeff = 4; - } - else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo) - && (pC->pReaderAudioStream->m_nbChannels == 1) ) - { - needChannelConversion = 2; - uiChannelConvertorCoeff = 1; - } - else - { - needChannelConversion = 0; - uiChannelConvertorCoeff = 2; - } - - /* Compute number of bytes remaining in the Ssrc buffer */ - uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short) - * pC->pReaderAudioStream->m_nbChannels; - uiBytesSsrc = - ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut; - - /* Check if the ssrc buffer is full */ - if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut ) - { - uiSsrc2Encoder_NbBytes = - pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2; - - /* Check if we can feed directly the encoder with the ssrc out buffer */ - if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL) - && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) ) - { - /* update position in ssrc out buffer after encoding */ - if( uiBytesSsrc == uiSsrc2Encoder_NbBytes ) - pC->pPosInSsrcBufferOut = M4OSA_NULL; - else - pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; - - /* mark the encoder buffer ready (= full) */ - pC->pPosInAudioEncoderBuffer = - pC->pAudioEncoderBuffer + pC->audioEncoderGranularity; - - if( needChannelConversion > 0 ) - { - /* channel convertor writes directly into encoder buffer */ - pEncoderInput = pC->pAudioEncoderBuffer; - - pChannelConvertorInput = pC->pSsrcBufferOut; - pChannelConvertorOutput = pC->pAudioEncoderBuffer; - uiChannelConvertorNbSamples = - uiSsrc2Encoder_NbBytes / sizeof(short); - - goto m4mcs_intaudiotranscoding_channel_convertor; - } - else - { - /* encode directly from ssrc out buffer */ - pEncoderInput = pC->pSsrcBufferOut; - - goto m4mcs_intaudiotranscoding_encode_and_write; - } - } - } - - /** - * Compute remaining space in encoder buffer in */ - if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL ) - { - pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer; - } - - uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity) - - pC->pPosInAudioEncoderBuffer; - pEncoderInput = pC->pAudioEncoderBuffer; - - /** - * Nb of bytes copied is the minimum between nb of bytes remaining in - * decoder out buffer and space remaining in ssrc in buffer */ - uiSsrc2Encoder_NbBytes = - (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc) - ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc; - - if( needChannelConversion > 0 ) - { - /* channel convertor writes directly into encoder buffer */ - pChannelConvertorInput = pC->pPosInSsrcBufferOut; - pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer; - uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short); - } - else - { - /* copy from the ssrc out buffer into the encoder in buffer */ - memcpy((void *)pC->pPosInAudioEncoderBuffer, (void *)pC->pPosInSsrcBufferOut, - uiSsrc2Encoder_NbBytes); - } - - /* Update position in ssrc out buffer after encoding */ - pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; - - /* Update the position in the encoder in buffer */ - pC->pPosInAudioEncoderBuffer += - uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff; - - /* Check if the ssrc buffer out is empty */ - if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut) - == (M4OSA_Int32)uiSsrcOutSize ) - { - pC->pPosInSsrcBufferOut = M4OSA_NULL; - } - - /* go to next statement */ - if( needChannelConversion > 0 ) - goto m4mcs_intaudiotranscoding_channel_convertor; - else - goto m4mcs_intaudiotranscoding_encode_and_write; - - /* _________________ */ - /*| |*/ - /*| STEREO <-> MONO |*/ - /*|_________________|*/ - -m4mcs_intaudiotranscoding_channel_convertor: - - /* convert the input pcm stream to mono or to stereo */ - switch( needChannelConversion ) - { - case 1: /* stereo to mono */ - From2iToMono_16((short *)pChannelConvertorInput, - (short *)pChannelConvertorOutput, - (short)(uiChannelConvertorNbSamples / 2)); - break; - - case 2: /* mono to stereo */ - MonoTo2I_16((short *)pChannelConvertorInput, - (short *)pChannelConvertorOutput, - (short)uiChannelConvertorNbSamples); - break; - } - - /* __________________ */ - /*| |*/ - /*| ENCODE AND WRITE |*/ - /*|__________________|*/ - -m4mcs_intaudiotranscoding_encode_and_write: - - /* Check if the encoder in buffer is ready (= full) */ - if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer) - < (M4OSA_Int32)pC->audioEncoderGranularity ) - { - goto m4mcs_intaudiotranscoding_end; - } - - /* [Mono] or [Stereo interleaved] : all is in one buffer */ - pEncInBuffer.pTableBuffer[0] = pEncoderInput; - pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity; - pEncInBuffer.pTableBuffer[1] = M4OSA_NULL; - pEncInBuffer.pTableBufferSize[1] = 0; - - /* Time in ms from data size, because it is PCM16 samples */ - frameTimeDelta = - ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2) - / sizeof(short) / pC->pReaderAudioStream->m_nbChannels; - - /** - * Prepare the writer AU */ - err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, - M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", - err); - return err; - } - - /*FlB 2009.03.04: apply audio effects if an effect is active*/ - if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects ) - { - if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL ) - { - M4MCS_ExternalProgress pProgress; - M4OSA_UInt32 tempProgress = 0; - pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS; - - pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000) - / pC->WriterAudioStream.timeScale; - tempProgress = ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS - - pC->pEffects[*pActiveEffectNumber].uiStartTime - - pC->uiBeginCutTime) * 1000; - pProgress.uiProgress = - (M4OSA_UInt32)(tempProgress / (M4OSA_UInt32)pC->pEffects[ - *pActiveEffectNumber].uiDuration); - - err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct( - pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt, - (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0], - pEncInBuffer.pTableBufferSize[0], &pProgress); - - if( err != M4NO_ERROR ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x", - err); - return err; - } - } - } - - /** - * Prepare output buffer */ - pEncOutBuffer.pTableBuffer[0] = - (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress; - pEncOutBuffer.pTableBufferSize[0] = 0; - -#ifdef MCS_DUMP_PCM_TO_FILE - - fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1, - file_pcm_encoder); - -#endif - - if( M4OSA_FALSE == pC->b_isRawWriter ) - { - /* This allow to write PCM data to file and to encode AMR data, - when output file is not RAW */ - if( pC->pOutputPCMfile != M4OSA_NULL ) - { - pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile, - pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]); - } - - /** - * Encode the PCM audio */ - err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt, - &pEncInBuffer, &pEncOutBuffer); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x", - err); - return err; - } - - /* update data consumed into encoder buffer in after encoding (empty) */ - pC->pPosInAudioEncoderBuffer = M4OSA_NULL; - - /** - * Set AU cts and size */ - pC->WriterAudioAU.size = - pEncOutBuffer. - pTableBufferSize[0]; /**< Get the size of encoded data */ - pC->WriterAudioAU.CTS += frameTimeDelta; - - /** - * Update duration of the encoded AU */ - pC->m_audioAUDuration = - ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale; - - /** - * Write the encoded AU to the output file */ - pC->uiAudioAUCount++; - err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, - M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", - err); - return err; - } - } - else - { - /* update data consumed into encoder buffer in after encoding (empty) */ - pC->pPosInAudioEncoderBuffer = M4OSA_NULL; - - pC->WriterAudioAU.dataAddress = - (M4OSA_MemAddr32) - pEncoderInput; /* will be converted back to u8* in file write */ - pC->WriterAudioAU.size = pC->audioEncoderGranularity; - pC->uiAudioAUCount++; - - err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, - M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", - err); - return err; - } - } - - /* _______________ */ - /*| |*/ - /*| ONE PASS DONE |*/ - /*|_______________|*/ - -m4mcs_intaudiotranscoding_end: - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize) - * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU - * because max AU size can be reevaluated during reading - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr, - M4OSA_UInt32 newSize ) -{ - if( *addr != M4OSA_NULL ) - { - free(*addr); - *addr = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(newSize, M4MCS, - (M4OSA_Char *)"Reallocation of temporary AU buffer"); - - if( *addr == M4OSA_NULL ) - { - return M4ERR_ALLOC; - } - } - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC) - * @author Alexis Vapillon (NXP Software Vision) - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err = M4NO_ERROR; - /* Duration of the AU (find the next AU duration - * to obtain a more precise video end cut) - */ - M4OSA_UInt32 videoAUDuration = 0; - - M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL; - M4OSA_Int32 lastdecodedCTS = 0; - M4_AccessUnit lReaderVideoAU; /**< Read video access unit */ - - if( pC->novideo ) - return M4NO_ERROR; - - /* H.264 Trimming */ - if( ( ( pC->bH264Trim == M4OSA_TRUE) - && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames) - && (pC->uiBeginCutTime > 0)) - || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) ) - { - err = M4MCS_intVideoTranscoding(pC); - return err; - } - - - if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0)) - { - // StageFright encoder does prefetch, the one frame we requested will not be written until - // the encoder is closed, so do it now rather than in MCS_close - if( ( M4NO_ERROR != err) - || (M4MCS_kEncoderRunning != pC->encoderState) ) - { - M4OSA_TRACE1_2( - "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding " - "returns 0x%X w/ encState=%d", err, pC->encoderState); - - return err; - } - - /* Stop and close the encoder now to flush the frame (prefetch) */ - if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL ) - { - err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X", - err); - return err; - } - } - pC->encoderState = M4MCS_kEncoderStopped; - err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X", - err); - return err; - } - pC->encoderState = M4MCS_kEncoderClosed; - } - - - if ((pC->EncodingVideoFormat == M4ENCODER_kNULL) - && (pC->bLastDecodedFrameCTS == M4OSA_FALSE) - && (pC->uiBeginCutTime > 0)) { - - pC->bLastDecodedFrameCTS = M4OSA_TRUE; - err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt, - M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS); - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!", - err); - return err; - } - /* Do not need video decoder any more, need to destroy it. Otherwise it - * will call reader function which will cause frame lost during triming, - * since the 3gp reader is shared between MCS and decoder.*/ - if (M4OSA_NULL != pC->pViDecCtxt) { - err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); - pC->pViDecCtxt = M4OSA_NULL; - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding: decoder pFctDestroy returns 0x%x", - err); - return err; - } - } - - err = pC->m_pReader->m_pFctJump(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS); - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding: m_pFctJump(V) returns 0x%x!", - err); - return err; - } - - - /* Initializes an access Unit */ - - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding:m_pReader->m_pFctFillAuStruct(video)\ - returns 0x%x", err); - return err; - } - - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); - - if (M4WAR_NO_MORE_AU == err) { - M4OSA_TRACE2_0( - "M4MCS_intVideoNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); - /* The audio transcoding is finished */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - return err; - } - else if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", - err); - return err; - } - - M4OSA_TRACE1_1( - "### [TS_CHECK] M4MCS_intVideoNullEncoding video AU CTS: %d ", - lReaderVideoAU.m_CTS); - - - } - - - pC->bLastDecodedFrameCTS = M4OSA_TRUE; - - - /* Find the next AU duration to obtain a more precise video end cut*/ - /** - * Initializes a new AU if needed */ - - if (pC->ReaderVideoAU1.m_structSize == 0) { - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU1); - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1( - "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", - err); - return err; - } - - pC->m_pDataVideoAddress1 = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU1.m_maxsize, M4MCS, - (M4OSA_Char *)"Temporary video AU1 buffer"); - - if (pC->m_pDataVideoAddress1 == M4OSA_NULL) { - M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); - return M4ERR_ALLOC; - } - - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU1); - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE2_0( - "M4MCS_intVideoNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); - /* The audio transcoding is finished */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\ - returns 0x%x", err); - return err; - } - - if( pC->ReaderVideoAU1.m_maxsize - > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); - /* pC->m_pDataVideoAddress1 - and pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. - Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> - m_basicProperties.m_maxAUSize)" is never true */ - /* and the size of the second buffer is never changed. */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); - /* pC->m_pDataVideoAddress1 and - pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* Update stream properties */ - pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = - pC->ReaderVideoAU1.m_maxsize; - } - memcpy((void *)pC->m_pDataVideoAddress1, - (void *)pC->ReaderVideoAU1.m_dataAddress, - pC->ReaderVideoAU1.m_size); - } - - if( pC->ReaderVideoAU2.m_structSize == 0 ) - { - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU2); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", - err); - return err; - } - pC->m_pDataVideoAddress2 = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU2.m_maxsize, M4MCS, - (M4OSA_Char *)"Temporary video AU buffer"); - - if( pC->m_pDataVideoAddress2 == M4OSA_NULL ) - { - M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); - return M4ERR_ALLOC; - } - } - /** - * Read the next video AU in the input file */ - if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS ) - { - memcpy((void *) &pC->ReaderVideoAU, - (void *) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit)); - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU1); - - if( pC->ReaderVideoAU1.m_maxsize - > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); - /* pC->m_pDataVideoAddress1 and - pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. - Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> - m_basicProperties.m_maxAUSize)" is never true */ - /* and the size of the second buffer is never changed. */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); - /* pC->m_pDataVideoAddress1 and - pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* Update stream properties */ - pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = - pC->ReaderVideoAU1.m_maxsize; - } - memcpy((void *)pC->m_pDataVideoAddress1, - (void *)pC->ReaderVideoAU1.m_dataAddress, - pC->ReaderVideoAU1.m_size); - videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS; - pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2; - } - else - { - memcpy((void *) &pC->ReaderVideoAU, - (void *) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit)); - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderVideoStream, - &pC->ReaderVideoAU2); - - if( pC->ReaderVideoAU2.m_maxsize - > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) - { - /* Constant memory reader case, we need to reallocate the temporary buffers */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize); - /* pC->m_pDataVideoAddress1 and - pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. - Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> - m_basicProperties.m_maxAUSize)" is never true */ - /* and the size of the second buffer is never changed. */ - M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 - *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize); - /* pC->m_pDataVideoAddress1 and - pC->m_pDataVideoAddress2 must be reallocated at the same time */ - /* Update stream properties */ - pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = - pC->ReaderVideoAU2.m_maxsize; - } - memcpy((void *)pC->m_pDataVideoAddress2, - (void *)pC->ReaderVideoAU2.m_dataAddress, - pC->ReaderVideoAU2.m_size); - videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS; - pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1; - } - - if( M4WAR_NO_MORE_AU == err ) - { - M4OSA_TRACE2_0( - "M4MCS_intVideoNullEncoding():\ - m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); - /* The video transcoding is finished */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x", - err); - return err; - } - else - { - /** - * Prepare the writer AU */ - err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, - M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x", - err); - return err; - } - /** - * Copy video data from reader AU to writer AU */ - M4OSA_TRACE3_1( - "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d", - pC->ReaderVideoAU.m_size); - /* + CRLV6775 -H.264 Trimming */ - if( M4OSA_TRUE == pC->bH264Trim ) - { - if( pC->H264MCSTempBufferSize - < (pC->ReaderVideoAU.m_size + 2048) ) - { - pC->H264MCSTempBufferSize = - (pC->ReaderVideoAU.m_size + 2048); - - if( pC->H264MCSTempBuffer != M4OSA_NULL ) - { - free(pC->H264MCSTempBuffer); - } - pC->H264MCSTempBuffer = - (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->H264MCSTempBufferSize, - M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer"); - - if( pC->H264MCSTempBuffer == M4OSA_NULL ) - { - M4OSA_TRACE1_0( - "M4MCS_intVideoNullEncoding(): allocation error"); - return M4ERR_ALLOC; - } - } - - pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize; - - err = H264MCS_ProcessNALU(pC->m_pInstance, - (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress, - pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer, - (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize); - - if( pC->m_pInstance->is_done == 1 ) - { - M4MCS_convetFromByteStreamtoNALStream( - (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress , - pC->ReaderVideoAU.m_size); - - memcpy((void *)pC->WriterVideoAU.dataAddress, - (void *)(pC->ReaderVideoAU.m_dataAddress + 4), - pC->ReaderVideoAU.m_size - 4); - pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4; - WritebufferAdd = - (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; - } - else - { - memcpy((void *)pC->WriterVideoAU.dataAddress, - (void *)(pC->H264MCSTempBuffer + 4), - pC->H264MCSTempBufferDataSize - 4); - pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4; - WritebufferAdd = - (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; - } - } - /* H.264 Trimming */ - else - { - memcpy((void *)pC->WriterVideoAU.dataAddress, - (void *)pC->ReaderVideoAU.m_dataAddress, - pC->ReaderVideoAU.m_size); - pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size; - } - /** - * Convert CTS unit from milliseconds to timescale */ - pC->WriterVideoAU.CTS = - (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts) - * (pC->WriterVideoStream.timeScale / 1000.0))); - pC->WriterVideoAU.nbFrag = 0; - pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute; - - M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms", - pC->WriterVideoAU.CTS); - - /** - * Write it to the output file */ - pC->uiVideoAUCount++; - err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, - M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x", - err); - return err; - } - /* + CRLV6775 -H.264 Trimming */ - if( M4OSA_TRUE == pC->bH264Trim ) - { - if( pC->m_pInstance->is_done == 1 ) - { - memcpy((void *)(WritebufferAdd - 4), - (void *)(pC->ReaderVideoAU.m_dataAddress), 4); - } - else - { - memcpy((void *)(WritebufferAdd - 4), - (void *)(pC->H264MCSTempBuffer), 4); - } - } /* H.264 Trimming */ - } - /** - * Check for end cut. */ - /* Bug fix 11/12/2008: We absolutely want to have less or same video duration -> - (2*videoAUDuration) to have a more precise end cut*/ - if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime ) - { - pC->VideoState = M4MCS_kStreamState_FINISHED; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC) - * @author Alexis Vapillon (NXP Software Vision) - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err = M4NO_ERROR; - M4_MediaTime mtTranscodedTime = 0.0; - M4ENCODER_FrameMode FrameMode; - M4OSA_Int32 derive = 0; - - /** - * Get video CTS to decode */ - mtTranscodedTime = pC->dViDecCurrentCts; - FrameMode = M4ENCODER_kNormalFrame; - - /** - * Decode video */ - M4OSA_TRACE3_1( - "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)", - mtTranscodedTime); - pC->isRenderDup = M4OSA_FALSE; - err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime, - M4OSA_FALSE, 0); - - if( M4WAR_NO_MORE_AU == err ) - { - FrameMode = - M4ENCODER_kLastFrame; /**< We will give this value to the encoder to - ask for the end of the encoding */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - } - else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) - { - M4OSA_TRACE2_0("Decoding output the same frame as before 3"); - pC->isRenderDup = M4OSA_TRUE; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!", - err); - return err; - } - - /** - * Check for end cut. - * We must check here if the end cut is reached, because in that case we must - * call the last encode step (-> bLastFrame set to true) */ - if( ( pC->dViDecCurrentCts + pC->dCtsIncrement ) >= (pC->uiEndCutTime - + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) ) - { - FrameMode = - M4ENCODER_kLastFrame; /**< We will give this value to the encoder to - ask for the end of the encoding */ - pC->VideoState = M4MCS_kStreamState_FINISHED; - derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5) - - (pC->uiEndCutTime - + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime))); - } - - /* Update starting CTS to have a more precise value ( - the begin cut is not a real CTS)*/ - if( pC->uiVideoAUCount == 0 ) - { - pC->dViDecStartingCts = mtTranscodedTime; - pC->dViDecCurrentCts = pC->dViDecStartingCts; - } - - /** - * Encode video */ - M4OSA_TRACE3_1( - "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\ - = %.2f",pC->ReaderVideoAU.m_CTS); - pC->uiVideoAUCount++; - /* update the given duration (the begin cut is not a real CTS)*/ - err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL, - (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)), - FrameMode); - - return err; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext) - * @author Dounya Manai (NXP Software Vision) - * @brief Retrieve the properties of the audio and video streams from the input file. - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC ) -{ - M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo; - M4READER_3GP_H263Properties H263prop; - M4OSA_ERR err; - M4OSA_UInt32 videoBitrate; - M4DECODER_VideoSize videoSize; - M4_AACType iAacType = 0; - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER, - "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL"); - - /** - * Reset common characteristics */ - pC->InputFileProperties.bAnalysed = M4OSA_FALSE; - pC->InputFileProperties.FileType = 0; - pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR; - pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR; - pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION; - pC->InputFileProperties.uiClipDuration = 0; - - memset((void *) &pC->InputFileProperties.ftyp, - 0, sizeof(M4VIDEOEDITING_FtypBox)); - - /** - * Reset video characteristics */ - pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; - pC->InputFileProperties.uiClipVideoDuration = 0; - pC->InputFileProperties.uiVideoBitrate = 0; - pC->InputFileProperties.uiVideoMaxAuSize = 0; - pC->InputFileProperties.uiVideoWidth = 0; - pC->InputFileProperties.uiVideoHeight = 0; - pC->InputFileProperties.uiVideoTimeScale = 0; - pC->InputFileProperties.fAverageFrameRate = 0.0; - pC->InputFileProperties.uiVideoLevel = - M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; - pC->InputFileProperties.uiVideoProfile = - M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; - pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE; - pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE; - pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE; - - /** - * Reset audio characteristics */ - pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; - pC->InputFileProperties.uiClipAudioDuration = 0; - pC->InputFileProperties.uiAudioBitrate = 0; - pC->InputFileProperties.uiAudioMaxAuSize = 0; - pC->InputFileProperties.uiNbChannels = 0; - pC->InputFileProperties.uiSamplingFrequency = 0; - pC->InputFileProperties.uiExtendedSamplingFrequency = 0; - pC->InputFileProperties.uiDecodedPcmSize = 0; - - /* Reset compatibility chart (not used in MCS) */ - pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE; - pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE; - pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE; - pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; - - /** - * Video stream properties */ - if( M4OSA_NULL != pC->pReaderVideoStream ) - { - switch( pC->pReaderVideoStream->m_basicProperties.m_streamType ) - { - case M4DA_StreamTypeVideoMpeg4: - pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4; - break; - - case M4DA_StreamTypeVideoH263: - pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263; - break; - - case M4DA_StreamTypeVideoMpeg4Avc: - pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264; - break; - - case M4DA_StreamTypeUnknown: - default: - pC->InputFileProperties.VideoStreamType = - M4VIDEOEDITING_kUnsupportedVideo; - break; - } - - /* if bitrate not available retrieve an estimation of the overall bitrate */ - pC->InputFileProperties.uiVideoBitrate = - pC->pReaderVideoStream->m_basicProperties.m_averageBitRate; - - if( 0 == pC->InputFileProperties.uiVideoBitrate ) - { - pC->m_pReader->m_pFctGetOption(pC->pReaderContext, - M4READER_kOptionID_Bitrate, &videoBitrate); - - if( M4OSA_NULL != pC->pReaderAudioStream ) - { - /* we get the overall bitrate, substract the audio bitrate if any */ - videoBitrate -= - pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; - } - pC->InputFileProperties.uiVideoBitrate = videoBitrate; - } - - /** - * Retrieve the Profile & Level */ - if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType) - && (M4VIDEOEDITING_kH264 - != pC->InputFileProperties.VideoStreamType) ) - { - /* Use the DSI parsing function from the external video shell decoder. - See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the - same issue. */ - - err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream-> - m_basicProperties.m_pDecoderSpecificInfo, - pC->pReaderVideoStream-> - m_basicProperties.m_decoderSpecificInfoSize, - &DecConfInfo, &videoSize); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intGetInputClipProperties():\ - M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", - err); - return err; - } - - pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth; - pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight; - pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale; - pC->InputFileProperties.bMPEG4dataPartition = - DecConfInfo.bDataPartition; - pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC; - pC->InputFileProperties.bMPEG4resynchMarker = - DecConfInfo.uiUseOfResynchMarker; - - err = getMPEG4ProfileAndLevel(DecConfInfo.uiProfile, - &(pC->InputFileProperties.uiVideoProfile), - &(pC->InputFileProperties.uiVideoLevel)); - if ( M4NO_ERROR != err ) { - M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ - getMPEG4ProfileAndLevel returns 0x%08X", err); - return err; - } - } - else if( M4VIDEOEDITING_kH263 == - pC->InputFileProperties.VideoStreamType ) { - - err = getH263ProfileAndLevel(pC->pReaderVideoStream-> - m_basicProperties.m_pDecoderSpecificInfo, - pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize, - &(pC->InputFileProperties.uiVideoProfile), - &(pC->InputFileProperties.uiVideoLevel)); - if ( M4NO_ERROR != err ) { - M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ - getH263ProfileAndLevel returns 0x%08X", err); - return err; - } - /* For h263 set default timescale : 30000:1001 */ - pC->InputFileProperties.uiVideoTimeScale = 30000; - } - else if ( M4VIDEOEDITING_kH264 == - pC->InputFileProperties.VideoStreamType ) { - - pC->InputFileProperties.uiVideoTimeScale = 30000; - err = getAVCProfileAndLevel(pC->pReaderVideoStream-> - m_basicProperties.m_pDecoderSpecificInfo, - pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize, - &(pC->InputFileProperties.uiVideoProfile), - &(pC->InputFileProperties.uiVideoLevel)); - if ( M4NO_ERROR != err ) { - M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ - getAVCProfileAndLevel returns 0x%08X", err); - return err; - } - } - - /* Here because width x height is correct only after dsi parsing - (done in create decoder) */ - pC->InputFileProperties.uiVideoHeight = - pC->pReaderVideoStream->m_videoHeight; - pC->InputFileProperties.uiVideoWidth = - pC->pReaderVideoStream->m_videoWidth; - pC->InputFileProperties.uiClipVideoDuration = - (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration; - pC->InputFileProperties.fAverageFrameRate = - pC->pReaderVideoStream->m_averageFrameRate; - pC->InputFileProperties.uiVideoMaxAuSize = - pC->pReaderVideoStream->m_basicProperties.m_maxAUSize; - pC->InputFileProperties.videoRotationDegrees = - pC->pReaderVideoStream->videoRotationDegrees; - } - else - { - if( M4OSA_TRUE == pC->bUnsupportedVideoFound ) - { - pC->InputFileProperties.VideoStreamType = - M4VIDEOEDITING_kUnsupportedVideo; - } - else - { - pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; - } - } - - /** - * Audio stream properties */ - if( M4OSA_NULL != pC->pReaderAudioStream ) - { - switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) - { - case M4DA_StreamTypeAudioAmrNarrowBand: - pC->InputFileProperties.AudioStreamType = - M4VIDEOEDITING_kAMR_NB; - break; - - case M4DA_StreamTypeAudioAac: - pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC; - break; - - case M4DA_StreamTypeAudioMp3: - pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3; - break; - - case M4DA_StreamTypeAudioEvrc: - pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC; - break; - - case M4DA_StreamTypeUnknown: - default: - pC->InputFileProperties.AudioStreamType = - M4VIDEOEDITING_kUnsupportedAudio; - break; - } - - if( ( M4OSA_NULL != pC->m_pAudioDecoder) - && (M4OSA_NULL == pC->pAudioDecCtxt) ) - { - M4OSA_TRACE3_1( - "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x", - pC->m_pCurrentAudioDecoderUserData); - - if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) { - err = M4MCS_intCheckAndGetCodecProperties(pC); - } - else - { - err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( - &pC->pAudioDecCtxt, pC->pReaderAudioStream, - pC->m_pCurrentAudioDecoderUserData); - - if( M4NO_ERROR == err ) - { - /* AAC properties*/ - //get from Reader; temporary, till Audio decoder shell API available to - //get the AAC properties - pC->AacProperties.aNumChan = - pC->pReaderAudioStream->m_nbChannels; - pC->AacProperties.aSampFreq = - pC->pReaderAudioStream->m_samplingFrequency; - - err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec( - pC->pAudioDecCtxt, M4AD_kOptionID_StreamType, - (M4OSA_DataOption) &iAacType); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intGetInputClipProperties:\ - m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", - err); - iAacType = M4_kAAC; //set to default - err = M4NO_ERROR; - } - else - { - M4OSA_TRACE3_1( - "M4MCS_intGetInputClipProperties:\ - m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d", - iAacType); - } - - switch( iAacType ) - { - case M4_kAAC: - pC->AacProperties.aSBRPresent = 0; - pC->AacProperties.aPSPresent = 0; - break; - - case M4_kAACplus: - pC->AacProperties.aSBRPresent = 1; - pC->AacProperties.aPSPresent = 0; - pC->AacProperties.aExtensionSampFreq = - pC->pReaderAudioStream-> - m_samplingFrequency; //TODO - break; - - case M4_keAACplus: - pC->AacProperties.aSBRPresent = 1; - pC->AacProperties.aPSPresent = 1; - pC->AacProperties.aExtensionSampFreq = - pC->pReaderAudioStream-> - m_samplingFrequency; //TODO - break; - case M4_kUnknown: - break; - default: - break; - } - M4OSA_TRACE3_2( - "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d", - pC->AacProperties.aNumChan, - pC->AacProperties.aSampFreq); - } - } - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intGetInputClipProperties:\ - m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", - err); - return err; - } - } - - //EVRC - if( pC->pReaderAudioStream->m_basicProperties.m_streamType - == M4DA_StreamTypeAudioEvrc ) - { - /* decoder not implemented yet, provide some default values for the null encoding */ - pC->pReaderAudioStream->m_nbChannels = 1; - pC->pReaderAudioStream->m_samplingFrequency = 8000; - } - - /** - * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according - the GetProperties function */ - if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate ) - { - if( M4VIDEOEDITING_kAMR_NB - == pC->InputFileProperties.AudioStreamType ) - { - /** - * Better returning a guessed 12.2 kbps value than a sure-to-be-false - 0 kbps value! */ - pC->InputFileProperties.uiAudioBitrate = - M4VIDEOEDITING_k12_2_KBPS; - } - else if( M4VIDEOEDITING_kEVRC - == pC->InputFileProperties.AudioStreamType ) - { - /** - * Better returning a guessed 8.5 kbps value than a sure-to-be-false - 0 kbps value! */ - pC->InputFileProperties.uiAudioBitrate = - M4VIDEOEDITING_k9_2_KBPS; - } - else - { - M4OSA_UInt32 FileBitrate; - - /* Can happen also for aac, in this case we calculate an approximative */ - /* value from global bitrate and video bitrate */ - err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, - M4READER_kOptionID_Bitrate, - (M4OSA_DataOption) &FileBitrate); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x", - err); - return err; - } - pC->InputFileProperties.uiAudioBitrate = - FileBitrate - - pC-> - InputFileProperties. - uiVideoBitrate /* normally setted to 0, if no video */; - } - } - else - { - pC->InputFileProperties.uiAudioBitrate = - pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; - } - - pC->InputFileProperties.uiNbChannels = - pC->pReaderAudioStream->m_nbChannels; - pC->InputFileProperties.uiSamplingFrequency = - pC->pReaderAudioStream->m_samplingFrequency; - pC->InputFileProperties.uiClipAudioDuration = - (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration; - pC->InputFileProperties.uiAudioMaxAuSize = - pC->pReaderAudioStream->m_basicProperties.m_maxAUSize; - - /* Bug: with aac, value is 0 until decoder start() is called */ - pC->InputFileProperties.uiDecodedPcmSize = - pC->pReaderAudioStream->m_byteFrameLength - * pC->pReaderAudioStream->m_byteSampleSize - * pC->pReaderAudioStream->m_nbChannels; - - /* New aac properties */ - if( M4DA_StreamTypeAudioAac - == pC->pReaderAudioStream->m_basicProperties.m_streamType ) - { - pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan; - pC->InputFileProperties.uiSamplingFrequency = - pC->AacProperties.aSampFreq; - - if( pC->AacProperties.aSBRPresent ) - { - pC->InputFileProperties.AudioStreamType = - M4VIDEOEDITING_kAACplus; - pC->InputFileProperties.uiExtendedSamplingFrequency = - pC->AacProperties.aExtensionSampFreq; - } - - if( pC->AacProperties.aPSPresent ) - { - pC->InputFileProperties.AudioStreamType = - M4VIDEOEDITING_keAACplus; - } - } - } - else - { - if( M4OSA_TRUE == pC->bUnsupportedAudioFound ) - { - pC->InputFileProperties.AudioStreamType = - M4VIDEOEDITING_kUnsupportedAudio; - } - else - { - pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; - } - } - - /* Get 'ftyp' atom */ - err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, - M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp); - - /* Analysis is successful */ - if( pC->InputFileProperties.uiClipVideoDuration - > pC->InputFileProperties.uiClipAudioDuration ) - pC->InputFileProperties.uiClipDuration = - pC->InputFileProperties.uiClipVideoDuration; - else - pC->InputFileProperties.uiClipDuration = - pC->InputFileProperties.uiClipAudioDuration; - - pC->InputFileProperties.FileType = pC->InputFileType; - pC->InputFileProperties.bAnalysed = M4OSA_TRUE; - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame) - * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer - * @note - * @param pCpAudioFrame (IN) AMRNB frame - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame ) -{ - M4OSA_UInt32 frameSize = 0; - M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3; - - switch( frameType ) - { - case 0: - frameSize = 95; - break; /* 4750 bps */ - - case 1: - frameSize = 103; - break; /* 5150 bps */ - - case 2: - frameSize = 118; - break; /* 5900 bps */ - - case 3: - frameSize = 134; - break; /* 6700 bps */ - - case 4: - frameSize = 148; - break; /* 7400 bps */ - - case 5: - frameSize = 159; - break; /* 7950 bps */ - - case 6: - frameSize = 204; - break; /* 10200 bps */ - - case 7: - frameSize = 244; - break; /* 12000 bps */ - - case 8: - frameSize = 39; - break; /* SID (Silence) */ - - case 15: - frameSize = 0; - break; /* No data */ - - default: - M4OSA_TRACE3_0( - "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0."); - return 0; - } - - return (1 + (( frameSize + 7) / 8)); -} - -/** - ****************************************************************************** - * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame) - * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer - * @note - * 0 1 2 3 - * +-+-+-+-+ - * |fr type| RFC 3558 - * +-+-+-+-+ - * - * Frame Type: 4 bits - * The frame type indicates the type of the corresponding codec data - * frame in the RTP packet. - * - * For EVRC and SMV codecs, the frame type values and size of the - * associated codec data frame are described in the table below: - * - * Value Rate Total codec data frame size (in octets) - * --------------------------------------------------------- - * 0 Blank 0 (0 bit) - * 1 1/8 2 (16 bits) - * 2 1/4 5 (40 bits; not valid for EVRC) - * 3 1/2 10 (80 bits) - * 4 1 22 (171 bits; 5 padded at end with zeros) - * 5 Erasure 0 (SHOULD NOT be transmitted by sender) - * - * @param pCpAudioFrame (IN) EVRC frame - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) -{ - M4OSA_UInt32 frameSize = 0; - M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F; - - switch( frameType ) - { - case 0: - frameSize = 0; - break; /* blank */ - - case 1: - frameSize = 16; - break; /* 1/8 */ - - case 2: - frameSize = 40; - break; /* 1/4 */ - - case 3: - frameSize = 80; - break; /* 1/2 */ - - case 4: - frameSize = 171; - break; /* 1 */ - - case 5: - frameSize = 0; - break; /* erasure */ - - default: - M4OSA_TRACE3_0( - "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0."); - return 0; - } - - return (1 + (( frameSize + 7) / 8)); -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext) - * @brief Check if max file size is greater enough to encode a file with the - * current selected bitrates and duration. - * @param pContext (IN) MCS context - * @return M4NO_ERROR - * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext ) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); - - M4OSA_UInt32 duration; - M4OSA_UInt32 audiobitrate; - M4OSA_UInt32 videobitrate; - - /* free file size : OK */ - if( pC->uiMaxFileSize == 0 ) - return M4NO_ERROR; - - /* duration */ - if( pC->uiEndCutTime == 0 ) - { - duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime; - } - else - { - duration = pC->uiEndCutTime - pC->uiBeginCutTime; - } - - /* audio bitrate */ - if( pC->noaudio ) - { - audiobitrate = 0; - } - else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) - { - audiobitrate = pC->InputFileProperties.uiAudioBitrate; - } - else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate ) - { - switch( pC->AudioEncParams.Format ) - { - case M4ENCODER_kAMRNB: - audiobitrate = M4VIDEOEDITING_k12_2_KBPS; - break; - //EVRC - // case M4ENCODER_kEVRC: - // audiobitrate = M4VIDEOEDITING_k9_2_KBPS; - // break; - - default: /* AAC and MP3*/ - audiobitrate = - (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) - ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; - break; - } - } - else - { - audiobitrate = pC->uiAudioBitrate; - } - - /* video bitrate */ - if( pC->novideo ) - { - videobitrate = 0; - } - else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) - { - videobitrate = pC->InputFileProperties.uiVideoBitrate; - } - else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate ) - { - videobitrate = M4VIDEOEDITING_k16_KBPS; - } - else - { - videobitrate = pC->uiVideoBitrate; - } - - /* max file size */ - if( (M4OSA_UInt32)pC->uiMaxFileSize - < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO - * (audiobitrate + videobitrate) * (duration / 8000.0)) ) - return M4MCS_ERR_MAXFILESIZE_TOO_SMALL; - else - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode) - * @brief Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate - * @param freebitrate: unsigned int value - * @param mode: -1:previous,0:current,1:next - * @return bitrate value in enum list M4VIDEOEDITING_Bitrate - ****************************************************************************** - */ -static M4VIDEOEDITING_Bitrate -M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode ) -{ - M4OSA_Int32 bitarray [] = - { - 0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS, - M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS, - M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS, - M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS, - M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS, - M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS, - M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS, - M4VIDEOEDITING_k5_MBPS, - M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */ - M4OSA_INT32_MAX - }; - - const M4OSA_UInt32 nbbitrates = 14; - M4OSA_UInt32 i; - - for ( i = 0; freebitrate >= bitarray[i]; i++ ); - - switch( mode ) - { - case -1: /* previous */ - if( i <= 2 ) - return 0; - else - return bitarray[i - 2]; - break; - - case 0: /* current */ - if( i <= 1 ) - return 0; - else - return bitarray[i - 1]; - break; - - case 1: /* next */ - if( i >= nbbitrates ) - return M4OSA_INT32_MAX; - else - return bitarray[i]; - break; - } - - return 0; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC); - * @brief Free all resources allocated by M4MCS_open() - * @param pContext (IN) MCS context - * @return M4NO_ERROR: No error - ****************************************************************************** - */ -static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC ) -{ - M4OSA_ERR err = M4NO_ERROR; - - M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC); - - /**/ - /* ----- Free video decoder stuff, if needed ----- */ - - if( M4OSA_NULL != pC->pViDecCtxt ) - { - err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); - pC->pViDecCtxt = M4OSA_NULL; - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - } - - /* ----- Free the audio decoder stuff ----- */ - - if( M4OSA_NULL != pC->pAudioDecCtxt ) - { - err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt); - pC->pAudioDecCtxt = M4OSA_NULL; - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - } - - if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress ) - { - free(pC->AudioDecBufferOut.m_dataAddress); - pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; - } - - /* ----- Free reader stuff, if needed ----- */ - // We cannot free the reader before decoders because the decoders may read - // from the reader (in another thread) before being stopped. - - if( M4OSA_NULL != pC-> - pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */ - { - err = pC->m_pReader->m_pFctClose(pC->pReaderContext); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext); - pC->pReaderContext = M4OSA_NULL; - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err); - /**< don't return, we still have stuff to free */ - } - } - - if( pC->m_pDataAddress1 != M4OSA_NULL ) - { - free(pC->m_pDataAddress1); - pC->m_pDataAddress1 = M4OSA_NULL; - } - - if( pC->m_pDataAddress2 != M4OSA_NULL ) - { - free(pC->m_pDataAddress2); - pC->m_pDataAddress2 = M4OSA_NULL; - } - /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/ - if( pC->m_pDataVideoAddress1 != M4OSA_NULL ) - { - free(pC->m_pDataVideoAddress1); - pC->m_pDataVideoAddress1 = M4OSA_NULL; - } - - if( pC->m_pDataVideoAddress2 != M4OSA_NULL ) - { - free(pC->m_pDataVideoAddress2); - pC->m_pDataVideoAddress2 = M4OSA_NULL; - } - - return M4NO_ERROR; -} - - -/** - - ****************************************************************************** - * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, - * M4OSA_Void* pFileOut, M4OSA_Void* pTempFile); - * @brief Set the MCS input and output files. It is the same as M4MCS_open without - * M4MCS_WITH_FAST_OPEN flag -It is used in VideoArtist - * @note It opens the input file, but the output file is not created yet. - * @param pContext (IN) MCS context - * @param pFileIn (IN) Input file to transcode (The type of this parameter - * (URL, pipe...) depends on the OSAL implementation). - * @param mediaType (IN) Container type (.3gp,.amr, ...) of input file. - * @param pFileOut (IN) Output file to create (The type of this parameter - * (URL, pipe...) depends on the OSAL implementation). - * @param pTempFile (IN) Temporary file for the constant memory writer to store - * metadata ("moov.bin"). - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called - * @return M4ERR_ALLOC: There is no more available memory - * @return M4ERR_FILE_NOT_FOUND: The input file has not been found - * @return M4MCS_ERR_INVALID_INPUT_FILE: The input file is not a valid file, or is corrupted - * @return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM: The input file contains no - * supported audio or video stream - ****************************************************************************** - */ -M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, - M4VIDEOEDITING_FileType InputFileType, - M4OSA_Void* pFileOut, M4OSA_Void* pTempFile) -{ - M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext); - M4OSA_ERR err; - - M4READER_MediaFamily mediaFamily; - M4_StreamHandler* pStreamHandler; - - M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\ - pFileOut=0x%x", pContext, pFileIn, pFileOut); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4MCS_open_normalMode: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER, - "M4MCS_open_normalMode: pFileIn is M4OSA_NULL"); - - if ((InputFileType == M4VIDEOEDITING_kFileType_JPG) - ||(InputFileType == M4VIDEOEDITING_kFileType_PNG) - ||(InputFileType == M4VIDEOEDITING_kFileType_GIF) - ||(InputFileType == M4VIDEOEDITING_kFileType_BMP)) - { - M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\ - supported with this function"); - return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; - } - - /** - * Check state automaton */ - if (M4MCS_kState_CREATED != pC->State) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /* Copy function input parameters into our context */ - pC->pInputFile = pFileIn; - pC->InputFileType = InputFileType; - pC->pOutputFile = pFileOut; - pC->pTemporaryFile = pTempFile; - - /***********************************/ - /* Open input file with the reader */ - /***********************************/ - - err = M4MCS_setCurrentReader(pContext, pC->InputFileType); - M4ERR_CHECK_RETURN(err); - - /** - * Reset reader related variables */ - pC->VideoState = M4MCS_kStreamState_NOSTREAM; - pC->AudioState = M4MCS_kStreamState_NOSTREAM; - pC->pReaderVideoStream = M4OSA_NULL; - pC->pReaderAudioStream = M4OSA_NULL; - - /*******************************************************/ - /* Initializes the reader shell and open the data file */ - /*******************************************************/ - err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err); - return err; - } - - /** - * Link the reader interface to the reader context */ - pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext; - - /** - * Set the reader shell file access functions */ - err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, - M4READER_kOptionID_SetOsaFileReaderFctsPtr, - (M4OSA_DataOption)pC->pOsaFileReadPtr); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err); - return err; - } - - /** - * Open the input file */ - err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile); - if (M4NO_ERROR != err) - { - M4OSA_UInt32 uiDummy, uiCoreId; - M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err); - - if (err == ((M4OSA_UInt32)M4ERR_UNSUPPORTED_MEDIA_TYPE)) { - M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_FILE_DRM_PROTECTED"); - return M4MCS_ERR_FILE_DRM_PROTECTED; - } else { - /** - * If the error is from the core reader, we change it to a public VXS error */ - M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); - if (M4MP4_READER == uiCoreId) - { - M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE"); - return M4MCS_ERR_INVALID_INPUT_FILE; - } - } - return err; - } - - /** - * Get the streams from the input file */ - while (M4NO_ERROR == err) - { - err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily, - &pStreamHandler); - - /** - * In case we found a BIFS stream or something else...*/ - if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) - || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))) - { - err = M4NO_ERROR; - continue; - } - - if (M4NO_ERROR == err) /**< One stream found */ - { - /** - * Found the first video stream */ - if ((M4READER_kMediaFamilyVideo == mediaFamily) \ - && (M4OSA_NULL == pC->pReaderVideoStream)) - { - if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) || - (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType) -#ifdef M4VSS_SUPPORT_VIDEO_AVC - ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)) -#else - ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType) - &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL))) -#endif - { - M4OSA_TRACE3_0("M4MCS_open_normalMode():\ - Found a H263 or MPEG-4 video stream in input 3gpp clip"); - - /** - * Keep pointer to the video stream */ - pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler; - pC->bUnsupportedVideoFound = M4OSA_FALSE; - pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; - - /** - * Init our video stream state variable */ - pC->VideoState = M4MCS_kStreamState_STARTED; - - /** - * Reset the stream reader */ - err = pC->m_pReader->m_pFctReset(pC->pReaderContext, - (M4_StreamHandler*)pC->pReaderVideoStream); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode():\ - m_pReader->m_pFctReset(video) returns 0x%x", err); - return err; - } - - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, - &pC->ReaderVideoAU); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode():\ - m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err); - return err; - } - } - else /**< Not H263 or MPEG-4 (H264, etc.) */ - { - M4OSA_TRACE1_1("M4MCS_open_normalMode():\ - Found an unsupported video stream (0x%x) in input 3gpp clip", - pStreamHandler->m_streamType); - - pC->bUnsupportedVideoFound = M4OSA_TRUE; - pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; - } - } - /** - * Found the first audio stream */ - else if ((M4READER_kMediaFamilyAudio == mediaFamily) - && (M4OSA_NULL == pC->pReaderAudioStream)) - { - if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) || - (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) || - (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) || - (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) ) - { - M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \ - or MP3 audio stream in input clip"); - - /** - * Keep pointer to the audio stream */ - pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler; - pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; - pC->bUnsupportedAudioFound = M4OSA_FALSE; - - /** - * Init our audio stream state variable */ - pC->AudioState = M4MCS_kStreamState_STARTED; - - /** - * Reset the stream reader */ - err = pC->m_pReader->m_pFctReset(pC->pReaderContext, - (M4_StreamHandler*)pC->pReaderAudioStream); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode():\ - m_pReader->m_pFctReset(audio) returns 0x%x", err); - return err; - } - - /** - * Initializes an access Unit */ - err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, - &pC->ReaderAudioAU); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode(): \ - m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err); - return err; - } - - /** - * Output max AU size is equal to input max AU size (this value - * will be changed if there is audio transcoding) */ - pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize; - - } - else - { - /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */ - M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\ - (0x%x) in input 3gpp clip", pStreamHandler->m_streamType); - - pC->bUnsupportedAudioFound = M4OSA_TRUE; - pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; - } - } - } - } /**< end of while (M4NO_ERROR == err) */ - - /** - * Check we found at least one supported stream */ - if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream)) - { - M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \ - M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM"); - return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; - } - -#ifndef M4VSS_ENABLE_EXTERNAL_DECODERS - if(pC->VideoState == M4MCS_kStreamState_STARTED) - { - err = M4MCS_setCurrentVideoDecoder(pContext, - pC->pReaderVideoStream->m_basicProperties.m_streamType); - M4ERR_CHECK_RETURN(err); - } -#endif - - if(pC->AudioState == M4MCS_kStreamState_STARTED) - { - //EVRC - if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType) - /* decoder not supported yet, but allow to do null encoding */ - { - err = M4MCS_setCurrentAudioDecoder(pContext, - pC->pReaderAudioStream->m_basicProperties.m_streamType); - M4ERR_CHECK_RETURN(err); - } - } - - /** - * Get the audio and video stream properties */ - err = M4MCS_intGetInputClipProperties(pC); - if (M4NO_ERROR != err) - { - M4OSA_TRACE1_1("M4MCS_open_normalMode():\ - M4MCS_intGetInputClipProperties returns 0x%x", err); - return err; - } - - /** - * Set the begin cut decoding increment according to the input frame rate */ - if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */ - { - pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \ - / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */ - } - else - { - pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/ - } - - /** - * Update state automaton */ - pC->State = M4MCS_kState_OPENED; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -M4OSA_ERR M4MCS_intCheckAndGetCodecProperties( - M4MCS_InternalContext *pC) { - - M4OSA_ERR err = M4NO_ERROR; - M4AD_Buffer outputBuffer; - uint32_t optionValue =0; - - M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecProperties :start"); - - // Decode first audio frame from clip to get properties from codec - - if (M4DA_StreamTypeAudioAac == - pC->pReaderAudioStream->m_basicProperties.m_streamType) { - - err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( - &pC->pAudioDecCtxt, - pC->pReaderAudioStream, &(pC->AacProperties)); - } else { - err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( - &pC->pAudioDecCtxt, - pC->pReaderAudioStream, - pC->m_pCurrentAudioDecoderUserData); - } - if (M4NO_ERROR != err) { - - M4OSA_TRACE1_1( - "M4MCS_intCheckAndGetCodecProperties: m_pFctCreateAudioDec \ - returns 0x%x", err); - return err; - } - - pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); - - pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); - - if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { - - err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); - if( M4NO_ERROR != err ) { - - M4OSA_TRACE1_1( - "M4MCS_intCheckAndGetCodecProperties: m_pFctStartAudioDec \ - returns 0x%x", err); - return err; - } - } - - /** - * Allocate output buffer for the audio decoder */ - outputBuffer.m_bufferSize = - pC->pReaderAudioStream->m_byteFrameLength - * pC->pReaderAudioStream->m_byteSampleSize - * pC->pReaderAudioStream->m_nbChannels; - - if( outputBuffer.m_bufferSize > 0 ) { - - outputBuffer.m_dataAddress = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \ - *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize"); - - if( M4OSA_NULL == outputBuffer.m_dataAddress ) { - - M4OSA_TRACE1_0( - "M4MCS_intCheckAndGetCodecProperties():\ - unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - } - - err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, - M4OSA_NULL, &outputBuffer, M4OSA_FALSE); - - if ( err == M4WAR_INFO_FORMAT_CHANGE ) { - - // Get the properties from codec node - pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue); - - // Reset Reader structure value also - pC->pReaderAudioStream->m_nbChannels = optionValue; - - pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, - M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue); - - // Reset Reader structure value also - pC->pReaderAudioStream->m_samplingFrequency = optionValue; - - if (M4DA_StreamTypeAudioAac == - pC->pReaderAudioStream->m_basicProperties.m_streamType) { - - pC->AacProperties.aNumChan = - pC->pReaderAudioStream->m_nbChannels; - pC->AacProperties.aSampFreq = - pC->pReaderAudioStream->m_samplingFrequency; - - } - - } else if( err != M4NO_ERROR) { - M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties:\ - m_pFctStepAudioDec returns err = 0x%x", err); - } - - free(outputBuffer.m_dataAddress); - - // Reset the stream reader - err = pC->m_pReader->m_pFctReset(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream); - - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties\ - Error in reseting reader: 0x%x", err); - } - - return err; - -} - -M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel( - M4ENCODER_AdvancedParams* EncParams) { - - M4OSA_ERR err = M4NO_ERROR; - - switch (EncParams->Format) { - case M4ENCODER_kH263: - EncParams->Bitrate = M4MCS_intLimitBitrateForH263Enc( - EncParams->videoProfile, - EncParams->videoLevel, EncParams->Bitrate); - break; - - case M4ENCODER_kMPEG4: - EncParams->Bitrate = M4MCS_intLimitBitrateForMpeg4Enc( - EncParams->videoProfile, - EncParams->videoLevel, EncParams->Bitrate); - break; - - case M4ENCODER_kH264: - EncParams->Bitrate = M4MCS_intLimitBitrateForH264Enc( - EncParams->videoProfile, - EncParams->videoLevel, EncParams->Bitrate); - break; - - default: - M4OSA_TRACE1_1("M4MCS_intLimitBitratePerCodecProfileLevel: \ - Wrong enc format %d", EncParams->Format); - err = M4ERR_PARAMETER; - break; - } - - return err; - -} - -M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate) { - - M4OSA_Int32 vidBitrate = 0; - - switch (profile) { - case OMX_VIDEO_AVCProfileBaseline: - case OMX_VIDEO_AVCProfileMain: - - switch (level) { - - case OMX_VIDEO_AVCLevel1: - vidBitrate = (bitrate > 64000) ? 64000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel1b: - vidBitrate = (bitrate > 128000) ? 128000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel11: - vidBitrate = (bitrate > 192000) ? 192000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel12: - vidBitrate = (bitrate > 384000) ? 384000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel13: - vidBitrate = (bitrate > 768000) ? 768000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel2: - vidBitrate = (bitrate > 2000000) ? 2000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel21: - vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel22: - vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel3: - vidBitrate = (bitrate > 10000000) ? 10000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel31: - vidBitrate = (bitrate > 14000000) ? 14000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel32: - vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel4: - vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel41: - vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel42: - vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel5: - vidBitrate = (bitrate > 135000000) ? 135000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel51: - vidBitrate = (bitrate > 240000000) ? 240000000 : bitrate; - break; - - default: - vidBitrate = bitrate; - break; - } - break; - - case OMX_VIDEO_AVCProfileHigh: - switch (level) { - case OMX_VIDEO_AVCLevel1: - vidBitrate = (bitrate > 80000) ? 80000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel1b: - vidBitrate = (bitrate > 160000) ? 160000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel11: - vidBitrate = (bitrate > 240000) ? 240000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel12: - vidBitrate = (bitrate > 480000) ? 480000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel13: - vidBitrate = (bitrate > 960000) ? 960000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel2: - vidBitrate = (bitrate > 2500000) ? 2500000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel21: - vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel22: - vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel3: - vidBitrate = (bitrate > 12500000) ? 12500000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel31: - vidBitrate = (bitrate > 17500000) ? 17500000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel32: - vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel4: - vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel41: - vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel42: - vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel5: - vidBitrate = (bitrate > 168750000) ? 168750000 : bitrate; - break; - - case OMX_VIDEO_AVCLevel51: - vidBitrate = (bitrate > 300000000) ? 300000000 : bitrate; - break; - - default: - vidBitrate = bitrate; - break; - } - break; - - default: - // We do not handle any other AVC profile for now. - // Return input bitrate - vidBitrate = bitrate; - break; - } - - return vidBitrate; -} - -M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate) { - - M4OSA_Int32 vidBitrate = 0; - - switch (profile) { - case OMX_VIDEO_MPEG4ProfileSimple: - switch (level) { - - case OMX_VIDEO_MPEG4Level0: - vidBitrate = (bitrate > 64000) ? 64000 : bitrate; - break; - - case OMX_VIDEO_MPEG4Level0b: - vidBitrate = (bitrate > 128000) ? 128000 : bitrate; - break; - - case OMX_VIDEO_MPEG4Level1: - vidBitrate = (bitrate > 64000) ? 64000 : bitrate; - break; - - case OMX_VIDEO_MPEG4Level2: - vidBitrate = (bitrate > 128000) ? 128000 : bitrate; - break; - - case OMX_VIDEO_MPEG4Level3: - vidBitrate = (bitrate > 384000) ? 384000 : bitrate; - break; - - default: - vidBitrate = bitrate; - break; - } - break; - - default: - // We do not handle any other MPEG4 profile for now. - // Return input bitrate - vidBitrate = bitrate; - break; - } - - return vidBitrate; -} - -M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile, - M4OSA_Int32 level, M4OSA_Int32 bitrate) { - - M4OSA_Int32 vidBitrate = 0; - - switch (profile) { - case OMX_VIDEO_H263ProfileBaseline: - switch (level) { - - case OMX_VIDEO_H263Level10: - vidBitrate = (bitrate > 64000) ? 64000 : bitrate; - break; - - case OMX_VIDEO_H263Level20: - vidBitrate = (bitrate > 128000) ? 128000 : bitrate; - break; - - case OMX_VIDEO_H263Level30: - vidBitrate = (bitrate > 384000) ? 384000 : bitrate; - break; - - default: - vidBitrate = bitrate; - break; - } - break; - - default: - // We do not handle any other H263 profile for now. - // Return input bitrate - vidBitrate = bitrate; - break; - } - - return vidBitrate; -} |