M4MCS_API.c revision 8806b706693c0992724f6603353af18aeb4a0f80
1593a894650e81be54173106ec266f0311cebebd3Stephen Hines/*
29999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines * Copyright (C) 2011 The Android Open Source Project
3593a894650e81be54173106ec266f0311cebebd3Stephen Hines *
4593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5593a894650e81be54173106ec266f0311cebebd3Stephen Hines * you may not use this file except in compliance with the License.
6593a894650e81be54173106ec266f0311cebebd3Stephen Hines * You may obtain a copy of the License at
7593a894650e81be54173106ec266f0311cebebd3Stephen Hines *
8593a894650e81be54173106ec266f0311cebebd3Stephen Hines *      http://www.apache.org/licenses/LICENSE-2.0
9593a894650e81be54173106ec266f0311cebebd3Stephen Hines *
10593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Unless required by applicable law or agreed to in writing, software
11593a894650e81be54173106ec266f0311cebebd3Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12593a894650e81be54173106ec266f0311cebebd3Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13593a894650e81be54173106ec266f0311cebebd3Stephen Hines * See the License for the specific language governing permissions and
14593a894650e81be54173106ec266f0311cebebd3Stephen Hines * limitations under the License.
15593a894650e81be54173106ec266f0311cebebd3Stephen Hines */
16593a894650e81be54173106ec266f0311cebebd3Stephen Hines
17593a894650e81be54173106ec266f0311cebebd3Stephen Hines/**
18593a894650e81be54173106ec266f0311cebebd3Stephen Hines *************************************************************************
19593a894650e81be54173106ec266f0311cebebd3Stephen Hines * @file   M4MCS_API.c
20593a894650e81be54173106ec266f0311cebebd3Stephen Hines * @brief  MCS implementation (Video Compressor Service)
21593a894650e81be54173106ec266f0311cebebd3Stephen Hines * @note   This file implements the API and the processing of the MCS
22593a894650e81be54173106ec266f0311cebebd3Stephen Hines *************************************************************************
23b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines **/
24593a894650e81be54173106ec266f0311cebebd3Stephen Hines
25593a894650e81be54173106ec266f0311cebebd3Stephen Hines/**
26593a894650e81be54173106ec266f0311cebebd3Stephen Hines ********************************************************************
27593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Includes
28593a894650e81be54173106ec266f0311cebebd3Stephen Hines ********************************************************************
29593a894650e81be54173106ec266f0311cebebd3Stephen Hines */
30593a894650e81be54173106ec266f0311cebebd3Stephen Hines/**
3112580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines * OSAL headers */
32593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "M4OSA_Memory.h" /**< OSAL memory management */
33593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "M4OSA_Debug.h"  /**< OSAL debug management */
34593a894650e81be54173106ec266f0311cebebd3Stephen Hines
35b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines/* PCM samples */
36b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "VideoEditorResampler.h"
379207a2e495c8363606861e4f034504ec5c153dabLogan Chien/**
389207a2e495c8363606861e4f034504ec5c153dabLogan Chien * Decoder interface */
399207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "M4DECODER_Common.h"
409207a2e495c8363606861e4f034504ec5c153dabLogan Chien
419207a2e495c8363606861e4f034504ec5c153dabLogan Chien/* Encoder interface*/
429207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "M4ENCODER_common.h"
439207a2e495c8363606861e4f034504ec5c153dabLogan Chien
449207a2e495c8363606861e4f034504ec5c153dabLogan Chien/* Enable for DEBUG logging */
459207a2e495c8363606861e4f034504ec5c153dabLogan Chien//#define MCS_DUMP_PCM_TO_FILE
469207a2e495c8363606861e4f034504ec5c153dabLogan Chien#ifdef MCS_DUMP_PCM_TO_FILE
479207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include <stdio.h>
48b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen HinesFILE *file_au_reader = NULL;
49b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen HinesFILE *file_pcm_decoder = NULL;
50b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen HinesFILE *file_pcm_encoder = NULL;
51b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#endif
52b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
539ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines/* Core headers */
54b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "M4MCS_API.h"
55b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "M4MCS_ErrorCodes.h"
56b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "M4MCS_InternalTypes.h"
57b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "M4MCS_InternalConfig.h"
58b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "M4MCS_InternalFunctions.h"
59b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
60b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#ifdef M4MCS_SUPPORT_STILL_PICTURE
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "M4MCS_StillPicture.h"
62b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
63b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
64b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines/* Common headers (for aac) */
657b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#include "M4_Common.h"
667b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
677b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#include "NXPSW_CompilerSwitches.h"
687b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
697b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
707b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#include "M4VD_EXTERNAL_Interface.h"
717b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
727b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
737b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#include "M4AIR_API.h"
747b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
757b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines/* Version */
767b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#define M4MCS_VERSION_MAJOR 3
777b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#define M4MCS_VERSION_MINOR 4
787b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines#define M4MCS_VERSION_REVISION  3
799ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
809ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines/**
819ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines ********************************************************************
829ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines * Static local functions
839ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines ********************************************************************
849ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines */
859ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
869ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hinesstatic M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC );
879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hinesstatic M4OSA_ERR M4MCS_intPrepareVideoDecoder(
889ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                                    M4MCS_InternalContext *pC );
899ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hinesstatic M4OSA_ERR M4MCS_intPrepareVideoEncoder(
909ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                                    M4MCS_InternalContext *pC );
919ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hinesstatic M4OSA_ERR M4MCS_intPrepareAudioProcessing(
929207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    M4MCS_InternalContext *pC );
939207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC );
949207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic M4OSA_ERR M4MCS_intPrepareAudioBeginCut(
957b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines                                    M4MCS_InternalContext *pC );
967b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hinesstatic M4OSA_ERR M4MCS_intStepEncoding(
97b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                    M4MCS_InternalContext *pC,
98b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                    M4OSA_UInt8 *pTranscodedTime );
99b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesstatic M4OSA_ERR M4MCS_intStepBeginVideoJump(
100b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                    M4MCS_InternalContext *pC );
101b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesstatic M4OSA_ERR M4MCS_intStepBeginVideoDecode(
102b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                    M4MCS_InternalContext *pC );
1034ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC );
1044ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC );
1054ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC );
1064ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC );
1074ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intGetInputClipProperties(
1084ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4MCS_InternalContext   *pContext );
1094ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(
1104ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_MemAddr8 pAudioFrame );
1114ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(
1124ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_MemAddr8 pAudioFrame );
1134ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext );
1144ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(
1154ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_Int32 freebitrate,
1164ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_Int8 mode );
1174ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(
1184ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4MCS_InternalContext *pC );
1194ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intReallocTemporaryAU(
1204ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_MemAddr8 *addr,
1214ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                    M4OSA_UInt32 newSize );
1224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_ERR M4MCS_intCheckAndGetCodecAacProperties(
1234ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                 M4MCS_InternalContext *pC);
1249207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1259207a2e495c8363606861e4f034504ec5c153dabLogan Chien/**
1269207a2e495c8363606861e4f034504ec5c153dabLogan Chien **********************************************************************
1279207a2e495c8363606861e4f034504ec5c153dabLogan Chien * External function used only by VideoEditor and that does not appear
1287b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * in the API
1297b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines **********************************************************************
1304ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines */
1314ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1324ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen HinesM4OSA_ERR M4MCS_open_normalMode( M4MCS_Context pContext,
1334ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                 M4OSA_Void *pFileIn,
1344ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                 M4VIDEOEDITING_FileType InputFileType,
1354ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                 M4OSA_Void *pFileOut,
1364ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                                 M4OSA_Void *pTempFile );
1374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1384ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines/* All errors are fatal in the MCS */
1394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#define M4ERR_CHECK_RETURN(err) if(M4NO_ERROR!=err) return err;
1404ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines/* A define used with SSRC 1.04 and above to avoid taking blocks smaller
1424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines * that the minimal block size
1434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines */
1444ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#define M4MCS_SSRC_MINBLOCKSIZE        100
1454ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1464ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hinesstatic M4OSA_UChar Tab_MCS[8] =
1474ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines{
1489207a2e495c8363606861e4f034504ec5c153dabLogan Chien    17, 5, 3, 3, 1, 1, 1, 1
1499207a2e495c8363606861e4f034504ec5c153dabLogan Chien};
1509207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1519207a2e495c8363606861e4f034504ec5c153dabLogan ChienM4OSA_ERR H264MCS_Getinstance( NSWAVC_MCS_t ** instance )
1527b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines{
1537b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    NSWAVC_MCS_t *p_bs = M4OSA_NULL;
1547b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    M4OSA_ERR err = M4NO_ERROR;
1554ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    p_bs = (NSWAVC_MCS_t *)M4OSA_32bitAlignedMalloc(sizeof(NSWAVC_MCS_t), M4MCS,
1564ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines        (M4OSA_Char *)"NSWAVC_MCS_t");
1574ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
158b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    if( M4OSA_NULL == p_bs )
159b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    {
1609207a2e495c8363606861e4f034504ec5c153dabLogan Chien        M4OSA_TRACE1_0("H264MCS_Getinstance: allocation error");
161b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        return M4ERR_ALLOC;
1624ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
1634ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    p_bs->prev_frame_num = 0;
1654ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    p_bs->cur_frame_num = 0;
166b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->log2_max_frame_num_minus4 = 0;
167b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->prev_new_frame_num = 0;
168b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->is_done = 0;
169b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->is_first = 1;
170b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1719207a2e495c8363606861e4f034504ec5c153dabLogan Chien    p_bs->m_pDecoderSpecificInfo = M4OSA_NULL;
172b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_decoderSpecificInfoSize = 0;
173b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
174b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_pEncoderSPS = M4OSA_NULL;
175b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_encoderSPSSize = 0;
176b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1774ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    p_bs->m_pEncoderPPS = M4OSA_NULL;
178b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_encoderPPSSize = 0;
179b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
180b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_pFinalDSI = M4OSA_NULL;
181b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->m_pFinalDSISize = 0;
1829207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1839207a2e495c8363606861e4f034504ec5c153dabLogan Chien    p_bs->p_clip_sps = M4OSA_NULL;
1849207a2e495c8363606861e4f034504ec5c153dabLogan Chien    p_bs->m_encoder_SPS_Cnt = 0;
1859207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1867b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    p_bs->p_clip_pps = M4OSA_NULL;
1877b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    p_bs->m_encoder_PPS_Cnt = 0;
1887b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
189b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->p_encoder_sps = M4OSA_NULL;
190b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->p_encoder_pps = M4OSA_NULL;
191b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
192b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->encoder_pps.slice_group_id = M4OSA_NULL;
1934ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
1944ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    *instance = (NSWAVC_MCS_t *)p_bs;
195b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return err;
196b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines}
1977b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
1984ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen HinesM4OSA_UInt32 H264MCS_getBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits )
1994ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines{
2007b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    M4OSA_UInt32 ui32RetBits;
2017b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    M4OSA_UInt8 *pbs;
2027b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    M4OSA_Int32 bcnt;
2037b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    p_bs->i8BitCnt -= numBits;
2047b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    bcnt = p_bs->i8BitCnt;
205b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
206b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    /* Measure the quantity of bits to be read in ui32TempBuff */
20712580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines    ui32RetBits = p_bs->ui32TempBuff >> (32 - numBits);
20812580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines
20912580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines    /* Read numBits in ui32TempBuff */
2107b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    p_bs->ui32TempBuff <<= numBits;
2117b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    p_bs->bitPos += numBits;
2127b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
2137b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if( bcnt > 24 )
2147b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    {
2159207a2e495c8363606861e4f034504ec5c153dabLogan Chien        return (ui32RetBits);
2169207a2e495c8363606861e4f034504ec5c153dabLogan Chien    }
2179207a2e495c8363606861e4f034504ec5c153dabLogan Chien    else
2189207a2e495c8363606861e4f034504ec5c153dabLogan Chien    { /* at least one byte can be buffered in ui32TempBuff */
2197b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr;
2207b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
2217b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        if( bcnt < (int)(p_bs->numBitsInBuffer - p_bs->bitPos) )
2227b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        { /* not enough remaining bits in ui32TempBuff: need to be filled */
22312580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines            do
22412580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines            {
22512580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines                /* On the fly detection of EPB byte */
22612580dcd125d958bff87385ab13599ad01bd8aeaStephen Hines                if( ( *(pbs) == 0x03)
227b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                    && (!(( pbs[-1])
228b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                    | (pbs[-2])))) //(p_bs->ui32LastTwoBytes & 0x0000FFFF) == 0)
229b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                {
2309ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    /* EPB byte found: skip it and update bitPos accordingly */
2319ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                            (pbs)++;
2329ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                            p_bs->bitPos += 8;
2339ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                        }
2349ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2359ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                        p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt);
2369ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                        bcnt += 8;
2379ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            } while ( bcnt <= 24 );
2389ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2399ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs;
2409ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            p_bs->i8BitCnt = bcnt;
2419ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            return (ui32RetBits);
2429ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
2439ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
2449ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2459ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    if( p_bs->bitPos <= p_bs->numBitsInBuffer )
2469ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    {
2479ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        return (ui32RetBits);
2489ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
2499ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    else
2509ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    {
2519ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        return (0);
2529ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
2539ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines}
2549ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2559ca96e70657cf5437a294213f56ba4768dc08ad2Stephen HinesM4OSA_Void H264MCS_flushBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits )
2569ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines{
2579ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    M4OSA_UInt8 *pbs;
2589ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    M4OSA_UInt32 bcnt;
2599ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->i8BitCnt -= numBits;
2609ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    bcnt = p_bs->i8BitCnt;
2619ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2629ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->ui32TempBuff <<= numBits;
2639ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->bitPos += numBits;
2649ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2659ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    if( bcnt > 24 )
2669ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    {
2679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        return;
2689ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
2699ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    else
2709ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    { /* at least one byte can be buffered in ui32TempBuff */
2719ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr;
2729ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2739ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        if( bcnt < (p_bs->numBitsInBuffer - p_bs->bitPos) )
2749ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        {   /* Not enough remaining bits in ui32TempBuff: need to be filled */
2759ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            do
2769ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            {
2779ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                /*  On the fly detection of EPB byte */
2789ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                if( ( *(pbs) == 0x03) && (!(( pbs[-1]) | (pbs[-2]))) )
2799ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                { /* JC: EPB byte found: skip it and update bitPos accordingly */
2809ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    (pbs)++;
2819ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    p_bs->bitPos += 8;
2829ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                }
2839ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt);
2849ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                bcnt += 8;
2859ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            } while ( bcnt <= 24 );
2869ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs;
2889ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            p_bs->i8BitCnt = bcnt;
2899ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
2909ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
2919ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2929ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    return;
2939ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines}
2949ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
2959ca96e70657cf5437a294213f56ba4768dc08ad2Stephen HinesM4OSA_UInt32 H264MCS_DecVLCReadExpGolombCode( ComBitStreamMCS_t *p_bs )
2969ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines{
2979ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    M4OSA_UInt32 code, l0 = 0, l1;
2989ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    /* Reading 32 Bits from local cache buffer of Bitstream structure*/
2999ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    code = p_bs->ui32TempBuff;
3009ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3019ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    /* Checking in first 3 bits*/
3029ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    if( code >> 29 )
3039ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    {
3049ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        l0 = Tab_MCS[(code >> 29)];
3059ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        code = code >> (32 - l0);
3069ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        H264MCS_flushBits(p_bs, l0);
3079ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
3089ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    else
3099ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        {
3109ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            if( code )
3119ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            {
3129ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                code <<= 3;
3139ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3149ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                for ( l0 = 3; code < 0x80000000; code <<= 1, l0++ );
3159ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3169ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                if( l0 < 16 ) /*all useful bits are inside the 32 bits read */
3179ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                {
3189ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    code = code >> (31 - l0);
3199ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    H264MCS_flushBits(p_bs, 2 * l0 + 1);
3209ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                }
3219ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                else
3229ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            { /* Read the useful bits in 2 parts */
3239ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    l1 = ( l0 << 1) - 31;
3249ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    code >>= l0;
3259ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    H264MCS_flushBits(p_bs, 32);
3269ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    code = ( code << l1) | H264MCS_getBits(p_bs, l1);
3279ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                }
3289ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            }
3299ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            else
3309ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            {
3319ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                H264MCS_flushBits(p_bs, 32);
3329ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3339ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                if( H264MCS_getBits(p_bs, 1) )
3349ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                {
3359ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    /* if number of leading 0's is 32, the only code allowed is 1 followed
3369ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    by 32 0's */
3379ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3389ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    /*reading 32 more bits from bitstream buffer*/
3399ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    code = H264MCS_getBits(p_bs, 32);
3409ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3419ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    if( code == 0 )
3429ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    {
3439ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                        return (code - 1);
3449ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                    }
3459ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                }
3469ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                /*if number of leading 0's is >32, then symbol is >32 bits,
3479ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                which is an error */
3489ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                //p_bs->state = _BS_ERR;
3499ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                //p_bs->flags |= _BF_SYM_ERR;
3509ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                return (0);
3519ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            }
3529ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
3539ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3549ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        if( 1 ) //(p_bs->state == _BS_OK)
3559ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        {
3569ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            return (code - 1);
3579ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
3589ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        else
3599ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        {
3609ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            return (0);
3619ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
3629ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    }
3639ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3649ca96e70657cf5437a294213f56ba4768dc08ad2Stephen HinesM4OSA_Int32 H264MCS_DecVLCReadSignedExpGolombCode( ComBitStreamMCS_t *p_bs )
3659ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines{
3669ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    M4OSA_Int32 codeNo, ret;
3679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3689ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    /* read the unsigned code number */
3699ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    codeNo = H264MCS_DecVLCReadExpGolombCode(p_bs);
3709ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3719ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    /* map to the signed value, if value is odd then it's positive,
3729ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    if even then it's negative, formula is (-1)^(k+1)*CEIL(k/2) */
3739ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3749ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    ret = (codeNo & 0x01) ? (( codeNo + 1) >> 1) : (( -codeNo) >> 1);
3759ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3769ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    return ret;
3779ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines}
3789ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3799ca96e70657cf5437a294213f56ba4768dc08ad2Stephen HinesM4OSA_Void DecBitStreamReset_MCS( ComBitStreamMCS_t *p_bs,
3809ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                                 M4OSA_UInt32 bytes_read )
3819ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines{
3829ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->bitPos = 0;
3839ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
3849ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->lastTotalBits = 0;
3859ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->numBitsInBuffer = bytes_read << 3;
3869ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    p_bs->readableBytesInBuffer = bytes_read;
3879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    //p_bs->state = M4NO_ERROR;//_BS_OK;
3889ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    //p_bs->flags = 0;
3899ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
390593a894650e81be54173106ec266f0311cebebd3Stephen Hines    p_bs->ui32TempBuff = 0;
391593a894650e81be54173106ec266f0311cebebd3Stephen Hines    p_bs->i8BitCnt = 0;
392b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
393593a894650e81be54173106ec266f0311cebebd3Stephen Hines    p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
394b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    H264MCS_getBits(p_bs, 0);
395593a894650e81be54173106ec266f0311cebebd3Stephen Hines}
396593a894650e81be54173106ec266f0311cebebd3Stephen Hines
397593a894650e81be54173106ec266f0311cebebd3Stephen HinesM4OSA_ERR NSWAVCMCS_initBitstream( NSWAVC_bitStream_t_MCS *bS )
398c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines{
399593a894650e81be54173106ec266f0311cebebd3Stephen Hines    bS->bitPos = 0;
400b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    bS->byteCnt = 0;
401b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    bS->currBuff = 0;
402593a894650e81be54173106ec266f0311cebebd3Stephen Hines    bS->prevByte = 0xff;
403593a894650e81be54173106ec266f0311cebebd3Stephen Hines    bS->prevPrevByte = 0xff;
404593a894650e81be54173106ec266f0311cebebd3Stephen Hines
405593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return M4NO_ERROR;
406593a894650e81be54173106ec266f0311cebebd3Stephen Hines}
407b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
408593a894650e81be54173106ec266f0311cebebd3Stephen HinesM4OSA_ERR NSWAVCMCS_putBits( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value,
409593a894650e81be54173106ec266f0311cebebd3Stephen Hines                            M4OSA_UInt8 length )
410b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines{
411b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    M4OSA_UInt32 maskedValue = 0, temp = 0;
412593a894650e81be54173106ec266f0311cebebd3Stephen Hines    M4OSA_UInt8 byteOne;
413593a894650e81be54173106ec266f0311cebebd3Stephen Hines
414593a894650e81be54173106ec266f0311cebebd3Stephen Hines    M4OSA_UInt32 len1 = (length == 32) ? 31 : length;
415593a894650e81be54173106ec266f0311cebebd3Stephen Hines
416593a894650e81be54173106ec266f0311cebebd3Stephen Hines    if( !(length) )
417593a894650e81be54173106ec266f0311cebebd3Stephen Hines    {
418593a894650e81be54173106ec266f0311cebebd3Stephen Hines        /* Length = 0, return OK*/
419593a894650e81be54173106ec266f0311cebebd3Stephen Hines        return M4NO_ERROR;
420593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
421b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
422593a894650e81be54173106ec266f0311cebebd3Stephen Hines    maskedValue = (M4OSA_UInt32)(value &(( 1 << len1) - 1));
423b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
424b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    if( 32 > (length + bS->bitPos) )
425b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    {
426b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        bS->bitPos += length;
427b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        bS->currBuff |= maskedValue << (32 - bS->bitPos);
428b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    }
429b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    else
430593a894650e81be54173106ec266f0311cebebd3Stephen Hines    {
431593a894650e81be54173106ec266f0311cebebd3Stephen Hines        temp = (( bS->bitPos + length) - 32);
432593a894650e81be54173106ec266f0311cebebd3Stephen Hines
433593a894650e81be54173106ec266f0311cebebd3Stephen Hines        bS->currBuff |= (maskedValue >> (temp));
434593a894650e81be54173106ec266f0311cebebd3Stephen Hines
435593a894650e81be54173106ec266f0311cebebd3Stephen Hines        byteOne =
436593a894650e81be54173106ec266f0311cebebd3Stephen Hines            bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
437593a894650e81be54173106ec266f0311cebebd3Stephen Hines
4381688a3c56851f235866d6870c89ddb20650cc030Shih-wei Liao        if( (( bS->prevPrevByte
4391688a3c56851f235866d6870c89ddb20650cc030Shih-wei Liao            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
44043730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao        {
441593a894650e81be54173106ec266f0311cebebd3Stephen Hines            bS->byteCnt -= 1;
442b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
443b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
444b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        }
445b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        else
446b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        {
447b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevPrevByte = bS->prevByte;
448b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevByte = byteOne;
449b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        }
450b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        byteOne = bS->streamBuffer[bS->byteCnt++] =
451b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
452b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
453b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        if( (( bS->prevPrevByte
454b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
455b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        {
456b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->byteCnt -= 1;
457b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
458b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
459b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        }
460b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        else
461593a894650e81be54173106ec266f0311cebebd3Stephen Hines        {
462593a894650e81be54173106ec266f0311cebebd3Stephen Hines            bS->prevPrevByte = bS->prevByte;
463593a894650e81be54173106ec266f0311cebebd3Stephen Hines            bS->prevByte = byteOne;
464b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        }
465b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        byteOne = bS->streamBuffer[bS->byteCnt++] =
466b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
4679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
4689ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        if( (( bS->prevPrevByte
4699ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
470b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        {
471593a894650e81be54173106ec266f0311cebebd3Stephen Hines            bS->byteCnt -= 1;
4729ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
4739ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
4749ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
4759ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        else
4769ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        {
477b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevPrevByte = bS->prevByte;
478b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            bS->prevByte = byteOne;
479593a894650e81be54173106ec266f0311cebebd3Stephen Hines        }
480593a894650e81be54173106ec266f0311cebebd3Stephen Hines        byteOne = bS->streamBuffer[bS->byteCnt++] =
481b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            (M4OSA_UInt8)((bS->currBuff) &0xff);
482593a894650e81be54173106ec266f0311cebebd3Stephen Hines
483593a894650e81be54173106ec266f0311cebebd3Stephen Hines        if( (( bS->prevPrevByte
484c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
485c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        {
486c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines            bS->byteCnt -= 1;
487c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
488c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
489c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        }
490c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        else
491c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        {
4929999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevPrevByte = bS->prevByte;
4939999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = byteOne;
4949ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        }
4959ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
4969ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        bS->currBuff = 0;
4979ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
498593a894650e81be54173106ec266f0311cebebd3Stephen Hines        bS->currBuff |= ( maskedValue &(( 1 << temp) - 1)) << (32 - temp);
499593a894650e81be54173106ec266f0311cebebd3Stephen Hines
500593a894650e81be54173106ec266f0311cebebd3Stephen Hines        bS->bitPos = temp;
501593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
502b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
5039999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    return M4NO_ERROR;
5049999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines}
505593a894650e81be54173106ec266f0311cebebd3Stephen Hines
506f736d5a12269e7e74740b130cdca98d9839b31e6Stephen HinesM4OSA_ERR NSWAVCMCS_putBit( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value )
5079999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines{
508f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines    M4OSA_UInt32 maskedValue = 0, temp = 0;
509f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines    M4OSA_UInt8 byteOne;
5109999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines
5119999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    maskedValue = (value ? 1 : 0);
512f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines
513f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines    if( 32 > (1 + bS->bitPos) )
514f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines    {
5159999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        bS->bitPos += 1;
5169999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        bS->currBuff |= maskedValue << (32 - bS->bitPos);
5179999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    }
5189999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    else
5199999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    {
5209ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        temp = 0;
5219ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
5229ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        bS->currBuff |= (maskedValue);
5239ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
5249ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        /* writing it to memory*/
5257b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        byteOne =
5269999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->streamBuffer[bS->byteCnt++] =
5279999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            (M4OSA_UInt8)(bS->currBuff >> 24);
5289999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines
5297b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        if( (( bS->prevPrevByte
5307b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
5317b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        {
5327b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->byteCnt -= 1;
5337b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
5347b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
5357b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        }
5367b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        else
5377b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        {
5387b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->prevPrevByte = bS->prevByte;
5397b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->prevByte = byteOne;
5407b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        }
5417b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        byteOne = bS->streamBuffer[bS->byteCnt++] =
5427b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
5437b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
5447b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        if( (( bS->prevPrevByte
5457b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
5467b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        {
5477b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines            bS->byteCnt -= 1;
5489999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
5499999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
5507b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines        }
551593a894650e81be54173106ec266f0311cebebd3Stephen Hines        else
552593a894650e81be54173106ec266f0311cebebd3Stephen Hines        {
5539207a2e495c8363606861e4f034504ec5c153dabLogan Chien            bS->prevPrevByte = bS->prevByte;
554fbfd7f5fd97458b6b23437556025ac1d55e98fd4Stephen Hines            bS->prevByte = byteOne;
555fbfd7f5fd97458b6b23437556025ac1d55e98fd4Stephen Hines        }
5569207a2e495c8363606861e4f034504ec5c153dabLogan Chien        byteOne = bS->streamBuffer[bS->byteCnt++] =
5579207a2e495c8363606861e4f034504ec5c153dabLogan Chien            (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
558593a894650e81be54173106ec266f0311cebebd3Stephen Hines
559593a894650e81be54173106ec266f0311cebebd3Stephen Hines        if( (( bS->prevPrevByte
5609999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
561593a894650e81be54173106ec266f0311cebebd3Stephen Hines        {
5629999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->byteCnt -= 1;
5639999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
5649999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
5659999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        }
5669999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        else
5679999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        {
5689207a2e495c8363606861e4f034504ec5c153dabLogan Chien            bS->prevPrevByte = bS->prevByte;
5699999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = byteOne;
5709207a2e495c8363606861e4f034504ec5c153dabLogan Chien        }
5719207a2e495c8363606861e4f034504ec5c153dabLogan Chien        byteOne = bS->streamBuffer[bS->byteCnt++] =
5729999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            (M4OSA_UInt8)((bS->currBuff) &0xff);
5739999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines
5749999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        if( (( bS->prevPrevByte
575593a894650e81be54173106ec266f0311cebebd3Stephen Hines            == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
576593a894650e81be54173106ec266f0311cebebd3Stephen Hines        {
5779999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->byteCnt -= 1;
5789999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
5799999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
5809999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        }
5819999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        else
5829999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        {
5839999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevPrevByte = bS->prevByte;
5849999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines            bS->prevByte = byteOne;
5859999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        }
5869999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        bS->currBuff = 0;
5879999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines        bS->bitPos = 0;
588593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
589688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
590593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return M4NO_ERROR;
5919207a2e495c8363606861e4f034504ec5c153dabLogan Chien}
5929207a2e495c8363606861e4f034504ec5c153dabLogan Chien
5939207a2e495c8363606861e4f034504ec5c153dabLogan ChienM4OSA_Int32 NSWAVCMCS_putRbspTbits( NSWAVC_bitStream_t_MCS *bS )
5949207a2e495c8363606861e4f034504ec5c153dabLogan Chien{
5959207a2e495c8363606861e4f034504ec5c153dabLogan Chien    M4OSA_UInt8 trailBits = 0;
5969207a2e495c8363606861e4f034504ec5c153dabLogan Chien    M4OSA_UInt8 byteCnt = 0;
597593a894650e81be54173106ec266f0311cebebd3Stephen Hines
598593a894650e81be54173106ec266f0311cebebd3Stephen Hines    trailBits = (M4OSA_UInt8)(bS->bitPos % 8);
599593a894650e81be54173106ec266f0311cebebd3Stephen Hines
600593a894650e81be54173106ec266f0311cebebd3Stephen Hines    /* Already in the byte aligned position,
6019207a2e495c8363606861e4f034504ec5c153dabLogan Chien    RBSP trailing bits will be 1000 0000 */
6029207a2e495c8363606861e4f034504ec5c153dabLogan Chien    if( 0 == trailBits )
6039207a2e495c8363606861e4f034504ec5c153dabLogan Chien    {
6049207a2e495c8363606861e4f034504ec5c153dabLogan Chien        trailBits = (1 << 7);
6059207a2e495c8363606861e4f034504ec5c153dabLogan Chien        NSWAVCMCS_putBits(bS, trailBits, 8);
6069207a2e495c8363606861e4f034504ec5c153dabLogan Chien    }
607593a894650e81be54173106ec266f0311cebebd3Stephen Hines    else
608593a894650e81be54173106ec266f0311cebebd3Stephen Hines    {
609593a894650e81be54173106ec266f0311cebebd3Stephen Hines        trailBits = (8 - trailBits);
610688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines        NSWAVCMCS_putBit(bS, 1);
611593a894650e81be54173106ec266f0311cebebd3Stephen Hines        trailBits--;
612593a894650e81be54173106ec266f0311cebebd3Stephen Hines
613593a894650e81be54173106ec266f0311cebebd3Stephen Hines        if( trailBits )
614593a894650e81be54173106ec266f0311cebebd3Stephen Hines        { /* put trailBits times zeros */
615593a894650e81be54173106ec266f0311cebebd3Stephen Hines            NSWAVCMCS_putBits(bS, 0, trailBits);
616593a894650e81be54173106ec266f0311cebebd3Stephen Hines        }
617    }
618
619    /* For writting the currBuff in streamBuff 4byte alignment is required*/
620    byteCnt = (M4OSA_UInt8)(( bS->bitPos + 4) / 8);
621
622    switch( byteCnt )
623    {
624        case 1:
625            bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
626            break;
627
628        case 2:
629            bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
630            bS->streamBuffer[bS->byteCnt++] =
631                (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
632            break;
633
634        case 3:
635            bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
636            bS->streamBuffer[bS->byteCnt++] =
637                (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
638            bS->streamBuffer[bS->byteCnt++] =
639                (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
640
641            break;
642
643        default:
644            /* It will not come here */
645            break;
646    }
647
648    //    bS->bitPos =0;
649    //    bS->currBuff = 0;
650
651    return M4NO_ERROR;
652}
653
654M4OSA_ERR NSWAVCMCS_uExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum )
655{
656
657    M4OSA_Int32 loop, temp;
658    M4OSA_Int32 data = 0;
659    M4OSA_UInt8 codeLen = 0;
660
661    /* The codeNum cannot be less than zero for this ue(v) */
662    if( codeNum < 0 )
663    {
664        return 0;
665    }
666
667    /* Implementation for Encoding of the Table 9-1 in the Standard */
668    temp = codeNum + 1;
669
670    for ( loop = 0; temp != 0; loop++ )
671    {
672        temp /= 2;
673    }
674
675    codeLen = (( loop * 2) - 1);
676
677    data = codeNum + 1;
678
679    NSWAVCMCS_putBits(bS, data, codeLen);
680
681    return M4NO_ERROR;
682}
683
684M4OSA_ERR NSWAVCMCS_sExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum )
685{
686
687    M4OSA_Int32 loop, temp1, temp2;
688    M4OSA_Int32 data = 0;
689    M4OSA_UInt8 codeLen = 0, isPositive = 0;
690    M4OSA_UInt32 abscodeNum;
691
692    if( codeNum > 0 )
693    {
694        isPositive = 1;
695    }
696
697    if( codeNum > 0 )
698    {
699        abscodeNum = codeNum;
700    }
701    else
702    {
703        abscodeNum = -codeNum;
704    }
705
706    temp1 = ( ( ( abscodeNum) << 1) - isPositive) + 1;
707    temp2 = temp1;
708
709    for ( loop = 0; loop < 16 && temp2 != 0; loop++ )
710    {
711        temp2 /= 2;
712    }
713
714    codeLen = ( loop * 2) - 1;
715
716    data = temp1;
717
718    NSWAVCMCS_putBits(bS, data, codeLen);
719
720    return M4NO_ERROR;
721}
722
723M4OSA_ERR H264MCS_ProcessEncodedNALU(   M4OSA_Void *ainstance,
724                                        M4OSA_UInt8 *inbuff,
725                                        M4OSA_Int32 inbuf_size,
726                                        M4OSA_UInt8 *outbuff,
727                                        M4OSA_Int32 *outbuf_size )
728{
729    ComBitStreamMCS_t *p_bs, bs;
730    NSWAVC_MCS_t *instance;
731    M4OSA_UInt8 nalu_info;
732    M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
733    M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num;
734    M4OSA_Int32 seq_parameter_set_id;
735    M4OSA_UInt8 temp1, temp2, temp3, temp4;
736    M4OSA_Int32 temp_frame_num;
737    M4OSA_Int32 bitstoDiacard, bytes;
738    M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
739    M4OSA_Int32 new_bytes, init_bit_pos;
740    M4OSA_UInt32 nal_size;
741    M4OSA_UInt32 cnt;
742    M4OSA_UInt32 outbuffpos = 0;
743    M4OSA_UInt32 nal_size_low16, nal_size_high16;
744    M4OSA_UInt32 frame_size = 0;
745    M4OSA_UInt32 temp = 0;
746
747    // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
748    M4OSA_Int8 *pTmpBuff1 = M4OSA_NULL;
749    M4OSA_Int8 *pTmpBuff2 = M4OSA_NULL;
750
751    p_bs = &bs;
752    instance = (NSWAVC_MCS_t *)ainstance;
753
754    M4OSA_TRACE1_2(
755        "In  H264MCS_ProcessEncodedNALU with FrameSize = %d  inBuf_Size=%d",
756        frame_size, inbuf_size);
757
758    // StageFright codecs may add a start code, make sure it is not present
759
760    if( !memcmp((void *)inbuff,
761        "\x00\x00\x00\x01", 4) )
762    {
763        M4OSA_TRACE1_3(
764            "H264MCS_ProcessNALU ERROR : NALU start code has not been removed %d "
765            "0x%X 0x%X", inbuf_size, ((M4OSA_UInt32 *)inbuff)[0],
766            ((M4OSA_UInt32 *)inbuff)[1]);
767
768        return M4ERR_PARAMETER;
769    }
770
771    // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
772    pTmpBuff1 = (M4OSA_Int8 *)M4OSA_32bitAlignedMalloc(inbuf_size + 4, M4MCS,
773        (M4OSA_Char *)"tmpNALU");
774    memcpy((void *)(pTmpBuff1 + 4), (void *)inbuff,
775        inbuf_size);
776    pTmpBuff1[3] = ( (M4OSA_UInt32)inbuf_size) & 0x000000FF;
777    pTmpBuff1[2] = ( (M4OSA_UInt32)inbuf_size >> 8) & 0x000000FF;
778    pTmpBuff1[1] = ( (M4OSA_UInt32)inbuf_size >> 16) & 0x000000FF;
779    pTmpBuff1[0] = ( (M4OSA_UInt32)inbuf_size >> 24) & 0x000000FF;
780    pTmpBuff2 = (M4OSA_Int8 *)inbuff;
781    inbuff = (M4OSA_UInt8 *)pTmpBuff1;
782    inbuf_size += 4;
783
784    // Make sure the available size was set
785    if( inbuf_size >= *outbuf_size )
786    {
787        M4OSA_TRACE1_1(
788            "!!! H264MCS_ProcessNALU ERROR : specified available size is incorrect %d ",
789            *outbuf_size);
790        return M4ERR_PARAMETER;
791    }
792
793
794
795    while( (M4OSA_Int32)frame_size < inbuf_size )
796    {
797        mask_bits = 0xFFFFFFFF;
798        p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
799
800        // Use unsigned value to fix errors due to bit sign extension, this fix should be generic
801
802        nal_size_high16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[0] << 8)
803            + ((M4OSA_UInt8 *)p_bs->Buffer)[1];
804        nal_size_low16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[2] << 8)
805            + ((M4OSA_UInt8 *)p_bs->Buffer)[3];
806
807        nalu_info = (unsigned char)p_bs->Buffer[4];
808
809        outbuff[outbuffpos] = p_bs->Buffer[4];
810
811        p_bs->Buffer = p_bs->Buffer + 5;
812
813        p_bs->bitPos = 0;
814        p_bs->lastTotalBits = 0;
815        p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3;
816        p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5;
817
818        p_bs->ui32TempBuff = 0;
819        p_bs->i8BitCnt = 0;
820        p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
821        p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
822
823        H264MCS_getBits(p_bs, 0);
824
825        nal_size = ( nal_size_high16 << 16) + nal_size_low16;
826
827        frame_size += nal_size + 4;
828
829        forbidden_bit = ( nalu_info >> 7) & 1;
830        nal_ref_idc = ( nalu_info >> 5) & 3;
831        nal_unit_type = (nalu_info) &0x1f;
832
833        NSWAVCMCS_initBitstream(&instance->encbs);
834
835        instance->encbs.streamBuffer = outbuff + outbuffpos + 1;
836
837        if( nal_unit_type == 8 )
838        {
839            M4OSA_TRACE1_0("Error : PPS");
840            return 0;
841        }
842
843        if( nal_unit_type == 7 )
844        {
845            /*SPS Packet */
846            M4OSA_TRACE1_0("Error : SPS");
847            return 0;
848        }
849
850        if( (nal_unit_type == 5) )
851        {
852            instance->frame_count = 0;
853            instance->POC_lsb = 0;
854        }
855
856        if( ( nal_unit_type == 1) || (nal_unit_type == 5) )
857        {
858            first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
859            slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
860            pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
861
862            /* First MB in slice */
863            NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice);
864
865            /* Slice Type */
866            NSWAVCMCS_uExpVLC(&instance->encbs, slice_type);
867
868            /* Picture Parameter set Id */
869            pic_parameter_set_id = instance->encoder_pps.pic_parameter_set_id;
870            NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id);
871
872            temp = H264MCS_getBits(p_bs,
873                instance->encoder_sps.log2_max_frame_num_minus4 + 4);
874            NSWAVCMCS_putBits(&instance->encbs, instance->frame_count,
875                instance->clip_sps.log2_max_frame_num_minus4 + 4);
876
877            // In Baseline Profile: frame_mbs_only_flag should be ON
878            if( nal_unit_type == 5 )
879            {
880                temp = H264MCS_DecVLCReadExpGolombCode(p_bs);
881                NSWAVCMCS_uExpVLC(&instance->encbs, temp);
882            }
883
884            if( instance->encoder_sps.pic_order_cnt_type == 0 )
885            {
886                temp = H264MCS_getBits(p_bs,
887                    instance->encoder_sps.log2_max_pic_order_cnt_lsb_minus4
888                    + 4);
889
890                // in baseline profile field_pic_flag should be off.
891                if( instance->encoder_pps.pic_order_present_flag )
892                {
893                    temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
894                }
895            }
896
897            if( ( instance->encoder_sps.pic_order_cnt_type == 1)
898                && (instance->encoder_sps.delta_pic_order_always_zero_flag) )
899            {
900                temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
901
902                // in baseline profile field_pic_flag should be off.
903                if( instance->encoder_pps.pic_order_present_flag )
904                {
905                    temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
906                }
907            }
908
909            if( instance->clip_sps.pic_order_cnt_type == 0 )
910            {
911                NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb,
912                    instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
913
914                // in baseline profile field_pic_flag should be off.
915                if( instance->encoder_pps.pic_order_present_flag )
916                {
917                    NSWAVCMCS_sExpVLC(&instance->encbs, 0);
918                }
919            }
920
921            if( ( instance->clip_sps.pic_order_cnt_type == 1)
922                && (instance->clip_sps.delta_pic_order_always_zero_flag) )
923            {
924                NSWAVCMCS_sExpVLC(&instance->encbs, 0);
925
926                // in baseline profile field_pic_flag should be off.
927                if( instance->encoder_pps.pic_order_present_flag )
928                {
929                    NSWAVCMCS_sExpVLC(&instance->encbs, 0);
930                }
931            }
932
933            cnt = p_bs->bitPos & 0x7;
934
935            if( cnt )
936            {
937                cnt = 8 - cnt;
938                temp = H264MCS_getBits(p_bs, cnt);
939                NSWAVCMCS_putBits(&instance->encbs, temp, cnt);
940            }
941
942            cnt = p_bs->bitPos >> 3;
943
944            while( cnt < (nal_size - 2) )
945            {
946                temp = H264MCS_getBits(p_bs, 8);
947                NSWAVCMCS_putBits(&instance->encbs, temp, 8);
948                cnt = p_bs->bitPos >> 3;
949            }
950
951            temp = H264MCS_getBits(p_bs, 8);
952
953            if( temp != 0 )
954            {
955                cnt = 0;
956
957                while( ( temp & 0x1) == 0 )
958                {
959                    cnt++;
960                    temp = temp >> 1;
961                }
962                cnt++;
963                temp = temp >> 1;
964
965                if( 8 - cnt )
966                {
967                    NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt));
968                }
969
970                NSWAVCMCS_putRbspTbits(&instance->encbs);
971            }
972            else
973            {
974
975                M4OSA_TRACE1_1(
976                    "H264MCS_ProcessEncodedNALU : 13 temp = 0 trailing bits = %d",
977                    instance->encbs.bitPos % 8);
978
979                if( instance->encbs.bitPos % 8 )
980                {
981                    NSWAVCMCS_putBits(&instance->encbs, 0,
982                        (8 - instance->encbs.bitPos % 8));
983                }
984            }
985
986            temp = instance->encbs.byteCnt;
987            temp = temp + 1;
988
989            outbuffpos = outbuffpos + temp;
990        }
991    }
992
993    *outbuf_size = outbuffpos;
994
995    instance->POC_lsb = instance->POC_lsb + 1;
996
997    if( instance->POC_lsb == instance->POC_lsb_mod )
998    {
999        instance->POC_lsb = 0;
1000    }
1001    instance->frame_count = instance->frame_count + 1;
1002
1003    if( instance->frame_count == instance->frame_mod_count )
1004    {
1005        instance->frame_count = 0;
1006    }
1007
1008    // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
1009
1010    free(pTmpBuff1);
1011    pTmpBuff1 = M4OSA_NULL;
1012    inbuff = (M4OSA_UInt8 *)pTmpBuff2;
1013
1014    return M4NO_ERROR;
1015}
1016
1017M4OSA_Int32 DecSPSMCS( ComBitStreamMCS_t *p_bs,
1018                      ComSequenceParameterSet_t_MCS *sps )
1019{
1020    M4OSA_UInt32 i;
1021    M4OSA_Int32 temp_max_dpb_size;
1022    M4OSA_Int32 nb_ignore_bits;
1023    M4OSA_Int32 error;
1024    M4OSA_UInt8 profile_idc, level_idc, reserved_zero_4bits,
1025        seq_parameter_set_id;
1026    M4OSA_UInt8 constraint_set0_flag, constraint_set1_flag,
1027        constraint_set2_flag, constraint_set3_flag;
1028
1029    sps->profile_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8);
1030    sps->constraint_set0_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1031    sps->constraint_set1_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1032    sps->constraint_set2_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1033    sps->constraint_set3_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1034    reserved_zero_4bits = (M4OSA_UInt8)H264MCS_getBits(p_bs, 4);
1035    sps->level_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8);
1036    sps->seq_parameter_set_id =
1037        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1038    sps->log2_max_frame_num_minus4 =
1039        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1040    sps->MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1041    sps->pic_order_cnt_type =
1042        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1043
1044    if (sps->pic_order_cnt_type == 0)
1045    {
1046        sps->log2_max_pic_order_cnt_lsb_minus4 =
1047            (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1048        sps->MaxPicOrderCntLsb =
1049            1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1050    }
1051    else if( sps->pic_order_cnt_type == 1 )
1052    {
1053        sps->delta_pic_order_always_zero_flag =
1054            (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1055
1056        // This fix should be generic to remove codec dependency
1057
1058        sps->offset_for_non_ref_pic =
1059            H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1060        sps->offset_for_top_to_bottom_field =
1061            H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1062
1063
1064        /*num_ref_frames_in_pic_order_cnt_cycle must be in the range 0, 255*/
1065
1066        sps->num_ref_frames_in_pic_order_cnt_cycle =
1067            (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1068
1069        /* compute deltaPOC */
1070        sps->expectedDeltaPerPicOrderCntCycle = 0;
1071
1072        for ( i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++ )
1073        {
1074            // This fix should be generic to remove codec dependency
1075            sps->offset_for_ref_frame[i] =
1076                H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1077
1078            sps->expectedDeltaPerPicOrderCntCycle +=
1079                sps->offset_for_ref_frame[i];
1080        }
1081    }
1082
1083    /* num_ref_frames must be in the range 0,16 */
1084    sps->num_ref_frames = (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1085    sps->gaps_in_frame_num_value_allowed_flag =
1086        (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1087
1088    sps->pic_width_in_mbs_minus1 =
1089        (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1090    sps->pic_height_in_map_units_minus1 =
1091        (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1092
1093    sps->frame_mbs_only_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1094
1095    if (!sps->frame_mbs_only_flag)
1096    {
1097        sps->mb_adaptive_frame_field_flag =
1098            (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1099    }
1100    else
1101    {
1102        sps->mb_adaptive_frame_field_flag = 0;
1103    }
1104
1105    sps->PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1;
1106    sps->FrameHeightInMbs = ( 2 - sps->frame_mbs_only_flag) * \
1107        (sps->pic_height_in_map_units_minus1 + 1);
1108#ifdef _CAP_FMO_
1109
1110    sps->NumSliceGroupMapUnits =
1111        sps->PicWidthInMbs * (sps->pic_height_in_map_units_minus1 + 1);
1112    sps->MaxPicSizeInMbs = sps->PicWidthInMbs * sps->FrameHeightInMbs;
1113
1114#endif /*_CAP_FMO_*/
1115
1116    sps->direct_8x8_inference_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1117
1118    if( sps->frame_mbs_only_flag == 0 )
1119        sps->direct_8x8_inference_flag = 1;
1120
1121    sps->frame_cropping_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1122
1123    if( sps->frame_cropping_flag )
1124    {
1125        sps->frame_crop_left_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1126        sps->frame_crop_right_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1127        sps->frame_crop_top_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1128        sps->frame_crop_bottom_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1129    }
1130    else
1131    {
1132        sps->frame_crop_left_offset = 0;
1133        sps->frame_crop_right_offset = 0;
1134        sps->frame_crop_top_offset = 0;
1135        sps->frame_crop_bottom_offset = 0;
1136    }
1137
1138    sps->vui_parameters_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1139
1140    if (sps->vui_parameters_present_flag) {
1141        /* no error message as stream can be decoded without VUI messages */
1142    }
1143
1144    return M4NO_ERROR;
1145}
1146
1147M4OSA_Int32 DecPPSMCS( ComBitStreamMCS_t *p_bs,
1148                      ComPictureParameterSet_t_MCS *pps )
1149{
1150    M4OSA_Int32 error;
1151    M4OSA_UInt32 pic_parameter_set_id;
1152
1153#ifdef _CAP_FMO_
1154    M4OSA_UInt32 i, length, v;
1155#endif
1156
1157    M4OSA_Int32 nb_ignore_bits;
1158
1159    pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1160    pps->pic_parameter_set_id = (M4OSA_UInt8)pic_parameter_set_id;
1161
1162    pps->seq_parameter_set_id =
1163        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1164
1165    /* entropy_coding_mode_flag must be 0 or 1 */
1166    pps->entropy_coding_mode_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1167    pps->pic_order_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1168
1169    pps->num_slice_groups_minus1 =
1170        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1171
1172#ifdef _CAP_FMO_
1173    /* FMO stuff begins here */
1174
1175    pps->map_initialized = FALSE;
1176
1177    if( pps->num_slice_groups_minus1 > 0 )
1178    {
1179        pps->slice_group_map_type =
1180            (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1181
1182        switch( pps->slice_group_map_type )
1183        {
1184            case 0:
1185                for ( i = 0; i <= pps->num_slice_groups_minus1; i++ )
1186                {
1187                    pps->run_length_minus1[i] =
1188                        (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1189                }
1190                break;
1191
1192            case 2:
1193                for ( i = 0; i < pps->num_slice_groups_minus1; i++ )
1194                {
1195                    pps->top_left[i] =
1196                        (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1197                    pps->bottom_right[i] =
1198                        (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1199                }
1200                break;
1201
1202            case 3:
1203            case 4:
1204            case 5:
1205                pps->slice_group_change_direction_flag =
1206                    (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1207                pps->slice_group_change_rate_minus1 =
1208                    (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1209                break;
1210
1211            case 6:
1212                pps->pic_size_in_map_units_minus1 =
1213                    (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1214
1215                pps->slice_group_id = (H264UInt8
1216                    *)M4H264Dec_malloc((pps->pic_size_in_map_units_minus1
1217                    + 1), M4H264_COREID, (M4OSA_Char *)"PPS");
1218
1219                if (M4OSA_NULL == pps->slice_group_id)
1220                {
1221                    M4OSA_TRACE1_0("DecPPSMCS: allocation error");
1222                    return M4ERR_ALLOC;
1223                }
1224
1225                for ( length = 0, v = pps->num_slice_groups_minus1 + 1; v != 0;
1226                    v >>= 1, length++ );
1227
1228                    for ( i = 0; i <= pps->pic_size_in_map_units_minus1; i++ )
1229                    {
1230                        pps->slice_group_id[i] =
1231                            (M4OSA_UInt8)getBits(p_vlc_engine->p_bs, length);
1232                    }
1233                    break;
1234        }
1235    }
1236    else
1237    {
1238        pps->slice_group_map_type = 0;
1239    }
1240    /* End of FMO stuff */
1241
1242#else
1243
1244#endif /* _CAP_FMO_ */
1245
1246    /* num_ref_idx_l0_active_minus1 must be in the range 0, 31 */
1247
1248    pps->num_ref_idx_l0_active_minus1 =
1249        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1250    /* num_ref_idx_l1_active_minus1 must be in the range 0, 31 */
1251    pps->num_ref_idx_l1_active_minus1 =
1252        (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1253    pps->weighted_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1254
1255    /* weighted_bipred_idc must be in the range 0,2 */
1256    pps->weighted_bipred_idc = (M4OSA_Bool)H264MCS_getBits(p_bs, 2);
1257
1258    /* pic_init_qp_minus26 must be in the range -26,25 */
1259    pps->pic_init_qp_minus26 =
1260        (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1261
1262    /* pic_init_qs_minus26 must be in the range -26,25 */
1263    pps->pic_init_qs_minus26 =
1264        (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1265
1266    /* chroma_qp_index_offset must be in the range -12,+12 */
1267    pps->chroma_qp_index_offset =
1268        (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1269    pps->deblocking_filter_control_present_flag =
1270        (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1271    pps->constrained_intra_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1272    pps->redundant_pic_cnt_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1273
1274    return M4NO_ERROR;
1275}
1276
1277M4OSA_ERR H264MCS_ProcessSPS_PPS( NSWAVC_MCS_t *instance, M4OSA_UInt8 *inbuff,
1278                                 M4OSA_Int32 inbuf_size )
1279{
1280    ComBitStreamMCS_t *p_bs, bs;
1281    ComBitStreamMCS_t *p_bs1, bs1;
1282
1283    M4OSA_UInt8 nalu_info = 0;
1284    M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
1285    M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id = 0,
1286        frame_num;
1287    M4OSA_Int32 seq_parameter_set_id;
1288    M4OSA_UInt8 temp1, temp2, temp3, temp4;
1289    M4OSA_Int32 temp_frame_num;
1290    M4OSA_Int32 bitstoDiacard, bytes;
1291    M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
1292    M4OSA_Int32 new_bytes, init_bit_pos;
1293    M4OSA_UInt32 nal_size = 0;
1294    M4OSA_UInt32 cnt, cnt1;
1295    M4OSA_UInt32 outbuffpos = 0;
1296    M4OSA_UInt32 nal_size_low16, nal_size_high16;
1297    M4OSA_UInt32 frame_size = 0;
1298    M4OSA_UInt32 temp = 0;
1299    M4OSA_UInt8 *lClipDSI;
1300    M4OSA_UInt8 *lClipDSI_PPS_start;
1301    M4OSA_UInt32 lClipDSI_PPS_offset = 0;
1302
1303    M4OSA_UInt8 *lPPS_Buffer = M4OSA_NULL;
1304    M4OSA_UInt32 lPPS_Buffer_Size = 0;
1305
1306    M4OSA_UInt32 lSize, lSize1;
1307    M4OSA_UInt32 lActiveSPSID_Clip;
1308    M4OSA_UInt32 lClipPPSRemBits = 0;
1309
1310    M4OSA_UInt32 lEncoder_SPSID = 0;
1311    M4OSA_UInt32 lEncoder_PPSID = 0;
1312    M4OSA_UInt32 lEncoderPPSRemBits = 0;
1313    M4OSA_UInt32 lFound = 0;
1314    M4OSA_UInt32 size;
1315
1316    M4OSA_UInt8 Clip_SPSID[32] = { 0 };
1317    M4OSA_UInt8 Clip_UsedSPSID[32] = { 0 };
1318    M4OSA_UInt8 Clip_PPSID[256] = { 0 };
1319    M4OSA_UInt8 Clip_SPSID_in_PPS[256] = { 0 };
1320    M4OSA_UInt8 Clip_UsedPPSID[256] = { 0 };
1321    M4OSA_ERR err = M4NO_ERROR;
1322
1323    p_bs = &bs;
1324    p_bs1 = &bs1;
1325
1326    /* Find the active SPS ID */
1327    M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
1328        "H264MCS_ProcessSPS_PPS: instance is M4OSA_NULL");
1329
1330    switch( instance->m_pDecoderSpecificInfo[4] & 0x3 )
1331    {
1332        case 0:
1333            instance->m_Num_Bytes_NALUnitLength = 1;
1334            break;
1335
1336        case 1:
1337            instance->m_Num_Bytes_NALUnitLength = 2;
1338            break;
1339
1340        case 3:
1341            //Note: Current code supports only this...
1342            instance->m_Num_Bytes_NALUnitLength = 4;
1343            break;
1344    }
1345
1346    instance->m_encoder_SPS_Cnt = instance->m_pDecoderSpecificInfo[5] & 0x1F;
1347
1348    lClipDSI = instance->m_pDecoderSpecificInfo + 6;
1349
1350    lClipDSI_PPS_offset = 6;
1351
1352    for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ )
1353    {
1354        lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1355        lClipDSI = lClipDSI + 2;
1356
1357        p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 4);
1358        DecBitStreamReset_MCS(p_bs, lSize - 4);
1359
1360        Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1361        Clip_UsedSPSID[Clip_SPSID[cnt]] = 1;
1362
1363        lClipDSI = lClipDSI + lSize;
1364        lClipDSI_PPS_offset = lClipDSI_PPS_offset + 2 + lSize;
1365    }
1366
1367    instance->m_encoder_PPS_Cnt = lClipDSI[0];
1368    lClipDSI = lClipDSI + 1;
1369
1370    lClipDSI_PPS_start = lClipDSI;
1371
1372    for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ )
1373    {
1374        lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1375        lClipDSI = lClipDSI + 2;
1376
1377        p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1378        DecBitStreamReset_MCS(p_bs, lSize - 1);
1379
1380        Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1381        Clip_UsedPPSID[Clip_PPSID[cnt]] = 1;
1382        Clip_SPSID_in_PPS[Clip_PPSID[cnt]] =
1383            H264MCS_DecVLCReadExpGolombCode(p_bs);
1384
1385        lClipDSI = lClipDSI + lSize;
1386    }
1387
1388    /* Find the clip SPS ID used at the cut start frame */
1389    while( ( (M4OSA_Int32)frame_size) < inbuf_size )
1390    {
1391        mask_bits = 0xFFFFFFFF;
1392        p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
1393
1394        switch( instance->m_Num_Bytes_NALUnitLength )
1395        {
1396            case 1:
1397                nal_size = (unsigned char)p_bs->Buffer[0];
1398                nalu_info = (unsigned char)p_bs->Buffer[1];
1399                p_bs->Buffer = p_bs->Buffer + 2;
1400
1401                break;
1402
1403            case 2:
1404                nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1];
1405                nal_size = nal_size_high16;
1406                nalu_info = (unsigned char)p_bs->Buffer[2];
1407                p_bs->Buffer = p_bs->Buffer + 3;
1408
1409                break;
1410
1411            case 4:
1412                nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1];
1413                nal_size_low16 = ( p_bs->Buffer[2] << 8) + p_bs->Buffer[3];
1414                nal_size = ( nal_size_high16 << 16) + nal_size_low16;
1415                nalu_info = (unsigned char)p_bs->Buffer[4];
1416                p_bs->Buffer = p_bs->Buffer + 5;
1417
1418                break;
1419        }
1420
1421        p_bs->bitPos = 0;
1422        p_bs->lastTotalBits = 0;
1423        p_bs->numBitsInBuffer =
1424            ( inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1)
1425            << 3;
1426        p_bs->readableBytesInBuffer =
1427            inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1;
1428
1429        p_bs->ui32TempBuff = 0;
1430        p_bs->i8BitCnt = 0;
1431        p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
1432        p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
1433
1434        H264MCS_getBits(p_bs, 0);
1435
1436        frame_size += nal_size + instance->m_Num_Bytes_NALUnitLength;
1437
1438        forbidden_bit = ( nalu_info >> 7) & 1;
1439        nal_ref_idc = ( nalu_info >> 5) & 3;
1440        nal_unit_type = (nalu_info) &0x1f;
1441
1442        if( nal_unit_type == 8 )
1443        {
1444            M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: PPS");
1445            return err;
1446        }
1447
1448        if( nal_unit_type == 7 )
1449        {
1450            /*SPS Packet */
1451            M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: SPS");
1452            return err;
1453        }
1454
1455        if( ( nal_unit_type == 1) || (nal_unit_type == 5) )
1456        {
1457            first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
1458            slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
1459            pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1460            break;
1461        }
1462    }
1463
1464    lActiveSPSID_Clip = Clip_SPSID_in_PPS[pic_parameter_set_id];
1465
1466    instance->final_SPS_ID = lActiveSPSID_Clip;
1467    /* Do we need to add encoder PPS to clip PPS */
1468
1469    lClipDSI = lClipDSI_PPS_start;
1470
1471    for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ )
1472    {
1473        lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1474        lClipDSI = lClipDSI + 2;
1475
1476        if( lActiveSPSID_Clip == Clip_SPSID_in_PPS[Clip_PPSID[cnt]] )
1477        {
1478            lPPS_Buffer = lClipDSI + 1;
1479            lPPS_Buffer_Size = lSize - 1;
1480
1481            p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1482            DecBitStreamReset_MCS(p_bs, lSize - 1);
1483
1484            Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1485            Clip_UsedPPSID[Clip_SPSID[cnt]] = 1;
1486            Clip_SPSID_in_PPS[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1487            lClipPPSRemBits = ( lSize - 1) << 3;
1488            lClipPPSRemBits -= p_bs->bitPos;
1489
1490            temp = lClipDSI[lSize - 1];
1491
1492            cnt1 = 0;
1493
1494            while( ( temp & 0x1) == 0 )
1495            {
1496                cnt1++;
1497                temp = temp >> 1;
1498            }
1499            cnt1++;
1500            lClipPPSRemBits -= cnt1;
1501
1502            lSize1 = instance->m_encoderPPSSize - 1;
1503            p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1);
1504            DecBitStreamReset_MCS(p_bs1, lSize1);
1505
1506            lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1507            lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1508
1509            lEncoderPPSRemBits = ( lSize1) << 3;
1510            lEncoderPPSRemBits -= p_bs1->bitPos;
1511
1512            temp = instance->m_pEncoderPPS[lSize1];
1513
1514            cnt1 = 0;
1515
1516            while( ( temp & 0x1) == 0 )
1517            {
1518                cnt1++;
1519                temp = temp >> 1;
1520            }
1521            cnt1++;
1522            lEncoderPPSRemBits -= cnt1;
1523
1524            if( lEncoderPPSRemBits == lClipPPSRemBits )
1525            {
1526                while( lEncoderPPSRemBits > 8 )
1527                {
1528                    temp1 = H264MCS_getBits(p_bs, 8);
1529                    temp2 = H264MCS_getBits(p_bs1, 8);
1530                    lEncoderPPSRemBits = lEncoderPPSRemBits - 8;
1531
1532                    if( temp1 != temp2 )
1533                    {
1534                        break;
1535                    }
1536                }
1537
1538                if( lEncoderPPSRemBits < 8 )
1539                {
1540                    if( lEncoderPPSRemBits )
1541                    {
1542                        temp1 = H264MCS_getBits(p_bs, lEncoderPPSRemBits);
1543                        temp2 = H264MCS_getBits(p_bs1, lEncoderPPSRemBits);
1544
1545                        if( temp1 == temp2 )
1546                        {
1547                            lFound = 1;
1548                        }
1549                    }
1550                    else
1551                    {
1552                        lFound = 1;
1553                    }
1554                }
1555                break;
1556            }
1557        }
1558
1559        lClipDSI = lClipDSI + lSize;
1560    }
1561
1562    /* Form the final SPS and PPS data */
1563
1564    if( lFound == 1 )
1565    {
1566        /* No need to add PPS */
1567        instance->final_PPS_ID = Clip_PPSID[cnt];
1568
1569        instance->m_pFinalDSI =
1570            (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(instance->m_decoderSpecificInfoSize,
1571            M4MCS, (M4OSA_Char *)"instance->m_pFinalDSI");
1572
1573        if( instance->m_pFinalDSI == M4OSA_NULL )
1574        {
1575            M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
1576            return M4ERR_ALLOC;
1577        }
1578
1579        instance->m_pFinalDSISize = instance->m_decoderSpecificInfoSize;
1580        memcpy((void *)instance->m_pFinalDSI,
1581            (void *)instance->m_pDecoderSpecificInfo,
1582            instance->m_decoderSpecificInfoSize);
1583    }
1584    else
1585    {
1586        /* ADD PPS */
1587        /* find the free PPS ID */
1588
1589        cnt = 0;
1590
1591        while( Clip_UsedPPSID[cnt] )
1592        {
1593            cnt++;
1594        }
1595        instance->final_PPS_ID = cnt;
1596
1597        size = instance->m_decoderSpecificInfoSize + instance->m_encoderPPSSize
1598            + 10;
1599
1600        instance->m_pFinalDSI = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(size, M4MCS,
1601            (M4OSA_Char *)"instance->m_pFinalDSI");
1602
1603        if( instance->m_pFinalDSI == M4OSA_NULL )
1604        {
1605            M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
1606            return M4ERR_ALLOC;
1607        }
1608
1609        memcpy((void *)instance->m_pFinalDSI,
1610            (void *)instance->m_pDecoderSpecificInfo,
1611            instance->m_decoderSpecificInfoSize);
1612
1613        temp = instance->m_pFinalDSI[lClipDSI_PPS_offset];
1614        temp = temp + 1;
1615        instance->m_pFinalDSI[lClipDSI_PPS_offset] = temp;
1616
1617        //temp = instance->m_pEncoderPPS[0];
1618        lSize1 = instance->m_encoderPPSSize - 1;
1619        p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1);
1620        DecBitStreamReset_MCS(p_bs1, lSize1);
1621
1622        lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1623        lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1624
1625        lEncoderPPSRemBits = ( lSize1) << 3;
1626        lEncoderPPSRemBits -= p_bs1->bitPos;
1627
1628        temp = instance->m_pEncoderPPS[lSize1];
1629
1630        cnt1 = 0;
1631
1632        while( ( temp & 0x1) == 0 )
1633        {
1634            cnt1++;
1635            temp = temp >> 1;
1636        }
1637        cnt1++;
1638        lEncoderPPSRemBits -= cnt1;
1639
1640        instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 2] =
1641            instance->m_pEncoderPPS[0];
1642
1643        NSWAVCMCS_initBitstream(&instance->encbs);
1644        instance->encbs.streamBuffer =
1645            &(instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 3]);
1646        lPPS_Buffer = instance->encbs.streamBuffer;
1647
1648        NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_PPS_ID);
1649        NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_SPS_ID);
1650
1651        while( lEncoderPPSRemBits > 8 )
1652        {
1653            temp = H264MCS_getBits(p_bs1, 8);
1654            NSWAVCMCS_putBits(&instance->encbs, temp, 8);
1655            lEncoderPPSRemBits = lEncoderPPSRemBits - 8;
1656        }
1657
1658        if( lEncoderPPSRemBits )
1659        {
1660            temp = H264MCS_getBits(p_bs1, lEncoderPPSRemBits);
1661            NSWAVCMCS_putBits(&instance->encbs, temp, lEncoderPPSRemBits);
1662        }
1663        NSWAVCMCS_putRbspTbits(&instance->encbs);
1664
1665        temp = instance->encbs.byteCnt;
1666        lPPS_Buffer_Size = temp;
1667        temp = temp + 1;
1668
1669        instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize] =
1670            ( temp >> 8) & 0xFF;
1671        instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 1] =
1672            (temp) &0xFF;
1673        instance->m_pFinalDSISize =
1674            instance->m_decoderSpecificInfoSize + 2 + temp;
1675    }
1676
1677    /* Decode the clip SPS */
1678
1679    lClipDSI = instance->m_pDecoderSpecificInfo + 6;
1680
1681    lClipDSI_PPS_offset = 6;
1682
1683    for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ )
1684    {
1685        lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1686        lClipDSI = lClipDSI + 2;
1687
1688        if( Clip_SPSID[cnt] == instance->final_SPS_ID )
1689        {
1690            p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1691            DecBitStreamReset_MCS(p_bs, lSize - 1);
1692
1693            DecSPSMCS(p_bs, &instance->clip_sps);
1694
1695            //Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1696            //Clip_UsedSPSID[Clip_SPSID[cnt]] = 1;
1697            break;
1698        }
1699
1700        lClipDSI = lClipDSI + lSize;
1701    }
1702
1703    /* Decode encoder SPS */
1704    p_bs->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderSPS + 1);
1705    DecBitStreamReset_MCS(p_bs, instance->m_encoderSPSSize - 1);
1706    DecSPSMCS(p_bs, &instance->encoder_sps);
1707
1708    if( instance->encoder_sps.num_ref_frames
1709    > instance->clip_sps.num_ref_frames )
1710    {
1711        return 100; //not supported
1712    }
1713
1714    p_bs->Buffer = (M4OSA_UInt8 *)lPPS_Buffer;
1715    DecBitStreamReset_MCS(p_bs, lPPS_Buffer_Size);
1716    DecPPSMCS(p_bs, &instance->encoder_pps);
1717
1718    instance->frame_count = 0;
1719    instance->frame_mod_count =
1720        1 << (instance->clip_sps.log2_max_frame_num_minus4 + 4);
1721
1722    instance->POC_lsb = 0;
1723    instance->POC_lsb_mod =
1724        1 << (instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
1725
1726    return M4NO_ERROR;
1727}
1728
1729M4OSA_ERR H264MCS_ProcessNALU( NSWAVC_MCS_t *ainstance, M4OSA_UInt8 *inbuff,
1730                               M4OSA_Int32 inbuf_size, M4OSA_UInt8 *outbuff,
1731                               M4OSA_Int32 *outbuf_size )
1732{
1733    ComBitStreamMCS_t *p_bs, bs;
1734    NSWAVC_MCS_t *instance;
1735    M4OSA_UInt8 nalu_info;
1736    M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
1737    M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num;
1738    M4OSA_Int32 seq_parameter_set_id;
1739    M4OSA_UInt8 temp1, temp2, temp3, temp4;
1740    M4OSA_Int32 temp_frame_num;
1741    M4OSA_Int32 bitstoDiacard, bytes;
1742    M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
1743    M4OSA_Int32 new_bytes, init_bit_pos;
1744    M4OSA_UInt32 nal_size;
1745    M4OSA_UInt32 cnt;
1746    M4OSA_UInt32 outbuffpos = 0;
1747    //#ifndef DGR_FIX // + new
1748    M4OSA_UInt32 nal_size_low16, nal_size_high16;
1749    //#endif // + end new
1750    M4OSA_UInt32 frame_size = 0;
1751    M4OSA_UInt32 temp = 0;
1752    M4OSA_ERR err = M4NO_ERROR;
1753    M4OSA_UInt8 *buff;
1754
1755    p_bs = &bs;
1756    instance = (NSWAVC_MCS_t *)ainstance;
1757    M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
1758        "H264MCS_ProcessNALU: instance is M4OSA_NULL");
1759
1760    if( instance->is_done )
1761        return err;
1762
1763    inbuff[0] = 0x00;
1764    inbuff[1] = 0x00;
1765    inbuff[2] = 0x00;
1766    inbuff[3] = 0x01;
1767
1768
1769    while( (M4OSA_Int32)frame_size < inbuf_size )
1770    {
1771        mask_bits = 0xFFFFFFFF;
1772        p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
1773
1774
1775        nalu_info = (unsigned char)p_bs->Buffer[4];
1776
1777        outbuff[outbuffpos] = p_bs->Buffer[0];
1778        outbuff[outbuffpos + 1] = p_bs->Buffer[1];
1779        outbuff[outbuffpos + 2] = p_bs->Buffer[2];
1780        outbuff[outbuffpos + 3] = p_bs->Buffer[3];
1781        outbuff[outbuffpos + 4] = p_bs->Buffer[4];
1782
1783        p_bs->Buffer = p_bs->Buffer + 5;
1784
1785        p_bs->bitPos = 0;
1786        p_bs->lastTotalBits = 0;
1787        p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3;
1788        p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5;
1789
1790        p_bs->ui32TempBuff = 0;
1791        p_bs->i8BitCnt = 0;
1792        p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
1793        p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
1794
1795        H264MCS_getBits(p_bs, 0);
1796
1797
1798
1799        nal_size = inbuf_size - frame_size - 4;
1800        buff = inbuff + frame_size + 4;
1801
1802        while( nal_size > 4 )
1803        {
1804            if( ( buff[0] == 0x00) && (buff[1] == 0x00) && (buff[2] == 0x00)
1805                && (buff[3] == 0x01) )
1806            {
1807                break;
1808            }
1809            buff = buff + 1;
1810            nal_size = nal_size - 1;
1811        }
1812
1813        if( nal_size <= 4 )
1814        {
1815            nal_size = 0;
1816        }
1817        nal_size = ( inbuf_size - frame_size - 4) - nal_size;
1818
1819        //      M4OSA_TRACE1_3("H264MCS_ProcessNALU frame  input buff size = %d  current position
1820        //= %d   nal size = %d",
1821        //  inbuf_size, frame_size,  nal_size + 4);
1822        frame_size += nal_size + 4;
1823
1824
1825
1826        forbidden_bit = ( nalu_info >> 7) & 1;
1827        nal_ref_idc = ( nalu_info >> 5) & 3;
1828        nal_unit_type = (nalu_info) &0x1f;
1829
1830        if( nal_unit_type == 5 )
1831        {
1832            /*IDR/PPS Packet - Do nothing*/
1833            instance->is_done = 1;
1834            return err;
1835        }
1836
1837        NSWAVCMCS_initBitstream(&instance->encbs);
1838        instance->encbs.streamBuffer = outbuff + outbuffpos + 5;
1839
1840        if( nal_unit_type == 8 )
1841        {
1842            M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: PPS");
1843            return err;
1844        }
1845
1846        if( nal_unit_type == 7 )
1847        {
1848            /*SPS Packet */
1849            M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: SPS");
1850            return 0;
1851        }
1852
1853        if( (nal_unit_type == 5) )
1854        {
1855            instance->frame_count = 0;
1856            instance->POC_lsb = 0;
1857        }
1858
1859        if( (nal_unit_type == 1) )
1860        {
1861            first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
1862            NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice);
1863
1864            slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
1865            NSWAVCMCS_uExpVLC(&instance->encbs, slice_type);
1866
1867            pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1868            NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id);
1869
1870            temp = H264MCS_getBits(p_bs,
1871                instance->clip_sps.log2_max_frame_num_minus4 + 4);
1872            NSWAVCMCS_putBits(&instance->encbs, instance->frame_count,
1873                instance->clip_sps.log2_max_frame_num_minus4 + 4);
1874
1875            // In Baseline Profile: frame_mbs_only_flag should be ON
1876
1877            if( nal_unit_type == 5 )
1878            {
1879                temp = H264MCS_DecVLCReadExpGolombCode(p_bs);
1880                NSWAVCMCS_uExpVLC(&instance->encbs, temp);
1881            }
1882
1883            if( instance->clip_sps.pic_order_cnt_type == 0 )
1884            {
1885                temp = H264MCS_getBits(p_bs,
1886                    instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4
1887                    + 4);
1888                NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb,
1889                    instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
1890            }
1891
1892            if( ( instance->clip_sps.pic_order_cnt_type == 1)
1893                && (instance->clip_sps.delta_pic_order_always_zero_flag) )
1894            {
1895                temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1896                NSWAVCMCS_sExpVLC(&instance->encbs, temp);
1897            }
1898
1899            cnt = p_bs->bitPos & 0x7;
1900
1901            if( cnt )
1902            {
1903                cnt = 8 - cnt;
1904                temp = H264MCS_getBits(p_bs, cnt);
1905                NSWAVCMCS_putBits(&instance->encbs, temp, cnt);
1906            }
1907
1908            cnt = p_bs->bitPos >> 3;
1909
1910            while( cnt < (nal_size - 2) )
1911            {
1912                temp = H264MCS_getBits(p_bs, 8);
1913                NSWAVCMCS_putBits(&instance->encbs, temp, 8);
1914                cnt = p_bs->bitPos >> 3;
1915            }
1916
1917            temp = H264MCS_getBits(p_bs, 8);
1918
1919            if( temp != 0 )
1920            {
1921                cnt = 0;
1922
1923                while( ( temp & 0x1) == 0 )
1924                {
1925                    cnt++;
1926                    temp = temp >> 1;
1927                }
1928                cnt++;
1929                temp = temp >> 1;
1930
1931                if( 8 - cnt )
1932                {
1933                    NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt));
1934                }
1935
1936                NSWAVCMCS_putRbspTbits(&instance->encbs);
1937            }
1938            else
1939            {
1940                if( instance->encbs.bitPos % 8 )
1941                {
1942                    NSWAVCMCS_putBits(&instance->encbs, 0,
1943                        (8 - instance->encbs.bitPos % 8));
1944                }
1945            }
1946
1947            temp = instance->encbs.byteCnt;
1948            temp = temp + 1;
1949
1950            outbuff[outbuffpos] = (M4OSA_UInt8)(( temp >> 24) & 0xFF);
1951            outbuff[outbuffpos + 1] = (M4OSA_UInt8)(( temp >> 16) & 0xFF);
1952            outbuff[outbuffpos + 2] = (M4OSA_UInt8)(( temp >> 8) & 0xFF);
1953            outbuff[outbuffpos + 3] = (M4OSA_UInt8)((temp) &0xFF);
1954            outbuffpos = outbuffpos + temp + 4;
1955        }
1956        else
1957        {
1958            p_bs->Buffer = p_bs->Buffer - 5;
1959            memcpy((void *) &outbuff[outbuffpos],
1960                (void *)p_bs->Buffer, nal_size + 4);
1961
1962            outbuff[outbuffpos] = (M4OSA_UInt8)((nal_size >> 24)& 0xFF);
1963        outbuff[outbuffpos + 1] = (M4OSA_UInt8)((nal_size >> 16)& 0xFF);;
1964        outbuff[outbuffpos + 2] = (M4OSA_UInt8)((nal_size >> 8)& 0xFF);;
1965        outbuff[outbuffpos + 3] = (M4OSA_UInt8)((nal_size)& 0xFF);;
1966
1967            outbuffpos = outbuffpos + nal_size + 4;
1968        }
1969    }
1970
1971    *outbuf_size = outbuffpos;
1972
1973    instance->POC_lsb = instance->POC_lsb + 1;
1974
1975    if( instance->POC_lsb == instance->POC_lsb_mod )
1976    {
1977        instance->POC_lsb = 0;
1978    }
1979    instance->frame_count = instance->frame_count + 1;
1980
1981    if( instance->frame_count == instance->frame_mod_count )
1982    {
1983        instance->frame_count = 0;
1984    }
1985    return M4NO_ERROR;
1986}
1987
1988M4OSA_ERR   M4MCS_convetFromByteStreamtoNALStream(  M4OSA_UInt8 *inbuff,
1989                                                    M4OSA_UInt32 inbuf_size )
1990{
1991    M4OSA_ERR err = M4NO_ERROR;
1992    M4OSA_UInt32 framesize = 0;
1993    M4OSA_UInt32 nal_size =0;
1994    M4OSA_UInt8 *buff;
1995
1996
1997    while(framesize < inbuf_size)
1998    {
1999            nal_size = inbuf_size - framesize - 4;
2000            buff =  inbuff + framesize + 4;
2001
2002            while(nal_size > 4){
2003                if((buff[0] == 0x00) &&
2004                (buff[1] == 0x00) &&
2005                (buff[2] == 0x00) &&
2006                (buff[3] == 0x01)){
2007                    break;
2008                }
2009                buff = buff + 1;
2010                nal_size = nal_size -1;
2011            }
2012
2013            if(nal_size <= 4){
2014                nal_size = 0;
2015            }
2016            nal_size = (inbuf_size - framesize - 4) - nal_size;
2017
2018        inbuff[framesize + 0]  = (M4OSA_UInt8)((nal_size >> 24)& 0xFF);
2019        inbuff[framesize + 1]  = (M4OSA_UInt8)((nal_size >> 16)& 0xFF);
2020        inbuff[framesize + 2]  = (M4OSA_UInt8)((nal_size >> 8)& 0xFF);
2021        inbuff[framesize + 3]  = (M4OSA_UInt8)((nal_size )& 0xFF);
2022        framesize += nal_size + 4;
2023
2024        M4OSA_TRACE1_2("M4MCS_convetFromByteStreamtoNALStream framesize = %x nalsize = %x",
2025            framesize, nal_size)
2026    }
2027
2028    return  err;
2029}
2030
2031
2032M4OSA_ERR H264MCS_Freeinstance( NSWAVC_MCS_t *instance )
2033{
2034    M4OSA_ERR err = M4NO_ERROR;
2035    M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
2036        "H264MCS_Freeinstance: instance is M4OSA_NULL");
2037
2038    if( M4OSA_NULL != instance->encoder_pps.slice_group_id )
2039    {
2040        free(instance->encoder_pps.slice_group_id);
2041    }
2042
2043    if( M4OSA_NULL != instance->p_encoder_sps )
2044    {
2045        free(instance->p_encoder_sps);
2046        instance->p_encoder_sps = M4OSA_NULL;
2047    }
2048
2049    if( M4OSA_NULL != instance->p_encoder_pps )
2050    {
2051        free(instance->p_encoder_pps);
2052        instance->p_encoder_pps = M4OSA_NULL;
2053    }
2054
2055    if( M4OSA_NULL != instance->m_pFinalDSI )
2056    {
2057        free(instance->m_pFinalDSI);
2058        instance->m_pFinalDSI = M4OSA_NULL;
2059    }
2060
2061    if( M4OSA_NULL != instance )
2062    {
2063        free(instance);
2064        instance = M4OSA_NULL;
2065    }
2066
2067    return err;
2068}
2069/**
2070 ******************************************************************************
2071 * M4OSA_ERR M4MCS_getVersion(M4_VersionInfo* pVersionInfo);
2072 * @brief    Get the MCS version.
2073 * @note Can be called anytime. Do not need any context.
2074 * @param    pVersionInfo        (OUT) Pointer to a version info structure
2075 * @return   M4NO_ERROR:         No error
2076 * @return   M4ERR_PARAMETER:    pVersionInfo is M4OSA_NULL (If Debug Level >= 2)
2077 ******************************************************************************
2078 */
2079M4OSA_ERR M4MCS_getVersion( M4_VersionInfo *pVersionInfo )
2080{
2081    M4OSA_TRACE3_1("M4MCS_getVersion called with pVersionInfo=0x%x",
2082        pVersionInfo);
2083
2084    /**
2085    * Check input parameters */
2086    M4OSA_DEBUG_IF2((M4OSA_NULL == pVersionInfo), M4ERR_PARAMETER,
2087        "M4MCS_getVersion: pVersionInfo is M4OSA_NULL");
2088
2089    pVersionInfo->m_major = M4MCS_VERSION_MAJOR;
2090    pVersionInfo->m_minor = M4MCS_VERSION_MINOR;
2091    pVersionInfo->m_revision = M4MCS_VERSION_REVISION;
2092
2093    /**
2094    * Return with no error */
2095    M4OSA_TRACE3_0("M4MCS_getVersion(): returning M4NO_ERROR");
2096    return M4NO_ERROR;
2097}
2098
2099/**
2100 ******************************************************************************
2101 * @brief    Initializes the MCS (allocates an execution context).
2102 * @note
2103 * @param    pContext            (OUT) Pointer on the MCS context to allocate
2104 * @param    pFileReadPtrFct     (IN) Pointer to OSAL file reader functions
2105 * @param    pFileWritePtrFct    (IN) Pointer to OSAL file writer functions
2106 * @return   M4NO_ERROR:         No error
2107 * @return   M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (If Debug Level >= 2)
2108 * @return   M4ERR_ALLOC:        There is no more available memory
2109 ******************************************************************************
2110 */
2111
2112M4OSA_ERR M4MCS_init( M4MCS_Context *pContext,
2113                     M4OSA_FileReadPointer *pFileReadPtrFct,
2114                     M4OSA_FileWriterPointer *pFileWritePtrFct )
2115{
2116    M4MCS_InternalContext *pC = M4OSA_NULL;
2117    M4OSA_ERR err;
2118
2119    M4OSA_TRACE3_3(
2120        "M4MCS_init called with pContext=0x%x, pFileReadPtrFct=0x%x, pFileWritePtrFct=0x%x",
2121        pContext, pFileReadPtrFct, pFileWritePtrFct);
2122
2123    /**
2124    * Check input parameters */
2125    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2126        "M4MCS_init: pContext is M4OSA_NULL");
2127    M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER,
2128        "M4MCS_init: pFileReadPtrFct is M4OSA_NULL");
2129    M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWritePtrFct), M4ERR_PARAMETER,
2130        "M4MCS_init: pFileWritePtrFct is M4OSA_NULL");
2131
2132    /**
2133    * Allocate the MCS context and return it to the user */
2134    pC = (M4MCS_InternalContext *)M4OSA_32bitAlignedMalloc(sizeof(M4MCS_InternalContext),
2135        M4MCS, (M4OSA_Char *)"M4MCS_InternalContext");
2136    *pContext = pC;
2137
2138    if( M4OSA_NULL == pC )
2139    {
2140        M4OSA_TRACE1_0(
2141            "M4MCS_init(): unable to allocate M4MCS_InternalContext, returning M4ERR_ALLOC");
2142        return M4ERR_ALLOC;
2143    }
2144
2145    /**
2146    * Init the context. All pointers must be initialized to M4OSA_NULL
2147    * because CleanUp() can be called just after Init(). */
2148    pC->State = M4MCS_kState_CREATED;
2149    pC->pOsaFileReadPtr = pFileReadPtrFct;
2150    pC->pOsaFileWritPtr = pFileWritePtrFct;
2151    pC->VideoState = M4MCS_kStreamState_NOSTREAM;
2152    pC->AudioState = M4MCS_kStreamState_NOSTREAM;
2153    pC->noaudio = M4OSA_FALSE;
2154    pC->novideo = M4OSA_FALSE;
2155    pC->uiProgress = 0;
2156
2157    /**
2158    * Reader stuff */
2159    pC->pInputFile = M4OSA_NULL;
2160    pC->InputFileType = M4VIDEOEDITING_kFileType_Unsupported;
2161    pC->bFileOpenedInFastMode = M4OSA_FALSE;
2162    pC->pReaderContext = M4OSA_NULL;
2163    pC->pReaderVideoStream = M4OSA_NULL;
2164    pC->pReaderAudioStream = M4OSA_NULL;
2165    pC->bUnsupportedVideoFound = M4OSA_FALSE;
2166    pC->bUnsupportedAudioFound = M4OSA_FALSE;
2167    pC->iAudioCtsOffset = 0;
2168    /* First temporary video AU to have more precise end video cut*/
2169    pC->ReaderVideoAU1.m_structSize = 0;
2170    /* Second temporary video AU to have more precise end video cut*/
2171    pC->ReaderVideoAU2.m_structSize = 0;
2172    pC->ReaderAudioAU1.m_structSize = 0;
2173    pC->ReaderAudioAU2.m_structSize = 0;
2174    pC->m_audioAUDuration = 0;
2175    pC->m_pDataAddress1 = M4OSA_NULL;
2176    pC->m_pDataAddress2 = M4OSA_NULL;
2177    /* First temporary video AU data to have more precise end video cut*/
2178    pC->m_pDataVideoAddress1 = M4OSA_NULL;
2179    /* Second temporary video AU data to have more precise end video cut*/
2180    pC->m_pDataVideoAddress2 = M4OSA_NULL;
2181
2182    /**
2183    * Video decoder stuff */
2184    pC->pViDecCtxt = M4OSA_NULL;
2185    pC->dViDecStartingCts = 0.0;
2186    pC->iVideoBeginDecIncr = 0;
2187    pC->dViDecCurrentCts = 0.0;
2188    pC->dCtsIncrement = 0.0;
2189    pC->isRenderDup = M4OSA_FALSE;
2190
2191    /**
2192    * Video encoder stuff */
2193    pC->pViEncCtxt = M4OSA_NULL;
2194    pC->pPreResizeFrame = M4OSA_NULL;
2195    pC->uiEncVideoBitrate = 0;
2196    pC->bActivateEmp = M4OSA_FALSE;
2197    pC->encoderState = M4MCS_kNoEncoder;
2198
2199    /**
2200    * Audio decoder stuff */
2201    pC->pAudioDecCtxt = M4OSA_NULL;
2202    pC->AudioDecBufferIn.m_dataAddress = M4OSA_NULL;
2203    pC->AudioDecBufferIn.m_bufferSize = 0;
2204    pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
2205    pC->AudioDecBufferOut.m_bufferSize = 0;
2206    pC->pPosInDecBufferOut = M4OSA_NULL;
2207    /**
2208    * Ssrc stuff */
2209    pC->pSsrcBufferIn = M4OSA_NULL;
2210    pC->pSsrcBufferOut = M4OSA_NULL;
2211    pC->pPosInSsrcBufferIn = M4OSA_NULL;
2212    pC->pPosInSsrcBufferOut = M4OSA_NULL;
2213    pC->iSsrcNbSamplIn = 0;
2214    pC->iSsrcNbSamplOut = 0;
2215    pC->SsrcScratch = M4OSA_NULL;
2216    pC->pLVAudioResampler = M4OSA_NULL;
2217    /**
2218    * Audio encoder */
2219    pC->pAudioEncCtxt = M4OSA_NULL;
2220    pC->pAudioEncDSI.infoSize = 0;
2221    pC->pAudioEncDSI.pInfo = M4OSA_NULL;
2222    pC->pAudioEncoderBuffer = M4OSA_NULL;
2223    pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
2224    pC->audioEncoderGranularity = 0;
2225
2226    /**
2227    * Writer stuff */
2228    pC->pOutputFile = M4OSA_NULL;
2229    pC->pTemporaryFile = M4OSA_NULL;
2230    pC->pWriterContext = M4OSA_NULL;
2231    pC->uiVideoAUCount = 0;
2232    pC->uiVideoMaxAuSize = 0;
2233    pC->uiVideoMaxChunckSize = 0;
2234    pC->uiAudioAUCount = 0;
2235    pC->uiAudioMaxAuSize = 0;
2236
2237    pC->uiAudioCts = 0;
2238    pC->b_isRawWriter = M4OSA_FALSE;
2239    pC->pOutputPCMfile = M4OSA_NULL;
2240
2241    /* Encoding config */
2242    pC->EncodingVideoFormat = M4ENCODER_kNULL; /**< No format set yet */
2243    pC->EncodingWidth = 0;                     /**< No size set yet */
2244    pC->EncodingHeight = 0;                    /**< No size set yet */
2245    pC->EncodingVideoFramerate = 0;            /**< No framerate set yet */
2246
2247    pC->uiBeginCutTime = 0;                    /**< No begin cut */
2248    pC->uiEndCutTime = 0;                      /**< No end cut */
2249    pC->uiMaxFileSize = 0;                     /**< No limit */
2250    pC->uiAudioBitrate =
2251        M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */
2252    pC->uiVideoBitrate =
2253        M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */
2254
2255    pC->WriterVideoStream.streamType = M4SYS_kVideoUnknown;
2256    pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL;
2257    pC->WriterAudioStream.streamType = M4SYS_kAudioUnknown;
2258
2259    pC->outputVideoTimescale = 0;
2260
2261    /*FB 2008/10/20: add media rendering parameter and AIR context to keep media aspect ratio*/
2262    pC->MediaRendering = M4MCS_kResizing;
2263    pC->m_air_context = M4OSA_NULL;
2264    /**/
2265
2266    /**
2267    * FlB 2009.03.04: add audio Effects*/
2268    pC->pEffects = M4OSA_NULL;
2269    pC->nbEffects = 0;
2270    pC->pActiveEffectNumber = -1;
2271    /**/
2272
2273    /*
2274    * Reset pointers for media and codecs interfaces */
2275    err = M4MCS_clearInterfaceTables(pC);
2276    M4ERR_CHECK_RETURN(err);
2277
2278    /*
2279    *  Call the media and codecs subscription module */
2280    err = M4MCS_subscribeMediaAndCodec(pC);
2281    M4ERR_CHECK_RETURN(err);
2282
2283#ifdef M4MCS_SUPPORT_STILL_PICTURE
2284    /**
2285    * Initialize the Still picture part of MCS*/
2286
2287    err = M4MCS_stillPicInit(pC, pFileReadPtrFct, pFileWritePtrFct);
2288    M4ERR_CHECK_RETURN(err);
2289
2290    pC->m_bIsStillPicture = M4OSA_FALSE;
2291
2292#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2293
2294    pC->m_pInstance = M4OSA_NULL;
2295    pC->H264MCSTempBuffer = M4OSA_NULL;
2296    pC->H264MCSTempBufferSize = 0;
2297    pC->H264MCSTempBufferDataSize = 0;
2298    pC->bH264Trim = M4OSA_FALSE;
2299
2300    /* Flag to get the last decoded frame cts */
2301    pC->bLastDecodedFrameCTS = M4OSA_FALSE;
2302
2303    if( pC->m_pInstance == M4OSA_NULL )
2304    {
2305        err = H264MCS_Getinstance(&pC->m_pInstance);
2306    }
2307    pC->bExtOMXAudDecoder = M4OSA_FALSE;
2308
2309    /**
2310    * Return with no error */
2311    M4OSA_TRACE3_0("M4MCS_init(): returning M4NO_ERROR");
2312    return M4NO_ERROR;
2313}
2314
2315/**
2316 ******************************************************************************
2317 * M4OSA_ERR M4MCS_open(M4MCS_Context pContext, M4OSA_Void* pFileIn,
2318 *                         M4OSA_Void* pFileOut, M4OSA_Void* pTempFile);
2319 * @brief   Set the MCS input and output files.
2320 * @note    It opens the input file, but the output file is not created yet.
2321 * @param   pContext            (IN) MCS context
2322 * @param   pFileIn             (IN) Input file to transcode (The type of this parameter
2323 *                                 (URL, pipe...) depends on the OSAL implementation).
2324 * @param   mediaType           (IN) Container type (.3gp,.amr,mp3 ...) of input file.
2325 * @param   pFileOut            (IN) Output file to create  (The type of this parameter
2326 *                                    (URL, pipe...) depends on the OSAL implementation).
2327 * @param   pTempFile           (IN) Temporary file for the constant memory writer to
2328 *                                     store metadata ("moov.bin").
2329 * @return  M4NO_ERROR:         No error
2330 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
2331 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2332 * @return  M4ERR_ALLOC:        There is no more available memory
2333 * @return  M4ERR_FILE_NOT_FOUND:   The input file has not been found
2334 * @return  M4MCS_ERR_INVALID_INPUT_FILE:   The input file is not a valid file, or is corrupted
2335 * @return  M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM:  The input file contains no
2336 *                                supported audio or video stream
2337 ******************************************************************************
2338 */
2339M4OSA_ERR M4MCS_open( M4MCS_Context pContext, M4OSA_Void *pFileIn,
2340                     M4VIDEOEDITING_FileType InputFileType, M4OSA_Void *pFileOut,
2341                     M4OSA_Void *pTempFile )
2342{
2343    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2344    M4OSA_ERR err;
2345
2346    M4READER_MediaFamily mediaFamily;
2347    M4_StreamHandler *pStreamHandler;
2348
2349    M4OSA_TRACE2_3(
2350        "M4MCS_open called with pContext=0x%x, pFileIn=0x%x, pFileOut=0x%x",
2351        pContext, pFileIn, pFileOut);
2352
2353    /**
2354    * Check input parameters */
2355    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2356        "M4MCS_open: pContext is M4OSA_NULL");
2357    M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn), M4ERR_PARAMETER,
2358        "M4MCS_open: pFileIn is M4OSA_NULL");
2359
2360    if( ( InputFileType == M4VIDEOEDITING_kFileType_JPG)
2361        || (InputFileType == M4VIDEOEDITING_kFileType_PNG)
2362        || (InputFileType == M4VIDEOEDITING_kFileType_GIF)
2363        || (InputFileType == M4VIDEOEDITING_kFileType_BMP) )
2364    {
2365#ifdef M4MCS_SUPPORT_STILL_PICTURE
2366        /**
2367        * Indicate that we must use the still picture functions*/
2368
2369        pC->m_bIsStillPicture = M4OSA_TRUE;
2370
2371        /**
2372        * Call the still picture MCS functions*/
2373        return M4MCS_stillPicOpen(pC, pFileIn, InputFileType, pFileOut);
2374
2375#else
2376
2377        M4OSA_TRACE1_0(
2378            "M4MCS_open: Still picture is not supported with this version of MCS");
2379        return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
2380
2381#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2382
2383    }
2384
2385    /**
2386    * Check state automaton */
2387    if( M4MCS_kState_CREATED != pC->State )
2388    {
2389        M4OSA_TRACE1_1("M4MCS_open(): Wrong State (%d), returning M4ERR_STATE",
2390            pC->State);
2391        return M4ERR_STATE;
2392    }
2393
2394    /* Copy function input parameters into our context */
2395    pC->pInputFile = pFileIn;
2396    pC->InputFileType = InputFileType;
2397    pC->pOutputFile = pFileOut;
2398    pC->pTemporaryFile = pTempFile;
2399    pC->uiProgress = 0;
2400
2401    /***********************************/
2402    /* Open input file with the reader */
2403    /***********************************/
2404
2405    err = M4MCS_setCurrentReader(pContext, pC->InputFileType);
2406    M4ERR_CHECK_RETURN(err);
2407
2408    /**
2409    * Reset reader related variables */
2410    pC->VideoState = M4MCS_kStreamState_NOSTREAM;
2411    pC->AudioState = M4MCS_kStreamState_NOSTREAM;
2412    pC->pReaderVideoStream = M4OSA_NULL;
2413    pC->pReaderAudioStream = M4OSA_NULL;
2414
2415    /*******************************************************/
2416    /* Initializes the reader shell and open the data file */
2417    /*******************************************************/
2418    err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext);
2419
2420    if( M4NO_ERROR != err )
2421    {
2422        M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctCreate returns 0x%x",
2423            err);
2424        return err;
2425    }
2426
2427    /**
2428    * Link the reader interface to the reader context */
2429    pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext;
2430
2431    /**
2432    * Set the reader shell file access functions */
2433    err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2434        M4READER_kOptionID_SetOsaFileReaderFctsPtr,
2435        (M4OSA_DataOption)pC->pOsaFileReadPtr);
2436
2437    if( M4NO_ERROR != err )
2438    {
2439        M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctSetOption returns 0x%x",
2440            err);
2441        return err;
2442    }
2443
2444#ifdef M4MCS_WITH_FAST_OPEN
2445
2446    if( M4OSA_FALSE == pC->bFileOpenedInFastMode )
2447    {
2448        M4OSA_Bool trueValue = M4OSA_TRUE;
2449
2450        /* For first call use fast open mode */
2451        err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2452            M4READER_3GP_kOptionID_FastOpenMode, &trueValue);
2453
2454        if( M4NO_ERROR == err )
2455        {
2456            pC->bFileOpenedInFastMode = M4OSA_TRUE;
2457        }
2458        else
2459        {
2460            M4OSA_TRACE1_1(
2461                "M4MCS_open(): M4READER_3GP_kOptionID_FastOpenMode returns 0x%x",
2462                err);
2463
2464            if( ( ( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) == err)
2465                || (( (M4OSA_UInt32)M4ERR_PARAMETER) == err) )
2466            {
2467                /* Not fatal, some readers may not support fast open mode */
2468                pC->bFileOpenedInFastMode = M4OSA_FALSE;
2469            }
2470            else
2471                return err;
2472        }
2473    }
2474    else
2475    {
2476        M4OSA_Bool falseValue = M4OSA_FALSE;
2477
2478        /* For second call use normal open mode */
2479        err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2480            M4READER_3GP_kOptionID_FastOpenMode, &falseValue);
2481    }
2482
2483#endif /* M4MCS_WITH_FAST_OPEN */
2484
2485    /**
2486    * Open the input file */
2487
2488    err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile);
2489
2490    if( M4NO_ERROR != err )
2491    {
2492        M4OSA_UInt32 uiDummy, uiCoreId;
2493        M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctOpen returns 0x%x", err);
2494
2495        /**
2496        * If the error is from the core reader, we change it to a public VXS error */
2497        M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
2498
2499        if( M4MP4_READER == uiCoreId )
2500        {
2501            M4OSA_TRACE1_0(
2502                "M4MCS_open(): returning M4MCS_ERR_INVALID_INPUT_FILE");
2503            return M4MCS_ERR_INVALID_INPUT_FILE;
2504        }
2505        return err;
2506    }
2507
2508    /**
2509    * Get the streams from the input file */
2510    while( M4NO_ERROR == err )
2511    {
2512        err =
2513            pC->m_pReader->m_pFctGetNextStream( pC->pReaderContext,
2514                                                &mediaFamily,
2515                                                &pStreamHandler);
2516
2517        /**
2518        * In case we found a BIFS stream or something else...*/
2519        if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
2520            || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) )
2521        {
2522            err = M4NO_ERROR;
2523            continue;
2524        }
2525
2526        if( M4NO_ERROR == err ) /**< One stream found */
2527        {
2528            /**
2529            * Found the first video stream */
2530            if( ( M4READER_kMediaFamilyVideo == mediaFamily)
2531                && (M4OSA_NULL == pC->pReaderVideoStream) )
2532            {
2533                if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType)
2534                    || (M4DA_StreamTypeVideoMpeg4
2535                    == pStreamHandler->m_streamType)
2536                    || (M4DA_StreamTypeVideoMpeg4Avc
2537                    == pStreamHandler->m_streamType) )
2538                {
2539                    M4OSA_TRACE3_0(
2540                        "M4MCS_open(): Found a H263 or MPEG-4 video stream in input 3gpp clip");
2541
2542                    /**
2543                    * Keep pointer to the video stream */
2544                    pC->pReaderVideoStream =
2545                        (M4_VideoStreamHandler *)pStreamHandler;
2546                    pC->bUnsupportedVideoFound = M4OSA_FALSE;
2547                    pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
2548
2549                    /**
2550                    * Init our video stream state variable */
2551                    pC->VideoState = M4MCS_kStreamState_STARTED;
2552
2553                    /**
2554                    * Reset the stream reader */
2555                    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
2556                        (M4_StreamHandler *)pC->pReaderVideoStream);
2557
2558                    if( M4NO_ERROR != err )
2559                    {
2560                        M4OSA_TRACE1_1(
2561                            "M4MCS_open():\
2562                            m_pReader->m_pFctReset(video) returns 0x%x",
2563                            err);
2564                        return err;
2565                    }
2566
2567                    /**
2568                    * Initializes an access Unit */
2569                    err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
2570                        pStreamHandler, &pC->ReaderVideoAU);
2571
2572                    if( M4NO_ERROR != err )
2573                    {
2574                        M4OSA_TRACE1_1(
2575                            "M4MCS_open():\
2576                            m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
2577                            err);
2578                        return err;
2579                    }
2580                }
2581                else /**< Not H263 or MPEG-4 (H264, etc.) */
2582                {
2583                    M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported video stream (0x%x) in\
2584                                   input 3gpp clip",
2585                                   pStreamHandler->m_streamType);
2586
2587                    pC->bUnsupportedVideoFound = M4OSA_TRUE;
2588                    pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
2589                }
2590                /* +CRLV6775 -H.264 Trimming */
2591                if( M4DA_StreamTypeVideoMpeg4Avc
2592                    == pStreamHandler->m_streamType )
2593                {
2594
2595                    // SPS and PPS are storead as per the 3gp file format
2596                    pC->m_pInstance->m_pDecoderSpecificInfo =
2597                        pStreamHandler->m_pH264DecoderSpecificInfo;
2598                    pC->m_pInstance->m_decoderSpecificInfoSize =
2599                        pStreamHandler->m_H264decoderSpecificInfoSize;
2600                }
2601                /* -CRLV6775 -H.264 Trimming */
2602            }
2603            /**
2604            * Found the first audio stream */
2605            else if( ( M4READER_kMediaFamilyAudio == mediaFamily)
2606                && (M4OSA_NULL == pC->pReaderAudioStream) )
2607            {
2608                if( ( M4DA_StreamTypeAudioAmrNarrowBand
2609                    == pStreamHandler->m_streamType)
2610                    || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType)
2611                    || (M4DA_StreamTypeAudioMp3
2612                    == pStreamHandler->m_streamType)
2613                    || (M4DA_StreamTypeAudioEvrc
2614                    == pStreamHandler->m_streamType) )
2615                {
2616                    M4OSA_TRACE3_0(
2617                        "M4MCS_open(): Found an AMR-NB, AAC or MP3 audio stream in input clip");
2618
2619                    /**
2620                    * Keep pointer to the audio stream */
2621                    pC->pReaderAudioStream =
2622                        (M4_AudioStreamHandler *)pStreamHandler;
2623                    pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
2624                    pC->bUnsupportedAudioFound = M4OSA_FALSE;
2625
2626                    /**
2627                    * Init our audio stream state variable */
2628                    pC->AudioState = M4MCS_kStreamState_STARTED;
2629
2630                    /**
2631                    * Reset the stream reader */
2632                    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
2633                        (M4_StreamHandler *)pC->pReaderAudioStream);
2634
2635                    if( M4NO_ERROR != err )
2636                    {
2637                        M4OSA_TRACE1_1(
2638                            "M4MCS_open():\
2639                            m_pReader->m_pFctReset(audio) returns 0x%x",
2640                            err);
2641                        return err;
2642                    }
2643
2644                    /**
2645                    * Initializes an access Unit */
2646                    err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
2647                        pStreamHandler, &pC->ReaderAudioAU);
2648
2649                    if( M4NO_ERROR != err )
2650                    {
2651                        M4OSA_TRACE1_1(
2652                            "M4MCS_open():\
2653                            m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
2654                            err);
2655                        return err;
2656                    }
2657
2658                    /**
2659                    * Output max AU size is equal to input max AU size (this value
2660                    * will be changed if there is audio transcoding) */
2661                    pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize;
2662                }
2663                else
2664                {
2665                    /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */
2666                    M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported audio stream (0x%x) in \
2667                                   input 3gpp clip", pStreamHandler->m_streamType);
2668
2669                    pC->bUnsupportedAudioFound = M4OSA_TRUE;
2670                    pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
2671                }
2672            }
2673        }
2674    } /**< end of while (M4NO_ERROR == err) */
2675
2676    /**
2677    * Check we found at least one supported stream */
2678    if( ( M4OSA_NULL == pC->pReaderVideoStream)
2679        && (M4OSA_NULL == pC->pReaderAudioStream) )
2680    {
2681        M4OSA_TRACE1_0(
2682            "M4MCS_open(): returning M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM");
2683        return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
2684    }
2685
2686    if( pC->VideoState == M4MCS_kStreamState_STARTED )
2687    {
2688        err = M4MCS_setCurrentVideoDecoder(pContext,
2689            pC->pReaderVideoStream->m_basicProperties.m_streamType);
2690        /*FB 2009-02-09: the error is check and returned only if video codecs are compiled,
2691        else only audio is used, that is why the editing process can continue*/
2692#ifndef M4MCS_AUDIOONLY
2693
2694        M4ERR_CHECK_RETURN(err);
2695
2696#else
2697
2698        if( ( M4NO_ERROR != err) && (M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED != err) )
2699        {
2700            M4ERR_CHECK_RETURN(err);
2701        }
2702
2703#endif /*M4MCS_AUDIOONLY*/
2704
2705    }
2706
2707    if( pC->AudioState == M4MCS_kStreamState_STARTED )
2708    {
2709        //EVRC
2710        if( M4DA_StreamTypeAudioEvrc
2711            != pStreamHandler->
2712            m_streamType ) /* decoder not supported yet, but allow to do null encoding */
2713        {
2714            err = M4MCS_setCurrentAudioDecoder(pContext,
2715                pC->pReaderAudioStream->m_basicProperties.m_streamType);
2716            M4ERR_CHECK_RETURN(err);
2717        }
2718    }
2719
2720    /**
2721    * Get the audio and video stream properties */
2722    err = M4MCS_intGetInputClipProperties(pC);
2723
2724    if( M4NO_ERROR != err )
2725    {
2726        M4OSA_TRACE1_1(
2727            "M4MCS_open(): M4MCS_intGetInputClipProperties returns 0x%x", err);
2728        return err;
2729    }
2730
2731    /**
2732    * Set the begin cut decoding increment according to the input frame rate */
2733    if( 0. != pC->InputFileProperties.fAverageFrameRate ) /**< sanity check */
2734    {
2735        pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000.
2736            / pC->InputFileProperties.
2737            fAverageFrameRate); /**< about 3 frames */
2738    }
2739    else
2740    {
2741        pC->iVideoBeginDecIncr =
2742            200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/
2743    }
2744
2745    /**
2746    * Update state automaton */
2747    pC->State = M4MCS_kState_OPENED;
2748
2749    /**
2750    * Return with no error */
2751    M4OSA_TRACE3_0("M4MCS_open(): returning M4NO_ERROR");
2752    return M4NO_ERROR;
2753}
2754
2755/**
2756 ******************************************************************************
2757 * M4OSA_ERR M4MCS_step(M4MCS_Context pContext, M4OSA_UInt8 *pProgress);
2758 * @brief   Perform one step of trancoding.
2759 * @note
2760 * @param   pContext            (IN) MCS context
2761 * @param   pProgress           (OUT) Progress percentage (0 to 100) of the transcoding
2762 * @note    pProgress must be a valid address.
2763 * @return  M4NO_ERROR:         No error
2764 * @return  M4ERR_PARAMETER:    One of the parameters is M4OSA_NULL (debug only)
2765 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2766 * @return  M4MCS_WAR_TRANSCODING_DONE: Transcoding is over, user should now call M4MCS_close()
2767 * @return  M4MCS_ERR_AUDIO_CONVERSION_FAILED: The audio conversion (AAC to AMR-NB or MP3) failed
2768 * @return  M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY: The input file contains an AAC audio track
2769 *                                 with an invalid sampling frequency (should never happen)
2770 ******************************************************************************
2771 */
2772M4OSA_ERR M4MCS_step( M4MCS_Context pContext, M4OSA_UInt8 *pProgress )
2773{
2774    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2775
2776    M4OSA_TRACE3_1("M4MCS_step called with pContext=0x%x", pContext);
2777
2778    /**
2779    * Check input parameters */
2780    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2781        "M4MCS_step: pContext is M4OSA_NULL");
2782    M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER,
2783        "M4MCS_step: pProgress is M4OSA_NULL");
2784
2785#ifdef M4MCS_SUPPORT_STILL_PICTURE
2786
2787    if( pC->m_bIsStillPicture )
2788    {
2789        /**
2790        * Call the still picture MCS functions*/
2791        return M4MCS_stillPicStep(pC, pProgress);
2792    }
2793
2794#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2795
2796    /**
2797    * Check state automaton */
2798
2799    switch( pC->State )
2800    {
2801        case M4MCS_kState_READY:
2802            *pProgress = 0;
2803            return M4MCS_intStepSet(pC);
2804            break;
2805
2806        case M4MCS_kState_BEGINVIDEOJUMP:
2807            *pProgress = pC->uiProgress;
2808            return M4MCS_intStepBeginVideoJump(pC);
2809            break;
2810
2811        case M4MCS_kState_BEGINVIDEODECODE:
2812            *pProgress = pC->uiProgress;
2813            return M4MCS_intStepBeginVideoDecode(pC);
2814            break;
2815
2816        case M4MCS_kState_PROCESSING:
2817            {
2818                M4OSA_ERR err = M4NO_ERROR;
2819                err = M4MCS_intStepEncoding(pC, pProgress);
2820                /* Save progress info in case of pause */
2821                pC->uiProgress = *pProgress;
2822                return err;
2823            }
2824            break;
2825
2826        default: /**< State error */
2827            M4OSA_TRACE1_1(
2828                "M4MCS_step(): Wrong State (%d), returning M4ERR_STATE",
2829                pC->State);
2830            return M4ERR_STATE;
2831    }
2832}
2833
2834/**
2835 ******************************************************************************
2836 * M4OSA_ERR M4MCS_pause(M4MCS_Context pContext);
2837 * @brief   Pause the transcoding i.e. release the (external hardware) video decoder.
2838 * @note    This function is not needed if no hardware accelerators are used.
2839 *          In that case, pausing the MCS is simply achieved by temporarily suspending
2840 *          the M4MCS_step function calls.
2841 * @param   pContext            (IN) MCS context
2842 * @return  M4NO_ERROR:         No error
2843 * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
2844 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2845 ******************************************************************************
2846 */
2847M4OSA_ERR M4MCS_pause( M4MCS_Context pContext )
2848{
2849    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2850    M4OSA_ERR err;
2851
2852    M4OSA_TRACE2_1("M4MCS_pause called with pContext=0x%x", pContext);
2853
2854    /**
2855    * Check input parameters */
2856    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2857        "M4MCS_pause: pContext is M4OSA_NULL");
2858
2859#ifdef M4MCS_SUPPORT_STILL_PICTURE
2860
2861    if( pC->m_bIsStillPicture )
2862    {
2863        /**
2864        * Call the corresponding still picture MCS function*/
2865        return M4MCS_stillPicPause(pC);
2866    }
2867
2868#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2869
2870    /**
2871    * Check state automaton */
2872
2873    switch( pC->State )
2874    {
2875        case M4MCS_kState_BEGINVIDEOJUMP: /**< the video decoder has been created,
2876                                            we must destroy it */
2877        case M4MCS_kState_BEGINVIDEODECODE: /**< the video is being used, we must destroy it */
2878        case M4MCS_kState_PROCESSING: /**< the video is being used, we must destroy it */
2879                    /**< OK, nothing to do here */
2880            break;
2881
2882        default: /**< State error */
2883            M4OSA_TRACE1_1(
2884                "M4MCS_pause(): Wrong State (%d), returning M4ERR_STATE",
2885                pC->State);
2886            return M4ERR_STATE;
2887    }
2888
2889    /**
2890    * Set the CTS at which we will resume the decoding */
2891    if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
2892    {
2893        /**
2894        * We passed the starting CTS, so the resume target is the current CTS */
2895        pC->dViDecStartingCts = pC->dViDecCurrentCts;
2896    }
2897    else {
2898        /**
2899        * We haven't passed the starting CTS yet, so the resume target is still the starting CTS
2900        * --> nothing to do in the else block */
2901    }
2902
2903    /**
2904    * Free video decoder stuff */
2905    if( M4OSA_NULL != pC->pViDecCtxt )
2906    {
2907        err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
2908        pC->pViDecCtxt = M4OSA_NULL;
2909
2910        if( M4NO_ERROR != err )
2911        {
2912            M4OSA_TRACE1_1(
2913                "M4MCS_pause: m_pVideoDecoder->pFctDestroy returns 0x%x", err);
2914            return err;
2915        }
2916    }
2917
2918    /**
2919    * State transition */
2920    pC->State = M4MCS_kState_PAUSED;
2921
2922    M4OSA_TRACE3_0("M4MCS_pause(): returning M4NO_ERROR");
2923    return M4NO_ERROR;
2924}
2925
2926/**
2927 ******************************************************************************
2928 * M4OSA_ERR M4MCS_resume(M4MCS_Context pContext);
2929 * @brief   Resume the transcoding after a pause (see M4MCS_pause).
2930 * @note    This function is not needed if no hardware accelerators are used.
2931 *          In that case, resuming the MCS is simply achieved by calling
2932 *          the M4MCS_step function.
2933 * @param   pContext            (IN) MCS context
2934 * @return  M4NO_ERROR:         No error
2935 * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
2936 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2937 ******************************************************************************
2938 */
2939M4OSA_ERR M4MCS_resume( M4MCS_Context pContext )
2940{
2941    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2942    M4OSA_ERR err;
2943
2944    M4OSA_TRACE2_1("M4MCS_resume called with pContext=0x%x", pContext);
2945
2946    /**
2947    * Check input parameters */
2948    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2949        "M4MCS_resume: pContext is M4OSA_NULL");
2950
2951#ifdef M4MCS_SUPPORT_STILL_PICTURE
2952
2953    if( pC->m_bIsStillPicture )
2954    {
2955        /**
2956        * Call the corresponding still picture MCS function*/
2957        return M4MCS_stillPicResume(pC);
2958    }
2959
2960#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2961
2962    /**
2963    * Check state automaton */
2964
2965    switch( pC->State )
2966    {
2967        case M4MCS_kState_PAUSED: /**< OK, nothing to do here */
2968            break;
2969
2970        default:                  /**< State error */
2971            M4OSA_TRACE1_1(
2972                "M4MCS_resume(): Wrong State (%d), returning M4ERR_STATE",
2973                pC->State);
2974            return M4ERR_STATE;
2975            break;
2976    }
2977
2978    /**
2979    * Prepare the video decoder */
2980    err = M4MCS_intPrepareVideoDecoder(pC);
2981
2982    if( M4NO_ERROR != err )
2983    {
2984        M4OSA_TRACE1_1(
2985            "M4MCS_resume(): M4MCS_intPrepareVideoDecoder() returns 0x%x", err);
2986        return err;
2987    }
2988
2989    /**
2990    * State transition */
2991    if( 0.0 == pC->dViDecStartingCts )
2992    {
2993        /**
2994        * We are still at the beginning of the decoded stream, no need to jump, we can proceed */
2995        pC->State = M4MCS_kState_PROCESSING;
2996    }
2997    else
2998    {
2999        /**
3000        * Jumping */
3001        pC->State = M4MCS_kState_BEGINVIDEOJUMP;
3002    }
3003
3004    M4OSA_TRACE3_0("M4MCS_resume(): returning M4NO_ERROR");
3005    return M4NO_ERROR;
3006}
3007
3008/**
3009 ******************************************************************************
3010 * M4OSA_ERR M4MCS_close(M4MCS_Context pContext);
3011 * @brief    Finish the MCS transcoding.
3012 * @note The output 3GPP file is ready to be played after this call
3013 * @param    pContext            (IN) MCS context
3014 * @return   M4NO_ERROR:         No error
3015 * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
3016 * @return   M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3017 ******************************************************************************
3018 */
3019M4OSA_ERR M4MCS_close( M4MCS_Context pContext )
3020{
3021    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3022    M4ENCODER_Header *encHeader;
3023    M4SYS_StreamIDmemAddr streamHeader;
3024
3025    M4OSA_ERR err = M4NO_ERROR, err2;
3026
3027    M4OSA_TRACE2_1("M4MCS_close called with pContext=0x%x", pContext);
3028
3029    /**
3030    * Check input parameters */
3031    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3032        "M4MCS_close: pContext is M4OSA_NULL");
3033
3034#ifdef M4MCS_SUPPORT_STILL_PICTURE
3035
3036    if( pC->m_bIsStillPicture )
3037    {
3038        /**
3039        * Indicate that current file is no longer a still picture*/
3040        pC->m_bIsStillPicture = M4OSA_FALSE;
3041
3042        /**
3043        * Call the corresponding still picture MCS function*/
3044        return M4MCS_stillPicClose(pC);
3045    }
3046
3047#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3048
3049    /**
3050    * Check state automaton */
3051
3052    if( M4MCS_kState_FINISHED != pC->State )
3053    {
3054        M4OSA_TRACE1_1("M4MCS_close(): Wrong State (%d), returning M4ERR_STATE",
3055            pC->State);
3056        return M4ERR_STATE;
3057    }
3058
3059    /* Close the encoder before the writer to be certain all the AUs have been written and we can
3060    get the DSI. */
3061
3062    /* Has the encoder actually been started? Don't stop it if that's not the case. */
3063    if( M4MCS_kEncoderRunning == pC->encoderState )
3064    {
3065        if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
3066        {
3067            err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt);
3068
3069            if( M4NO_ERROR != err )
3070            {
3071                M4OSA_TRACE1_1(
3072                    "M4MCS_close: pVideoEncoderGlobalFcts->pFctStop returns 0x%x",
3073                    err);
3074                /* Well... how the heck do you handle a failed cleanup? */
3075            }
3076        }
3077
3078        pC->encoderState = M4MCS_kEncoderStopped;
3079    }
3080
3081    /* Has the encoder actually been opened? Don't close it if that's not the case. */
3082    if( M4MCS_kEncoderStopped == pC->encoderState )
3083    {
3084        err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt);
3085
3086        if( M4NO_ERROR != err )
3087        {
3088            M4OSA_TRACE1_1(
3089                "M4MCS_close: pVideoEncoderGlobalFcts->pFctClose returns 0x%x",
3090                err);
3091            /* Well... how the heck do you handle a failed cleanup? */
3092        }
3093
3094        pC->encoderState = M4MCS_kEncoderClosed;
3095    }
3096
3097    /**********************************/
3098    /******** Close the writer ********/
3099    /**********************************/
3100    if( M4OSA_NULL != pC->pWriterContext ) /* happens in state _SET */
3101    {
3102        /* HW encoder: fetch the DSI from the shell video encoder, and feed it to the writer before
3103        closing it. */
3104
3105        if( pC->novideo != M4OSA_TRUE )
3106        {
3107            if( ( M4ENCODER_kMPEG4 == pC->EncodingVideoFormat)
3108                || (M4ENCODER_kH264 == pC->EncodingVideoFormat) )
3109            {
3110                err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt,
3111                    M4ENCODER_kOptionID_EncoderHeader,
3112                    (M4OSA_DataOption) &encHeader);
3113
3114                if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) )
3115                {
3116                    M4OSA_TRACE1_1(
3117                        "M4MCS_close: failed to get the encoder header (err 0x%x)",
3118                        err);
3119                    /**< no return here, we still have stuff to deallocate after close, even
3120                     if it fails. */
3121                }
3122                else
3123                {
3124                    /* set this header in the writer */
3125                    streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
3126                    streamHeader.size = encHeader->Size;
3127                    streamHeader.addr = (M4OSA_MemAddr32)encHeader->pBuf;
3128                }
3129
3130                M4OSA_TRACE1_0("calling set option");
3131                err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
3132                    M4WRITER_kDSI, &streamHeader);
3133                M4OSA_TRACE1_0("set option done");
3134
3135                if( M4NO_ERROR != err )
3136                {
3137                    M4OSA_TRACE1_1(
3138                        "M4MCS_close: failed to set the DSI in the writer (err 0x%x)",
3139                        err);
3140                }
3141            }
3142
3143            if( ( M4OSA_TRUE == pC->bH264Trim)
3144                && (M4ENCODER_kNULL == pC->EncodingVideoFormat) )
3145            {
3146                if(pC->uiBeginCutTime == 0)
3147                {
3148                    M4OSA_TRACE1_1("Decoder specific info size = %d",
3149                        pC->m_pInstance->m_decoderSpecificInfoSize);
3150                    pC->m_pInstance->m_pFinalDSISize =
3151                        pC->m_pInstance->m_decoderSpecificInfoSize;
3152                    M4OSA_TRACE1_1("Decoder specific info pointer = %d",
3153                        (M4OSA_MemAddr8)pC->m_pInstance->m_pDecoderSpecificInfo);
3154
3155                    pC->m_pInstance->m_pFinalDSI =
3156                        (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->m_pInstance-> \
3157                        m_decoderSpecificInfoSize, M4MCS,
3158                        (M4OSA_Char *)"instance->m_pFinalDSI");
3159
3160                    if( pC->m_pInstance->m_pFinalDSI == M4OSA_NULL )
3161                    {
3162                        M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
3163                        return M4ERR_ALLOC;
3164                    }
3165                    memcpy((void *)pC->m_pInstance->m_pFinalDSI,
3166                        (void *)pC-> \
3167                        m_pInstance->m_pDecoderSpecificInfo,
3168                        pC->m_pInstance->m_decoderSpecificInfoSize);
3169                }
3170                streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
3171                streamHeader.size = pC->m_pInstance->m_pFinalDSISize;
3172                streamHeader.addr =
3173                    (M4OSA_MemAddr32)pC->m_pInstance->m_pFinalDSI;
3174                M4OSA_TRACE1_0("calling set option");
3175                err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
3176                    M4WRITER_kDSI, &streamHeader);
3177                M4OSA_TRACE1_0("set option done");
3178
3179                if( M4NO_ERROR != err )
3180                {
3181                    M4OSA_TRACE1_1(
3182                        "M4MCS_close: failed to set the DSI in the writer (err 0x%x)",
3183                        err);
3184                }
3185            }
3186        }
3187        /* Write and close the 3GP output file */
3188        err2 = pC->pWriterGlobalFcts->pFctCloseWrite(pC->pWriterContext);
3189        pC->pWriterContext = M4OSA_NULL;
3190
3191        if( M4NO_ERROR != err2 )
3192        {
3193            M4OSA_TRACE1_1(
3194                "M4MCS_close: pWriterGlobalFcts->pFctCloseWrite returns 0x%x",
3195                err2);
3196
3197            if( M4NO_ERROR == err )
3198                err = err2;
3199            /**< no return here, we still have stuff to deallocate after close, even if it fails.*/
3200        }
3201    }
3202
3203    /* Close output PCM file if needed */
3204    if( pC->pOutputPCMfile != M4OSA_NULL )
3205    {
3206        pC->pOsaFileWritPtr->closeWrite(pC->pOutputPCMfile);
3207        pC->pOutputPCMfile = M4OSA_NULL;
3208    }
3209
3210    /*FlB 2009.03.04: add audio effects,
3211    free effects list*/
3212    if( M4OSA_NULL != pC->pEffects )
3213    {
3214        free(pC->pEffects);
3215        pC->pEffects = M4OSA_NULL;
3216    }
3217    pC->nbEffects = 0;
3218    pC->pActiveEffectNumber = -1;
3219
3220    /**
3221    * State transition */
3222    pC->State = M4MCS_kState_CLOSED;
3223
3224    if( M4OSA_NULL != pC->H264MCSTempBuffer )
3225    {
3226        free(pC->H264MCSTempBuffer);
3227    }
3228
3229    M4OSA_TRACE3_0("M4MCS_close(): returning M4NO_ERROR");
3230    return err;
3231}
3232
3233/**
3234 ******************************************************************************
3235 * M4OSA_ERR M4MCS_cleanUp(M4MCS_Context pContext);
3236 * @brief    Free all resources used by the MCS.
3237 * @note The context is no more valid after this call
3238 * @param    pContext            (IN) MCS context
3239 * @return   M4NO_ERROR:         No error
3240 * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
3241 * @return   M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3242 ******************************************************************************
3243 */
3244M4OSA_ERR M4MCS_cleanUp( M4MCS_Context pContext )
3245{
3246    M4OSA_ERR err = M4NO_ERROR;
3247    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3248
3249    M4OSA_TRACE3_1("M4MCS_cleanUp called with pContext=0x%x", pContext);
3250
3251#ifdef MCS_DUMP_PCM_TO_FILE
3252
3253    if( file_au_reader )
3254    {
3255        fclose(file_au_reader);
3256        file_au_reader = NULL;
3257    }
3258
3259    if( file_pcm_decoder )
3260    {
3261        fclose(file_pcm_decoder);
3262        file_pcm_decoder = NULL;
3263    }
3264
3265    if( file_pcm_encoder )
3266    {
3267        fclose(file_pcm_encoder);
3268        file_pcm_encoder = NULL;
3269    }
3270
3271#endif
3272
3273    /**
3274    * Check input parameter */
3275
3276    if( M4OSA_NULL == pContext )
3277    {
3278        M4OSA_TRACE1_0(
3279            "M4MCS_cleanUp: pContext is M4OSA_NULL, returning M4ERR_PARAMETER");
3280        return M4ERR_PARAMETER;
3281    }
3282
3283    /**
3284    * Check state automaton */
3285    if( M4MCS_kState_CLOSED != pC->State )
3286    {
3287        M4OSA_TRACE1_1(
3288            "M4MCS_cleanUp(): Wrong State (%d), returning M4ERR_STATE",
3289            pC->State);
3290        return M4ERR_STATE;
3291    }
3292
3293    if( M4OSA_NULL != pC->m_pInstance )
3294    {
3295        err = H264MCS_Freeinstance(pC->m_pInstance);
3296        pC->m_pInstance = M4OSA_NULL;
3297    }
3298
3299    /* ----- Free video encoder stuff, if needed ----- */
3300
3301    if( ( M4OSA_NULL != pC->pViEncCtxt)
3302        && (M4OSA_NULL != pC->pVideoEncoderGlobalFcts) )
3303    {
3304        err = pC->pVideoEncoderGlobalFcts->pFctCleanup(pC->pViEncCtxt);
3305        pC->pViEncCtxt = M4OSA_NULL;
3306
3307        if( M4NO_ERROR != err )
3308        {
3309            M4OSA_TRACE1_1(
3310                "M4MCS_cleanUp: pVideoEncoderGlobalFcts->pFctCleanup returns 0x%x",
3311                err);
3312            /**< don't return, we still have stuff to free */
3313        }
3314
3315        pC->encoderState = M4MCS_kNoEncoder;
3316    }
3317
3318    /**
3319    * In the H263 case, we allocated our own DSI buffer */
3320    if( ( M4ENCODER_kH263 == pC->EncodingVideoFormat)
3321        && (M4OSA_NULL != pC->WriterVideoStreamInfo.Header.pBuf) )
3322    {
3323        free(pC->WriterVideoStreamInfo.Header.pBuf);
3324        pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL;
3325    }
3326
3327    if( M4OSA_NULL != pC->pPreResizeFrame )
3328    {
3329        if( M4OSA_NULL != pC->pPreResizeFrame[0].pac_data )
3330        {
3331            free(pC->pPreResizeFrame[0].pac_data);
3332            pC->pPreResizeFrame[0].pac_data = M4OSA_NULL;
3333        }
3334
3335        if( M4OSA_NULL != pC->pPreResizeFrame[1].pac_data )
3336        {
3337            free(pC->pPreResizeFrame[1].pac_data);
3338            pC->pPreResizeFrame[1].pac_data = M4OSA_NULL;
3339        }
3340
3341        if( M4OSA_NULL != pC->pPreResizeFrame[2].pac_data )
3342        {
3343            free(pC->pPreResizeFrame[2].pac_data);
3344            pC->pPreResizeFrame[2].pac_data = M4OSA_NULL;
3345        }
3346        free(pC->pPreResizeFrame);
3347        pC->pPreResizeFrame = M4OSA_NULL;
3348    }
3349
3350    /* ----- Free the ssrc stuff ----- */
3351
3352    if( M4OSA_NULL != pC->SsrcScratch )
3353    {
3354        free(pC->SsrcScratch);
3355        pC->SsrcScratch = M4OSA_NULL;
3356    }
3357
3358    if( M4OSA_NULL != pC->pSsrcBufferIn )
3359    {
3360        free(pC->pSsrcBufferIn);
3361        pC->pSsrcBufferIn = M4OSA_NULL;
3362    }
3363
3364    if( M4OSA_NULL != pC->pSsrcBufferOut )
3365    {
3366        free(pC->pSsrcBufferOut);
3367        pC->pSsrcBufferOut = M4OSA_NULL;
3368    }
3369
3370    if (pC->pLVAudioResampler != M4OSA_NULL)
3371    {
3372        LVDestroy(pC->pLVAudioResampler);
3373        pC->pLVAudioResampler = M4OSA_NULL;
3374    }
3375
3376    /* ----- Free the audio encoder stuff ----- */
3377
3378    if( M4OSA_NULL != pC->pAudioEncCtxt )
3379    {
3380        err = pC->pAudioEncoderGlobalFcts->pFctClose(pC->pAudioEncCtxt);
3381
3382        if( M4NO_ERROR != err )
3383        {
3384            M4OSA_TRACE1_1(
3385                "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x",
3386                err);
3387            /**< don't return, we still have stuff to free */
3388        }
3389
3390        err = pC->pAudioEncoderGlobalFcts->pFctCleanUp(pC->pAudioEncCtxt);
3391
3392        if( M4NO_ERROR != err )
3393        {
3394            M4OSA_TRACE1_1(
3395                "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x",
3396                err);
3397            /**< don't return, we still have stuff to free */
3398        }
3399
3400        pC->pAudioEncCtxt = M4OSA_NULL;
3401    }
3402
3403    if( M4OSA_NULL != pC->pAudioEncoderBuffer )
3404    {
3405        free(pC->pAudioEncoderBuffer);
3406        pC->pAudioEncoderBuffer = M4OSA_NULL;
3407    }
3408
3409    /* ----- Free all other stuff ----- */
3410
3411    /**
3412    * Free the readers and the decoders */
3413    M4MCS_intCleanUp_ReadersDecoders(pC);
3414
3415#ifdef M4MCS_SUPPORT_STILL_PICTURE
3416    /**
3417    * Free the still picture resources */
3418
3419    M4MCS_stillPicCleanUp(pC);
3420
3421#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3422
3423    /**
3424    * Free the shells interfaces */
3425
3426    M4MCS_unRegisterAllWriters(pContext);
3427    M4MCS_unRegisterAllEncoders(pContext);
3428    M4MCS_unRegisterAllReaders(pContext);
3429    M4MCS_unRegisterAllDecoders(pContext);
3430
3431    /**
3432    * Free the context itself */
3433    free(pC);
3434    pC = M4OSA_NULL;
3435
3436    M4OSA_TRACE3_0("M4MCS_cleanUp(): returning M4NO_ERROR");
3437    return M4NO_ERROR;
3438}
3439
3440/**
3441 ******************************************************************************
3442 * M4OSA_ERR M4MCS_abort(M4MCS_Context pContext);
3443 * @brief    Finish the MCS transcoding and free all resources used by the MCS
3444 *          whatever the state is.
3445 * @note    The context is no more valid after this call
3446 * @param    pContext            (IN) MCS context
3447 * @return    M4NO_ERROR:            No error
3448 * @return    M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
3449 ******************************************************************************
3450 */
3451M4OSA_ERR M4MCS_abort( M4MCS_Context pContext )
3452{
3453    M4OSA_ERR err = M4NO_ERROR;
3454    M4OSA_ERR err1 = M4NO_ERROR;
3455    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3456
3457    if( M4OSA_NULL == pContext )
3458    {
3459        return M4NO_ERROR;
3460    }
3461
3462    if( ( pC->State == M4MCS_kState_CREATED)
3463        || (pC->State == M4MCS_kState_CLOSED) )
3464    {
3465        pC->State = M4MCS_kState_CLOSED;
3466
3467        err = M4MCS_cleanUp(pContext);
3468
3469        if( err != M4NO_ERROR )
3470        {
3471            M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err);
3472        }
3473    }
3474    else
3475    {
3476#ifdef M4MCS_SUPPORT_STILL_PICTURE
3477
3478        if( pC->m_bIsStillPicture )
3479        {
3480            /**
3481            * Cancel the ongoing processes if any*/
3482            err = M4MCS_stillPicCancel(pC);
3483
3484            if( err != M4NO_ERROR )
3485            {
3486                M4OSA_TRACE1_1(
3487                    "M4MCS_abort : M4MCS_stillPicCancel fails err = 0x%x", err);
3488            }
3489            /*Still picture process is now stopped; Carry on with close and cleanup*/
3490        }
3491
3492#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3493
3494        pC->State = M4MCS_kState_FINISHED;
3495
3496        err = M4MCS_close(pContext);
3497
3498        if( err != M4NO_ERROR )
3499        {
3500            M4OSA_TRACE1_1("M4MCS_abort : M4MCS_close fails err = 0x%x", err);
3501            err1 = err;
3502        }
3503
3504        err = M4MCS_cleanUp(pContext);
3505
3506        if( err != M4NO_ERROR )
3507        {
3508            M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err);
3509        }
3510    }
3511    err = (err1 == M4NO_ERROR) ? err : err1;
3512    return err;
3513}
3514
3515/**
3516 ******************************************************************************
3517 * M4OSA_ERR M4MCS_getInputFileProperties(M4MCS_Context pContext,
3518 *                                         M4VIDEOEDITING_ClipProperties* pFileProperties);
3519 * @brief   Retrieves the properties of the audio and video streams from the input file.
3520 * @param   pContext            (IN) MCS context
3521 * @param   pProperties         (OUT) Pointer on an allocated M4VIDEOEDITING_ClipProperties
3522structure which is filled with the input stream properties.
3523 * @note    The structure pProperties must be allocated and further de-allocated
3524by the application. The function must be called in the opened state.
3525 * @return  M4NO_ERROR:         No error
3526 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
3527 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3528 ******************************************************************************
3529 */
3530M4OSA_ERR M4MCS_getInputFileProperties( M4MCS_Context pContext,
3531                                       M4VIDEOEDITING_ClipProperties *pFileProperties )
3532{
3533    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3534
3535    M4OSA_TRACE2_2("M4MCS_getInputFileProperties called with pContext=0x%x, \
3536                   pFileProperties=0x%x", pContext, pFileProperties);
3537
3538    /**
3539    * Check input parameters */
3540    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3541        "M4MCS_getInputFileProperties: pContext is M4OSA_NULL");
3542    M4OSA_DEBUG_IF2((M4OSA_NULL == pFileProperties), M4ERR_PARAMETER,
3543        "M4MCS_getInputFileProperties: pProperties is M4OSA_NULL");
3544
3545#ifdef M4MCS_SUPPORT_STILL_PICTURE
3546
3547    if( pC->m_bIsStillPicture )
3548    {
3549        /**
3550        * Call the corresponding still picture MCS function*/
3551        return M4MCS_stillPicGetInputFileProperties(pC, pFileProperties);
3552    }
3553
3554#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3555
3556    /**
3557    * Check state automaton */
3558
3559    if( M4MCS_kState_OPENED != pC->State )
3560    {
3561        M4OSA_TRACE1_1(
3562            "M4MCS_getInputFileProperties(): Wrong State (%d), returning M4ERR_STATE",
3563            pC->State);
3564        return M4ERR_STATE;
3565    }
3566
3567    /**
3568    * Copy previously computed properties into given structure */
3569    memcpy((void *)pFileProperties,
3570        (void *) &pC->InputFileProperties,
3571        sizeof(M4VIDEOEDITING_ClipProperties));
3572
3573    return M4NO_ERROR;
3574}
3575
3576/**
3577 ******************************************************************************
3578 * M4OSA_ERR M4MCS_setOutputParams(M4MCS_Context pContext, M4MCS_OutputParams* pParams);
3579 * @brief   Set the MCS video output parameters.
3580 * @note    Must be called after M4MCS_open. Must be called before M4MCS_step.
3581 * @param   pContext            (IN) MCS context
3582 * @param   pParams             (IN/OUT) Transcoding parameters
3583 * @return  M4NO_ERROR:         No error
3584 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
3585 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3586 * @return  M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 : Output video frame size parameter is
3587 *                                                        incompatible with H263 encoding
3588 * @return  M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 : Output video frame size parameter is
3589 *                                                        incompatible with H263 encoding
3590 * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT     : Undefined output video format parameter
3591 * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE : Undefined output video frame size
3592 * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE : Undefined output video frame rate
3593 * @return  M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT : Undefined output audio format parameter
3594 * @return  M4MCS_ERR_DURATION_IS_NULL : Specified output parameters define a null duration stream
3595 *                                         (no audio and video)
3596 ******************************************************************************
3597 */
3598M4OSA_ERR M4MCS_setOutputParams( M4MCS_Context pContext,
3599                                M4MCS_OutputParams *pParams )
3600{
3601    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3602    M4OSA_UInt32 uiFrameWidth;
3603    M4OSA_UInt32 uiFrameHeight;
3604    M4OSA_ERR err;
3605
3606    M4OSA_TRACE2_2(
3607        "M4MCS_setOutputParams called with pContext=0x%x, pParams=0x%x",
3608        pContext, pParams);
3609
3610    /**
3611    * Check input parameters */
3612    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3613        "M4MCS_setOutputParams: pContext is M4OSA_NULL");
3614    M4OSA_DEBUG_IF2((M4OSA_NULL == pParams), M4ERR_PARAMETER,
3615        "M4MCS_setOutputParams: pParam is M4OSA_NULL");
3616
3617#ifdef M4MCS_SUPPORT_STILL_PICTURE
3618
3619    if( pC->m_bIsStillPicture )
3620    {
3621        /**
3622        * Call the corresponding still picture MCS function*/
3623        return M4MCS_stillPicSetOutputParams(pC, pParams);
3624    }
3625
3626#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3627
3628    /**
3629    * Check state automaton */
3630
3631    if( M4MCS_kState_OPENED != pC->State )
3632    {
3633        M4OSA_TRACE1_1(
3634            "M4MCS_setOutputParams(): Wrong State (%d), returning M4ERR_STATE",
3635            pC->State);
3636        return M4ERR_STATE;
3637    }
3638
3639    /* Ignore audio or video stream if the output do not need it, */
3640    /* or if the input file does not have any audio or video stream */
3641    /*FlB 26.02.2009: add mp3 as mcs output format*/
3642    if( ( pParams->OutputVideoFormat == M4VIDEOEDITING_kNoneVideo)
3643        || (pC->VideoState == M4MCS_kStreamState_NOSTREAM)
3644        || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_AMR)
3645        || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP3) )
3646    {
3647        pC->novideo = M4OSA_TRUE;
3648    }
3649
3650    if( ( pParams->OutputAudioFormat == M4VIDEOEDITING_kNoneAudio)
3651        || (pC->AudioState == M4MCS_kStreamState_NOSTREAM) )
3652    {
3653        pC->noaudio = M4OSA_TRUE;
3654    }
3655
3656    if( pC->noaudio && pC->novideo )
3657    {
3658        M4OSA_TRACE1_0(
3659            "!!! M4MCS_setOutputParams : clip is NULL, there is no audio, no video");
3660        return M4MCS_ERR_DURATION_IS_NULL;
3661    }
3662
3663    /* Set writer */
3664    err = M4MCS_setCurrentWriter(pContext, pParams->OutputFileType);
3665    M4ERR_CHECK_RETURN(err);
3666
3667    /* Set video parameters */
3668    if( pC->novideo == M4OSA_FALSE )
3669    {
3670        /**
3671        * Check Video Format correctness */
3672
3673        switch( pParams->OutputVideoFormat )
3674        {
3675            case M4VIDEOEDITING_kH263:
3676                if( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4 )
3677                    return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE;
3678
3679                pC->EncodingVideoFormat = M4ENCODER_kH263;
3680                err = M4MCS_setCurrentVideoEncoder(pContext,
3681                    pParams->OutputVideoFormat);
3682                M4ERR_CHECK_RETURN(err);
3683                break;
3684
3685            case M4VIDEOEDITING_kMPEG4_EMP:
3686                pC->bActivateEmp = M4OSA_TRUE;
3687
3688            case M4VIDEOEDITING_kMPEG4:
3689
3690                pC->EncodingVideoFormat = M4ENCODER_kMPEG4;
3691                err = M4MCS_setCurrentVideoEncoder(pContext,
3692                    pParams->OutputVideoFormat);
3693                M4ERR_CHECK_RETURN(err);
3694                break;
3695
3696            case M4VIDEOEDITING_kH264:
3697
3698                pC->EncodingVideoFormat = M4ENCODER_kH264;
3699                err = M4MCS_setCurrentVideoEncoder(pContext,
3700                    pParams->OutputVideoFormat);
3701                M4ERR_CHECK_RETURN(err);
3702                break;
3703
3704            case M4VIDEOEDITING_kNullVideo:
3705                if( ( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4)
3706                    && (pC->InputFileProperties.VideoStreamType
3707                    == M4VIDEOEDITING_kH263) )
3708                    return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE;
3709
3710
3711                /* If input file is EMP, output file will be too */
3712
3713                if( pC->InputFileProperties.VideoStreamType
3714                    == M4VIDEOEDITING_kMPEG4_EMP )
3715                    pC->bActivateEmp = M4OSA_TRUE;
3716
3717                /* Encoder needed for begin cut to generate an I-frame */
3718                pC->EncodingVideoFormat = M4ENCODER_kNULL;
3719                err = M4MCS_setCurrentVideoEncoder(pContext,
3720                    pC->InputFileProperties.VideoStreamType);
3721                M4ERR_CHECK_RETURN(err);
3722                break;
3723
3724            default:
3725                M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output video format (%d),\
3726                               returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
3727                               pParams->OutputVideoFormat);
3728                return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
3729        }
3730
3731        /**
3732        * Check Video frame size correctness */
3733        if( M4VIDEOEDITING_kNullVideo == pParams->OutputVideoFormat )
3734        {
3735            uiFrameWidth =
3736                pC->EncodingWidth = pC->InputFileProperties.uiVideoWidth;
3737            uiFrameHeight =
3738                pC->EncodingHeight = pC->InputFileProperties.uiVideoHeight;
3739        }
3740        else
3741        {
3742            switch( pParams->OutputVideoFrameSize )
3743            {
3744                case M4VIDEOEDITING_kSQCIF:
3745                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width;
3746                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height;
3747                    break;
3748
3749                case M4VIDEOEDITING_kQQVGA:
3750                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width;
3751                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height;
3752                    break;
3753
3754                case M4VIDEOEDITING_kQCIF:
3755                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width;
3756                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height;
3757                    break;
3758
3759                case M4VIDEOEDITING_kQVGA:
3760                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width;
3761                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height;
3762                    break;
3763
3764                case M4VIDEOEDITING_kCIF:
3765                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width;
3766                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height;
3767                    break;
3768
3769                case M4VIDEOEDITING_kVGA:
3770                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width;
3771                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height;
3772                    break;
3773                    /* +PR LV5807 */
3774                case M4VIDEOEDITING_kWVGA:
3775                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width;
3776                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height;
3777                    break;
3778
3779                case M4VIDEOEDITING_kNTSC:
3780                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width;
3781                    uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height;
3782                    break;
3783                    /* -PR LV5807*/
3784                    /* +CR Google */
3785                case M4VIDEOEDITING_k640_360:
3786                    uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width;
3787                    uiFrameHeight =
3788                        pC->EncodingHeight = M4ENCODER_640_360_Height;
3789                    break;
3790
3791                case M4VIDEOEDITING_k854_480:
3792                    uiFrameWidth =
3793                        pC->EncodingWidth = M4ENCODER_854_480_Width;
3794                    uiFrameHeight =
3795                        pC->EncodingHeight = M4ENCODER_854_480_Height;
3796                    break;
3797
3798                case M4VIDEOEDITING_k1280_720:
3799                    uiFrameWidth =
3800                        pC->EncodingWidth = M4ENCODER_1280_720_Width;
3801                    uiFrameHeight =
3802                        pC->EncodingHeight = M4ENCODER_1280_720_Height;
3803                    break;
3804
3805                case M4VIDEOEDITING_k1080_720:
3806                    uiFrameWidth =
3807                        pC->EncodingWidth = M4ENCODER_1080_720_Width;
3808                    uiFrameHeight =
3809                        pC->EncodingHeight = M4ENCODER_1080_720_Height;
3810                    break;
3811
3812                case M4VIDEOEDITING_k960_720:
3813                    uiFrameWidth =
3814                        pC->EncodingWidth = M4ENCODER_960_720_Width;
3815                    uiFrameHeight =
3816                        pC->EncodingHeight = M4ENCODER_960_720_Height;
3817                    break;
3818
3819                case M4VIDEOEDITING_k1920_1080:
3820                    uiFrameWidth =
3821                        pC->EncodingWidth = M4ENCODER_1920_1080_Width;
3822                    uiFrameHeight =
3823                        pC->EncodingHeight = M4ENCODER_1920_1080_Height;
3824                    break;
3825                    /* -CR Google */
3826                default:
3827                    M4OSA_TRACE1_1(
3828                        "M4MCS_setOutputParams: Undefined output video frame size \
3829                        (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE",
3830                        pParams->OutputVideoFrameSize);
3831                    return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
3832            }
3833        }
3834
3835        /**
3836        * Compute video max au size and max chunck size.
3837        * We do it here because it depends on the frame size only, and
3838        * because we need it for the file size/video bitrate estimations */
3839        pC->uiVideoMaxAuSize =
3840            (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \
3841            *M4MCS_VIDEO_MIN_COMPRESSION_RATIO);
3842        pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize       \
3843            *
3844            M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */
3845
3846        if( 0 == pC->uiVideoMaxAuSize )
3847        {
3848            /* Size may be zero in case of null encoding with unrecognized stream */
3849            M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\
3850                           M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE");
3851            return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
3852        }
3853
3854
3855        /**
3856        * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */
3857
3858        if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
3859        {
3860            switch( pParams->OutputVideoFrameSize )
3861            {
3862                case M4VIDEOEDITING_kSQCIF:
3863                case M4VIDEOEDITING_kQCIF:
3864                case M4VIDEOEDITING_kCIF:
3865                    /* OK */
3866                    break;
3867
3868                default:
3869                    M4OSA_TRACE1_0(
3870                        "M4MCS_setOutputParams():\
3871                        returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263");
3872                    return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263;
3873            }
3874        }
3875
3876        /**
3877        * Check Video Frame rate correctness */
3878        if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat )
3879        {
3880            switch( pParams->OutputVideoFrameRate )
3881            {
3882                case M4VIDEOEDITING_k5_FPS:
3883                    pC->EncodingVideoFramerate = M4ENCODER_k5_FPS;
3884                    break;
3885
3886                case M4VIDEOEDITING_k7_5_FPS:
3887                    pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS;
3888                    break;
3889
3890                case M4VIDEOEDITING_k10_FPS:
3891                    pC->EncodingVideoFramerate = M4ENCODER_k10_FPS;
3892                    break;
3893
3894                case M4VIDEOEDITING_k12_5_FPS:
3895                    pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS;
3896                    break;
3897
3898                case M4VIDEOEDITING_k15_FPS:
3899                    pC->EncodingVideoFramerate = M4ENCODER_k15_FPS;
3900                    break;
3901
3902                case M4VIDEOEDITING_k20_FPS:
3903                    pC->EncodingVideoFramerate = M4ENCODER_k20_FPS;
3904                    break;
3905
3906                case M4VIDEOEDITING_k25_FPS:
3907                    pC->EncodingVideoFramerate = M4ENCODER_k25_FPS;
3908                    break;
3909
3910                case M4VIDEOEDITING_k30_FPS:
3911                    pC->EncodingVideoFramerate = M4ENCODER_k30_FPS;
3912                    break;
3913
3914                default:
3915                    M4OSA_TRACE1_1(
3916                        "M4MCS_setOutputParams: Undefined output video frame rate\
3917                        (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
3918                        pParams->OutputVideoFrameRate);
3919                    return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
3920            }
3921        }
3922
3923        /**
3924        * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */
3925        if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
3926        {
3927            switch( pC->EncodingVideoFramerate )
3928            {
3929                case M4ENCODER_k5_FPS:
3930                case M4ENCODER_k7_5_FPS:
3931                case M4ENCODER_k10_FPS:
3932                case M4ENCODER_k15_FPS:
3933                case M4ENCODER_k30_FPS:
3934                    /* OK */
3935                    break;
3936
3937                default:
3938                    M4OSA_TRACE1_0(
3939                        "M4MCS_setOutputParams():\
3940                        returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263");
3941                    return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263;
3942            }
3943        }
3944    }
3945
3946    /* Set audio parameters */
3947    if( pC->noaudio == M4OSA_FALSE )
3948    {
3949        /**
3950        * Check Audio Format correctness */
3951        switch( pParams->OutputAudioFormat )
3952        {
3953            case M4VIDEOEDITING_kAMR_NB:
3954
3955                err = M4MCS_setCurrentAudioEncoder(pContext,
3956                    pParams->OutputAudioFormat);
3957                M4ERR_CHECK_RETURN(err);
3958
3959                pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
3960                pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
3961                pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
3962                pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID;
3963                break;
3964
3965            case M4VIDEOEDITING_kAAC:
3966
3967                err = M4MCS_setCurrentAudioEncoder(pContext,
3968                    pParams->OutputAudioFormat);
3969                M4ERR_CHECK_RETURN(err);
3970
3971                pC->AudioEncParams.Format = M4ENCODER_kAAC;
3972                pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
3973
3974                switch( pParams->OutputAudioSamplingFrequency )
3975                {
3976                    case M4VIDEOEDITING_k8000_ASF:
3977                        pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
3978                        break;
3979
3980                    case M4VIDEOEDITING_k16000_ASF:
3981                        pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
3982                        break;
3983
3984                    case M4VIDEOEDITING_k22050_ASF:
3985                        pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
3986                        break;
3987
3988                    case M4VIDEOEDITING_k24000_ASF:
3989                        pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
3990                        break;
3991
3992                    case M4VIDEOEDITING_k32000_ASF:
3993                        pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
3994                        break;
3995
3996                    case M4VIDEOEDITING_k44100_ASF:
3997                        pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
3998                        break;
3999
4000                    case M4VIDEOEDITING_k48000_ASF:
4001                        pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
4002                        break;
4003
4004                    case M4VIDEOEDITING_k11025_ASF:
4005                    case M4VIDEOEDITING_k12000_ASF:
4006                    case M4VIDEOEDITING_kDefault_ASF:
4007                        break;
4008                }
4009                    pC->AudioEncParams.ChannelNum =
4010                        (pParams->bAudioMono == M4OSA_TRUE) ? \
4011                        M4ENCODER_kMono : M4ENCODER_kStereo;
4012                    pC->AudioEncParams.SpecifParam.AacParam.Regulation =
4013                        M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
4014                    /* unused */
4015                    pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE;
4016                    pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE;
4017                    pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE;
4018                    pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE;
4019                    /* TODO change into highspeed asap */
4020                    pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
4021                        M4OSA_FALSE;
4022                    break;
4023
4024                    /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
4025                case M4VIDEOEDITING_kMP3:
4026                    err = M4MCS_setCurrentAudioEncoder(pContext,
4027                        pParams->OutputAudioFormat);
4028                    M4ERR_CHECK_RETURN(err);
4029
4030                    pC->AudioEncParams.Format = M4ENCODER_kMP3;
4031                    pC->AudioEncParams.ChannelNum =
4032                        (pParams->bAudioMono == M4OSA_TRUE) ? \
4033                        M4ENCODER_kMono : M4ENCODER_kStereo;
4034
4035                    pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4036
4037                    switch( pParams->OutputAudioSamplingFrequency )
4038                    {
4039                        case M4VIDEOEDITING_k8000_ASF:
4040                            pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4041                            break;
4042
4043                        case M4VIDEOEDITING_k11025_ASF:
4044                            pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz;
4045                            break;
4046
4047                        case M4VIDEOEDITING_k12000_ASF:
4048                            pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz;
4049                            break;
4050
4051                        case M4VIDEOEDITING_k16000_ASF:
4052                            pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4053                            break;
4054
4055                        case M4VIDEOEDITING_k22050_ASF:
4056                            pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
4057                            break;
4058
4059                        case M4VIDEOEDITING_k24000_ASF:
4060                            pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
4061                            break;
4062
4063                        case M4VIDEOEDITING_k32000_ASF:
4064                            pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
4065                            break;
4066
4067                        case M4VIDEOEDITING_k44100_ASF:
4068                            pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
4069                            break;
4070
4071                        case M4VIDEOEDITING_k48000_ASF:
4072                            pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
4073                            break;
4074
4075                        case M4VIDEOEDITING_kDefault_ASF:
4076                            break;
4077                    }
4078
4079                    break;
4080
4081                case M4VIDEOEDITING_kNullAudio:
4082                    if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 )
4083                    {
4084                        /* no encoder needed */
4085                        pC->AudioEncParams.Format = M4ENCODER_kAudioNULL;
4086                        pC->AudioEncParams.Frequency =
4087                            pC->pReaderAudioStream->m_samplingFrequency;
4088                        pC->AudioEncParams.ChannelNum =
4089                            (pC->pReaderAudioStream->m_nbChannels == 1) ? \
4090                            M4ENCODER_kMono : M4ENCODER_kStereo;
4091                    }
4092                    else
4093                    {
4094                        pC->AudioEncParams.Frequency =
4095                            pC->pReaderAudioStream->m_samplingFrequency;
4096                        pC->AudioEncParams.ChannelNum =
4097                            (pC->pReaderAudioStream->m_nbChannels == 1) ? \
4098                            M4ENCODER_kMono : M4ENCODER_kStereo;
4099
4100                        switch( pC->InputFileProperties.AudioStreamType )
4101                        {
4102                            case M4VIDEOEDITING_kAMR_NB:
4103                                M4OSA_TRACE3_0(
4104                                    "M4MCS_setOutputParams calling \
4105                                    M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR");
4106                                err = M4MCS_setCurrentAudioEncoder(pContext,
4107                                    pC->InputFileProperties.AudioStreamType);
4108                                M4ERR_CHECK_RETURN(err);
4109
4110                                pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
4111                                pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4112                                pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
4113
4114                                if( pC->pReaderAudioStream->m_samplingFrequency
4115                                    != 8000 )
4116                                {
4117                                    pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
4118                                }
4119                                pC->AudioEncParams.SpecifParam.AmrSID =
4120                                    M4ENCODER_kAmrNoSID;
4121                                break;
4122
4123                            case M4VIDEOEDITING_kAAC:
4124                                M4OSA_TRACE3_0(
4125                                    "M4MCS_setOutputParams calling \
4126                                    M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC");
4127                                err = M4MCS_setCurrentAudioEncoder(pContext,
4128                                    pC->InputFileProperties.AudioStreamType);
4129                                M4ERR_CHECK_RETURN(err);
4130
4131                                pC->AudioEncParams.Format = M4ENCODER_kAAC;
4132                                pC->AudioEncParams.SpecifParam.AacParam.Regulation =
4133                                    M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
4134                                pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4135                                pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4136
4137                                switch( pC->pReaderAudioStream->
4138                                    m_samplingFrequency )
4139                                {
4140                                case 16000:
4141                                    pC->AudioEncParams.Frequency =
4142                                        M4ENCODER_k16000Hz;
4143                                    break;
4144
4145                                case 22050:
4146                                    pC->AudioEncParams.Frequency =
4147                                        M4ENCODER_k22050Hz;
4148                                    break;
4149
4150                                case 24000:
4151                                    pC->AudioEncParams.Frequency =
4152                                        M4ENCODER_k24000Hz;
4153                                    break;
4154
4155                                case 32000:
4156                                    pC->AudioEncParams.Frequency =
4157                                        M4ENCODER_k32000Hz;
4158                                    break;
4159
4160                                case 44100:
4161                                    pC->AudioEncParams.Frequency =
4162                                        M4ENCODER_k44100Hz;
4163                                    break;
4164
4165                                case 48000:
4166                                    pC->AudioEncParams.Frequency =
4167                                        M4ENCODER_k48000Hz;
4168                                    break;
4169
4170                                default:
4171                                    pC->AudioEncParams.Format = M4ENCODER_kAAC;
4172                                    break;
4173                            }
4174                            /* unused */
4175                            pC->AudioEncParams.SpecifParam.AacParam.bIS =
4176                                M4OSA_FALSE;
4177                            pC->AudioEncParams.SpecifParam.AacParam.bMS =
4178                                M4OSA_FALSE;
4179                            pC->AudioEncParams.SpecifParam.AacParam.bPNS =
4180                                M4OSA_FALSE;
4181                            pC->AudioEncParams.SpecifParam.AacParam.bTNS =
4182                                M4OSA_FALSE;
4183                            /* TODO change into highspeed asap */
4184                            pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
4185                                M4OSA_FALSE;
4186                            break;
4187
4188                        case M4VIDEOEDITING_kMP3:
4189                            M4OSA_TRACE3_0(
4190                                "M4MCS_setOutputParams calling\
4191                                M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3");
4192                            err = M4MCS_setCurrentAudioEncoder(pContext,
4193                                pC->InputFileProperties.AudioStreamType);
4194                            M4ERR_CHECK_RETURN(err);
4195
4196                            pC->AudioEncParams.Format = M4ENCODER_kMP3;
4197                            pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4198
4199                            switch( pC->pReaderAudioStream->
4200                                m_samplingFrequency )
4201                            {
4202                                case 8000:
4203                                    pC->AudioEncParams.Frequency =
4204                                        M4ENCODER_k8000Hz;
4205                                    break;
4206
4207                                case 16000:
4208                                    pC->AudioEncParams.Frequency =
4209                                        M4ENCODER_k16000Hz;
4210                                    break;
4211
4212                                case 22050:
4213                                    pC->AudioEncParams.Frequency =
4214                                        M4ENCODER_k22050Hz;
4215                                    break;
4216
4217                                case 24000:
4218                                    pC->AudioEncParams.Frequency =
4219                                        M4ENCODER_k24000Hz;
4220                                    break;
4221
4222                                case 32000:
4223                                    pC->AudioEncParams.Frequency =
4224                                        M4ENCODER_k32000Hz;
4225                                    break;
4226
4227                                case 44100:
4228                                    pC->AudioEncParams.Frequency =
4229                                        M4ENCODER_k44100Hz;
4230                                    break;
4231
4232                                case 48000:
4233                                    pC->AudioEncParams.Frequency =
4234                                        M4ENCODER_k48000Hz;
4235                                    break;
4236
4237                                default:
4238                                    pC->AudioEncParams.Format = M4ENCODER_kMP3;
4239                                    break;
4240                            }
4241                            break;
4242
4243                        case M4VIDEOEDITING_kEVRC:
4244                        case M4VIDEOEDITING_kUnsupportedAudio:
4245                        default:
4246                            M4OSA_TRACE1_1(
4247                                "M4MCS_setOutputParams: Output audio format (%d) is\
4248                                incompatible with audio effects, returning \
4249                                M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
4250                                pC->InputFileProperties.AudioStreamType);
4251                            return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
4252                        }
4253                    }
4254                    break;
4255                    /* EVRC
4256                    //            case M4VIDEOEDITING_kEVRC:
4257                    //
4258                    //                err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\
4259                    //                    OutputAudioFormat);
4260                    //                M4ERR_CHECK_RETURN(err);
4261                    //
4262                    //                pC->AudioEncParams.Format = M4ENCODER_kEVRC;
4263                    //                pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4264                    //                pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
4265                    //                break; */
4266
4267                default:
4268                    M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\
4269                                   returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
4270                                   pParams->OutputAudioFormat);
4271                    return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
4272        }
4273    }
4274
4275    if( pParams->pOutputPCMfile != M4OSA_NULL )
4276    {
4277        pC->pOutputPCMfile = pParams->pOutputPCMfile;
4278
4279        /* Open output PCM file */
4280        pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile),
4281            pParams->pOutputPCMfile, M4OSA_kFileWrite);
4282    }
4283    else
4284    {
4285        pC->pOutputPCMfile = M4OSA_NULL;
4286    }
4287
4288    /*Store media rendering parameter into the internal context*/
4289    pC->MediaRendering = pParams->MediaRendering;
4290
4291    /* Add audio effects*/
4292    /*Copy MCS effects structure into internal context*/
4293    if( pParams->nbEffects > 0 )
4294    {
4295        M4OSA_UInt32 j = 0;
4296        pC->nbEffects = pParams->nbEffects;
4297        pC->pEffects = (M4MCS_EffectSettings *)M4OSA_32bitAlignedMalloc(pC->nbEffects \
4298            *sizeof(M4MCS_EffectSettings), M4MCS,
4299            (M4OSA_Char *)"Allocation of effects list");
4300
4301        if( pC->pEffects == M4OSA_NULL )
4302        {
4303            M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error");
4304            return M4ERR_ALLOC;
4305        }
4306
4307        for ( j = 0; j < pC->nbEffects; j++ )
4308        {
4309            /* Copy effect to "local" structure */
4310            memcpy((void *) &(pC->pEffects[j]),
4311                (void *) &(pParams->pEffects[j]),
4312                sizeof(M4MCS_EffectSettings));
4313
4314            switch( pC->pEffects[j].AudioEffectType )
4315            {
4316                case M4MCS_kAudioEffectType_None:
4317                    M4OSA_TRACE3_1(
4318                        "M4MCS_setOutputParams(): effect type %i is None", j);
4319                    pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4320                    pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL;
4321                    break;
4322
4323                case M4MCS_kAudioEffectType_FadeIn:
4324                    M4OSA_TRACE3_1(
4325                        "M4MCS_setOutputParams(): effect type %i is FadeIn", j);
4326                    pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4327                    pC->pEffects[j].ExtAudioEffectFct =
4328                        M4MCS_editAudioEffectFct_FadeIn;
4329                    break;
4330
4331                case M4MCS_kAudioEffectType_FadeOut:
4332                    M4OSA_TRACE3_1(
4333                        "M4MCS_setOutputParams(): effect type %i is FadeOut",
4334                        j);
4335                    pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4336                    pC->pEffects[j].ExtAudioEffectFct =
4337                        M4MCS_editAudioEffectFct_FadeOut;
4338                    break;
4339
4340                case M4MCS_kAudioEffectType_External:
4341                    M4OSA_TRACE3_1(
4342                        "M4MCS_setOutputParams(): effect type %i is External",
4343                        j);
4344
4345                    if( pParams->pEffects != M4OSA_NULL )
4346                    {
4347                        if( pParams->pEffects[j].ExtAudioEffectFct
4348                            == M4OSA_NULL )
4349                        {
4350                            M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\
4351                                           associated to external effect number %i", j);
4352                            return M4ERR_PARAMETER;
4353                        }
4354                        pC->pEffects[j].pExtAudioEffectFctCtxt =
4355                            pParams->pEffects[j].pExtAudioEffectFctCtxt;
4356
4357                        pC->pEffects[j].ExtAudioEffectFct =
4358                            pParams->pEffects[j].ExtAudioEffectFct;
4359                    }
4360
4361                    break;
4362
4363                default:
4364                    M4OSA_TRACE1_0(
4365                        "M4MCS_setOutputParams(): effect type not recognized");
4366                    return M4ERR_PARAMETER;
4367            }
4368        }
4369    }
4370    else
4371    {
4372        pC->nbEffects = 0;
4373        pC->pEffects = M4OSA_NULL;
4374    }
4375
4376    /**
4377    * Update state automaton */
4378    pC->State = M4MCS_kState_SET;
4379
4380    /**
4381    * Return with no error */
4382    M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR");
4383    return M4NO_ERROR;
4384}
4385
4386/**
4387 ******************************************************************************
4388 * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
4389 * @brief   Set the values of the encoding parameters
4390 * @note    Must be called before M4MCS_checkParamsAndStart().
4391 * @param   pContext           (IN) MCS context
4392 * @param   pRates             (IN) Transcoding parameters
4393 * @return  M4NO_ERROR:         No error
4394 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
4395 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
4396 * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps)
4397 * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2
4398 *                                            for amr, 8 for mp3)
4399 * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals
4400 * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip
4401 *                                                     duration
4402 * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time
4403 * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given
4404 *                                             bitrates
4405 * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps)
4406 * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:  Video bitrate too low
4407 ******************************************************************************
4408 */
4409M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext,
4410                                  M4MCS_EncodingParams *pRates )
4411{
4412    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
4413    M4OSA_UInt32 j = 0;
4414
4415    M4OSA_TRACE2_2(
4416        "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x",
4417        pContext, pRates);
4418
4419    /**
4420    * Check input parameters */
4421    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
4422        "M4MCS_setEncodingParams: pContext is M4OSA_NULL");
4423    M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER,
4424        "M4MCS_setEncodingParams: pRates is M4OSA_NULL");
4425
4426#ifdef M4MCS_SUPPORT_STILL_PICTURE
4427
4428    if( pC->m_bIsStillPicture )
4429    {
4430        /**
4431        * Call the corresponding still picture MCS function*/
4432        return M4MCS_stillPicSetEncodingParams(pC, pRates);
4433    }
4434
4435#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
4436
4437    /**
4438    * Check state automaton */
4439
4440    if( M4MCS_kState_SET != pC->State )
4441    {
4442        M4OSA_TRACE1_1(
4443            "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE",
4444            pC->State);
4445        return M4ERR_STATE;
4446    }
4447
4448    /* Set given values */
4449    pC->uiVideoBitrate = pRates->OutputVideoBitrate;
4450    pC->uiAudioBitrate = pRates->OutputAudioBitrate;
4451    pC->uiBeginCutTime = pRates->BeginCutTime;
4452    pC->uiEndCutTime = pRates->EndCutTime;
4453    pC->uiMaxFileSize = pRates->OutputFileSize;
4454
4455    /**
4456    * Check begin cut time validity */
4457    if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration )
4458    {
4459        M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\
4460                       returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION",
4461                       pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration);
4462        return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION;
4463    }
4464
4465    /**
4466    * If end cut time is too large, we set it to the clip duration */
4467    if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration )
4468    {
4469        pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
4470    }
4471
4472    /**
4473    * Check end cut time validity */
4474    if( pC->uiEndCutTime > 0 )
4475    {
4476        if( pC->uiEndCutTime < pC->uiBeginCutTime )
4477        {
4478            M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \
4479                           returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT",
4480                           pC->uiBeginCutTime, pC->uiEndCutTime);
4481            return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT;
4482        }
4483
4484        if( pC->uiEndCutTime == pC->uiBeginCutTime )
4485        {
4486            M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\
4487                           returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT",
4488                           pC->uiBeginCutTime, pC->uiEndCutTime);
4489            return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
4490        }
4491    }
4492
4493    /**
4494    * FlB 2009.03.04: check audio effects start time and duration validity*/
4495    for ( j = 0; j < pC->nbEffects; j++ )
4496    {
4497        M4OSA_UInt32 outputEndCut = pC->uiEndCutTime;
4498
4499        if( pC->uiEndCutTime == 0 )
4500        {
4501            outputEndCut = pC->InputFileProperties.uiClipDuration;
4502        }
4503
4504        if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) )
4505        {
4506            M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\
4507                           duration (%d,%d), returning M4ERR_PARAMETER",
4508                           pC->pEffects[j].uiStartTime,
4509                           (pC->uiEndCutTime - pC->uiBeginCutTime));
4510            return M4ERR_PARAMETER;
4511        }
4512
4513        if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \
4514            (outputEndCut - pC->uiBeginCutTime) )
4515        {
4516            /* Re-adjust the effect duration until the end of the output clip*/
4517            pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \
4518                pC->pEffects[j].uiStartTime;
4519        }
4520    }
4521
4522    /* Check audio bitrate consistency */
4523    if( ( pC->noaudio == M4OSA_FALSE)
4524        && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) )
4525    {
4526        if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
4527        {
4528            if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
4529            {
4530                if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS )
4531                    return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4532
4533                if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS )
4534                    return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4535            }
4536            //EVRC
4537            //            else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
4538            //            {
4539            //                if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS)
4540            //                    return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4541            //                if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS)
4542            //                     return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4543            //            }
4544            /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
4545            else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
4546            {
4547                if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz )
4548                {
4549                    /*Mpeg layer 1*/
4550                    if( pC->uiAudioBitrate > 320000 )
4551                        return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4552
4553                    if( pC->uiAudioBitrate < 32000 )
4554                        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4555                }
4556                else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz )
4557                {
4558                    /*Mpeg layer 2*/
4559                    if( pC->uiAudioBitrate > 160000 )
4560                        return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4561
4562                    if( ( pC->uiAudioBitrate < 8000
4563                        && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4564                        || (pC->uiAudioBitrate < 16000
4565                        && pC->AudioEncParams.ChannelNum
4566                        == M4ENCODER_kStereo) )
4567                        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4568                }
4569                else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz
4570                    || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz
4571                    || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz )
4572                {
4573                    /*Mpeg layer 2.5*/
4574                    if( pC->uiAudioBitrate > 64000 )
4575                        return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4576
4577                    if( ( pC->uiAudioBitrate < 8000
4578                        && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4579                        || (pC->uiAudioBitrate < 16000
4580                        && pC->AudioEncParams.ChannelNum
4581                        == M4ENCODER_kStereo) )
4582                        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4583                }
4584                else
4585                {
4586                    M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\
4587                                   (%d)", pC->AudioEncParams.Frequency);
4588                    return M4ERR_PARAMETER;
4589                }
4590            }
4591            else
4592            {
4593                if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS )
4594                    return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4595
4596                if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono )
4597                {
4598                    if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS )
4599                        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4600                }
4601                else
4602                {
4603                    if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS )
4604                        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4605                }
4606            }
4607        }
4608    }
4609    else
4610    {
4611        /* NULL audio : copy input file bitrate */
4612        pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
4613    }
4614
4615    /* Check video bitrate consistency */
4616    if( ( pC->novideo == M4OSA_FALSE)
4617        && (pC->EncodingVideoFormat != M4ENCODER_kNULL) )
4618    {
4619        if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate )
4620        {
4621            if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4622                return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH;
4623
4624            if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS )
4625                return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
4626        }
4627    }
4628    else
4629    {
4630        /* NULL video : copy input file bitrate */
4631        pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
4632    }
4633
4634    if( pRates->OutputVideoTimescale <= 30000
4635        && pRates->OutputVideoTimescale > 0 )
4636    {
4637        pC->outputVideoTimescale = pRates->OutputVideoTimescale;
4638    }
4639
4640    /* Check file size */
4641    return M4MCS_intCheckMaxFileSize(pC);
4642}
4643
4644/**
4645 ******************************************************************************
4646 * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
4647 * @brief   Get the extended values of the encoding parameters
4648 * @note    Could be called after M4MCS_setEncodingParams.
4649 * @param   pContext           (IN) MCS context
4650 * @param   pRates             (OUT) Transcoding parameters
4651 * @return  M4NO_ERROR:         No error
4652 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
4653 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
4654 * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration
4655 *                                             clip = encoding is impossible
4656 ******************************************************************************
4657 */
4658M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext,
4659                                          M4MCS_EncodingParams *pRates )
4660{
4661    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
4662
4663    M4OSA_Int32 minaudiobitrate;
4664    M4OSA_Int32 minvideobitrate;
4665    M4OSA_Int32 maxcombinedbitrate;
4666
4667    M4OSA_Int32 calcbitrate;
4668
4669    M4OSA_UInt32 maxduration;
4670    M4OSA_UInt32 calcduration;
4671
4672    M4OSA_Bool fixed_audio = M4OSA_FALSE;
4673    M4OSA_Bool fixed_video = M4OSA_FALSE;
4674
4675#ifdef M4MCS_SUPPORT_STILL_PICTURE
4676
4677    if( pC->m_bIsStillPicture )
4678    {
4679        /**
4680        * Call the corresponding still picture MCS function*/
4681        return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates);
4682    }
4683
4684#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
4685
4686    pRates->OutputVideoBitrate =
4687        M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0);
4688    pRates->OutputAudioBitrate =
4689        M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0);
4690    pRates->BeginCutTime = pC->uiBeginCutTime;
4691    pRates->EndCutTime = pC->uiEndCutTime;
4692    pRates->OutputFileSize = pC->uiMaxFileSize;
4693
4694    /**
4695    * Check state automaton */
4696    if( M4MCS_kState_SET != pC->State )
4697    {
4698        M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\
4699                       returning M4ERR_STATE", pC->State);
4700        return M4ERR_STATE;
4701    }
4702
4703    /* Compute min audio bitrate */
4704    if( pC->noaudio )
4705    {
4706        fixed_audio = M4OSA_TRUE;
4707        pRates->OutputAudioBitrate = 0;
4708        minaudiobitrate = 0;
4709    }
4710    else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
4711    {
4712        fixed_audio = M4OSA_TRUE;
4713        pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
4714        minaudiobitrate = pC->InputFileProperties.uiAudioBitrate;
4715    }
4716    else
4717    {
4718        if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
4719        {
4720            fixed_audio = M4OSA_TRUE;
4721            pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS;
4722            minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS;
4723        }
4724        //EVRC
4725        //        if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
4726        //        {
4727        //            fixed_audio = M4OSA_TRUE;
4728        //            pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS;
4729        //            minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS;
4730        //        }
4731        /*FlB 26.02.2009: add mp3 as mcs output format*/
4732        else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
4733        {
4734            minaudiobitrate =
4735                M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1,
4736                                             for both mono and stereo channels*/
4737        }
4738        else
4739        {
4740            minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4741                ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
4742        }
4743    }
4744
4745    /* Check audio bitrate is in the correct range */
4746    if( fixed_audio == M4OSA_FALSE )
4747    {
4748        if( ( pC->uiAudioBitrate > 0)
4749            && (pRates->OutputAudioBitrate < minaudiobitrate) )
4750        {
4751            pRates->OutputAudioBitrate = minaudiobitrate;
4752        }
4753
4754        if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
4755        {
4756            pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4757        }
4758    }
4759
4760    /* Compute min video bitrate */
4761    if( pC->novideo )
4762    {
4763        fixed_video = M4OSA_TRUE;
4764        pRates->OutputVideoBitrate = 0;
4765        minvideobitrate = 0;
4766    }
4767    else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
4768    {
4769        fixed_video = M4OSA_TRUE;
4770        pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
4771        minvideobitrate = pC->InputFileProperties.uiVideoBitrate;
4772    }
4773    else
4774    {
4775        minvideobitrate = M4VIDEOEDITING_k16_KBPS;
4776    }
4777
4778    /* Check video bitrate is in the correct range */
4779    if( fixed_video == M4OSA_FALSE )
4780    {
4781        if( ( pC->uiVideoBitrate > 0)
4782            && (pRates->OutputVideoBitrate < minvideobitrate) )
4783        {
4784            pRates->OutputVideoBitrate = minvideobitrate;
4785        }
4786        /*+ New Encoder bitrates */
4787        if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4788        {
4789            pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
4790        }
4791        /*- New Encoder bitrates */
4792    }
4793
4794    /* Check cut times are in correct range */
4795    if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration)
4796        || (( pRates->BeginCutTime >= pRates->EndCutTime)
4797        && (pRates->EndCutTime > 0)) )
4798    {
4799        pRates->BeginCutTime = 0;
4800        pRates->EndCutTime = 0;
4801    }
4802
4803    if( pRates->EndCutTime == 0 )
4804        calcduration =
4805        pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
4806    else
4807        calcduration = pRates->EndCutTime - pRates->BeginCutTime;
4808
4809    /* priority 1 : max file size */
4810    if( pRates->OutputFileSize == 0 )
4811    {
4812        /* we can put maximum values for all undefined parameters */
4813        if( pRates->EndCutTime == 0 )
4814        {
4815            pRates->EndCutTime = pC->InputFileProperties.uiClipDuration;
4816        }
4817
4818        if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate)
4819            && (fixed_audio == M4OSA_FALSE) )
4820        {
4821            pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4822        }
4823
4824        if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate)
4825            && (fixed_video == M4OSA_FALSE) )
4826        {
4827            /*+ New Encoder bitrates */
4828            pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
4829            /*- New Encoder bitrates */
4830        }
4831    }
4832    else
4833    {
4834        /* compute max duration */
4835        maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
4836            / M4MCS_MOOV_OVER_FILESIZE_RATIO
4837            / (minvideobitrate + minaudiobitrate) * 8000.0);
4838
4839        if( maxduration
4840            + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
4841        {
4842            maxduration =
4843                pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
4844        }
4845
4846        /* priority 2 : cut times */
4847        if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) )
4848        {
4849            if( calcduration > maxduration )
4850            {
4851                calcduration = maxduration;
4852            }
4853
4854            if( calcduration == 0 )
4855            {
4856                return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
4857            }
4858
4859            maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
4860                / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0));
4861
4862            /* audio and video bitrates */
4863            if( ( pRates->OutputAudioBitrate
4864                == M4VIDEOEDITING_kUndefinedBitrate)
4865                && (pRates->OutputVideoBitrate
4866                == M4VIDEOEDITING_kUndefinedBitrate) )
4867            {
4868                /* set audio = 1/3 and video = 2/3 */
4869                if( fixed_audio == M4OSA_FALSE )
4870                {
4871                    if( pC->novideo )
4872                        pRates->OutputAudioBitrate =
4873                        M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0);
4874                    else
4875                        pRates->OutputAudioBitrate =
4876                        M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3,
4877                        0);
4878
4879                    if( pRates->OutputAudioBitrate < minaudiobitrate )
4880                        pRates->OutputAudioBitrate = minaudiobitrate;
4881
4882                    if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
4883                        pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4884                }
4885
4886                if( fixed_video == M4OSA_FALSE )
4887                {
4888                    pRates->OutputVideoBitrate =
4889                        M4MCS_intGetNearestBitrate(maxcombinedbitrate
4890                        - pRates->OutputAudioBitrate, 0);
4891
4892                    if( pRates->OutputVideoBitrate < minvideobitrate )
4893                        pRates->OutputVideoBitrate = minvideobitrate;
4894
4895                    if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4896                        pRates->OutputVideoBitrate =
4897                        M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
4898                                                bitrates */
4899                }
4900            }
4901            else
4902            {
4903                /* priority 3 : audio bitrate */
4904                if( pRates->OutputAudioBitrate
4905                    != M4VIDEOEDITING_kUndefinedBitrate )
4906                {
4907                    while( ( fixed_audio == M4OSA_FALSE)
4908                        && (pRates->OutputAudioBitrate >= minaudiobitrate)
4909                        && (pRates->OutputAudioBitrate
4910                        + minvideobitrate > maxcombinedbitrate) )
4911                    {
4912                        pRates->OutputAudioBitrate =
4913                            M4MCS_intGetNearestBitrate(
4914                            pRates->OutputAudioBitrate, -1);
4915                    }
4916
4917                    if( ( fixed_audio == M4OSA_FALSE)
4918                        && (pRates->OutputAudioBitrate < minaudiobitrate) )
4919                    {
4920                        pRates->OutputAudioBitrate = minaudiobitrate;
4921                    }
4922
4923                    calcbitrate = M4MCS_intGetNearestBitrate(
4924                                    maxcombinedbitrate
4925                                    - pRates->OutputAudioBitrate, 0);
4926
4927                    if( calcbitrate < minvideobitrate )
4928                        calcbitrate = minvideobitrate;
4929
4930                    if( calcbitrate > M4VIDEOEDITING_k8_MBPS )
4931                        calcbitrate = M4VIDEOEDITING_k8_MBPS;
4932
4933                    if( ( fixed_video == M4OSA_FALSE)
4934                        && (( pRates->OutputVideoBitrate
4935                        == M4VIDEOEDITING_kUndefinedBitrate)
4936                        || (pRates->OutputVideoBitrate > calcbitrate)) )
4937                    {
4938                        pRates->OutputVideoBitrate = calcbitrate;
4939                    }
4940                }
4941                else
4942                {
4943                    /* priority 4 : video bitrate */
4944                    if( pRates->OutputVideoBitrate
4945                        != M4VIDEOEDITING_kUndefinedBitrate )
4946                    {
4947                        while( ( fixed_video == M4OSA_FALSE)
4948                            && (pRates->OutputVideoBitrate >= minvideobitrate)
4949                            && (pRates->OutputVideoBitrate
4950                            + minaudiobitrate > maxcombinedbitrate) )
4951                        {
4952                            pRates->OutputVideoBitrate =
4953                                M4MCS_intGetNearestBitrate(
4954                                pRates->OutputVideoBitrate, -1);
4955                        }
4956
4957                        if( ( fixed_video == M4OSA_FALSE)
4958                            && (pRates->OutputVideoBitrate < minvideobitrate) )
4959                        {
4960                            pRates->OutputVideoBitrate = minvideobitrate;
4961                        }
4962
4963                        calcbitrate =
4964                            M4MCS_intGetNearestBitrate(maxcombinedbitrate
4965                            - pRates->OutputVideoBitrate, 0);
4966
4967                        if( calcbitrate < minaudiobitrate )
4968                            calcbitrate = minaudiobitrate;
4969
4970                        if( calcbitrate > M4VIDEOEDITING_k96_KBPS )
4971                            calcbitrate = M4VIDEOEDITING_k96_KBPS;
4972
4973                        if( ( fixed_audio == M4OSA_FALSE)
4974                            && (( pRates->OutputAudioBitrate
4975                            == M4VIDEOEDITING_kUndefinedBitrate)
4976                            || (pRates->OutputAudioBitrate > calcbitrate)) )
4977                        {
4978                            pRates->OutputAudioBitrate = calcbitrate;
4979                        }
4980                    }
4981                }
4982            }
4983        }
4984        else
4985        {
4986            /* priority 3 : audio bitrate */
4987            if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
4988            {
4989                /* priority 4 : video bitrate */
4990                if( pRates->OutputVideoBitrate
4991                    != M4VIDEOEDITING_kUndefinedBitrate )
4992                {
4993                    /* compute max duration */
4994                    maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
4995                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
4996                        / (pRates->OutputVideoBitrate
4997                        + pRates->OutputAudioBitrate) * 8000.0);
4998
4999                    if( maxduration + pRates->BeginCutTime
5000                        > pC->InputFileProperties.uiClipDuration )
5001                    {
5002                        maxduration = pC->InputFileProperties.uiClipDuration
5003                            - pRates->BeginCutTime;
5004                    }
5005
5006                    if( calcduration > maxduration )
5007                    {
5008                        calcduration = maxduration;
5009                    }
5010
5011                    if( calcduration == 0 )
5012                    {
5013                        return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5014                    }
5015                }
5016                else
5017                {
5018                    /* start with min video bitrate */
5019                    pRates->OutputVideoBitrate = minvideobitrate;
5020
5021                    /* compute max duration */
5022                    maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5023                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5024                        / (pRates->OutputVideoBitrate
5025                        + pRates->OutputAudioBitrate) * 8000.0);
5026
5027                    if( maxduration + pRates->BeginCutTime
5028                        > pC->InputFileProperties.uiClipDuration )
5029                    {
5030                        maxduration = pC->InputFileProperties.uiClipDuration
5031                            - pRates->BeginCutTime;
5032                    }
5033
5034                    if( calcduration > maxduration )
5035                    {
5036                        calcduration = maxduration;
5037                    }
5038
5039                    if( calcduration == 0 )
5040                    {
5041                        return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5042                    }
5043
5044                    /* search max possible video bitrate */
5045                    maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5046                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5047                        / (calcduration / 8000.0));
5048
5049                    while( ( fixed_video == M4OSA_FALSE)
5050                        && (pRates->OutputVideoBitrate
5051                        < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */
5052                    {
5053                        calcbitrate = M4MCS_intGetNearestBitrate(
5054                            pRates->OutputVideoBitrate, +1);
5055
5056                        if( calcbitrate
5057                            + pRates->OutputAudioBitrate <= maxcombinedbitrate )
5058                            pRates->OutputVideoBitrate = calcbitrate;
5059                        else
5060                            break;
5061                    }
5062                }
5063            }
5064            else
5065            {
5066                /* priority 4 : video bitrate */
5067                if( pRates->OutputVideoBitrate
5068                    != M4VIDEOEDITING_kUndefinedBitrate )
5069                {
5070                    /* start with min audio bitrate */
5071                    pRates->OutputAudioBitrate = minaudiobitrate;
5072
5073                    /* compute max duration */
5074                    maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5075                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5076                        / (pRates->OutputVideoBitrate
5077                        + pRates->OutputAudioBitrate) * 8000.0);
5078
5079                    if( maxduration + pRates->BeginCutTime
5080                        > pC->InputFileProperties.uiClipDuration )
5081                    {
5082                        maxduration = pC->InputFileProperties.uiClipDuration
5083                            - pRates->BeginCutTime;
5084                    }
5085
5086                    if( calcduration > maxduration )
5087                    {
5088                        calcduration = maxduration;
5089                    }
5090
5091                    if( calcduration == 0 )
5092                    {
5093                        return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5094                    }
5095
5096                    /* search max possible audio bitrate */
5097                    maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5098                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5099                        / (calcduration / 8000.0));
5100
5101                    while( ( fixed_audio == M4OSA_FALSE)
5102                        && (pRates->OutputAudioBitrate
5103                        < M4VIDEOEDITING_k96_KBPS) )
5104                    {
5105                        calcbitrate = M4MCS_intGetNearestBitrate(
5106                            pRates->OutputAudioBitrate, +1);
5107
5108                        if( calcbitrate
5109                            + pRates->OutputVideoBitrate <= maxcombinedbitrate )
5110                            pRates->OutputAudioBitrate = calcbitrate;
5111                        else
5112                            break;
5113                    }
5114                }
5115                else
5116                {
5117                    /* compute max duration */
5118                    maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5119                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5120                        / (minvideobitrate + minaudiobitrate) * 8000.0);
5121
5122                    if( maxduration + pRates->BeginCutTime
5123                        > pC->InputFileProperties.uiClipDuration )
5124                    {
5125                        maxduration = pC->InputFileProperties.uiClipDuration
5126                            - pRates->BeginCutTime;
5127                    }
5128
5129                    if( calcduration > maxduration )
5130                    {
5131                        calcduration = maxduration;
5132                    }
5133
5134                    if( calcduration == 0 )
5135                    {
5136                        return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5137                    }
5138
5139                    /* set audio = 1/3 and video = 2/3 */
5140                    maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5141                        / M4MCS_MOOV_OVER_FILESIZE_RATIO
5142                        / (calcduration / 8000.0));
5143
5144                    if( fixed_audio == M4OSA_FALSE )
5145                    {
5146                        if( pC->novideo )
5147                            pRates->OutputAudioBitrate =
5148                            M4MCS_intGetNearestBitrate(maxcombinedbitrate,
5149                            0);
5150                        else
5151                            pRates->OutputAudioBitrate =
5152                            M4MCS_intGetNearestBitrate(maxcombinedbitrate
5153                            / 3, 0);
5154
5155                        if( pRates->OutputAudioBitrate < minaudiobitrate )
5156                            pRates->OutputAudioBitrate = minaudiobitrate;
5157
5158                        if( pRates->OutputAudioBitrate
5159                        > M4VIDEOEDITING_k96_KBPS )
5160                        pRates->OutputAudioBitrate =
5161                        M4VIDEOEDITING_k96_KBPS;
5162                    }
5163
5164                    if( fixed_video == M4OSA_FALSE )
5165                    {
5166                        pRates->OutputVideoBitrate =
5167                            M4MCS_intGetNearestBitrate(maxcombinedbitrate
5168                            - pRates->OutputAudioBitrate, 0);
5169
5170                        if( pRates->OutputVideoBitrate < minvideobitrate )
5171                            pRates->OutputVideoBitrate = minvideobitrate;
5172
5173                        if( pRates->OutputVideoBitrate
5174                        > M4VIDEOEDITING_k8_MBPS )
5175                        pRates->OutputVideoBitrate =
5176                        M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
5177                                                bitrates */
5178                    }
5179                }
5180            }
5181        }
5182    }
5183
5184    /* recompute max duration with final bitrates */
5185    if( pRates->OutputFileSize > 0 )
5186    {
5187        maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5188            / M4MCS_MOOV_OVER_FILESIZE_RATIO
5189            / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
5190            * 8000.0);
5191    }
5192    else
5193    {
5194        maxduration = pC->InputFileProperties.uiClipDuration;
5195    }
5196
5197    if( maxduration
5198        + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
5199    {
5200        maxduration =
5201            pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
5202    }
5203
5204    if( pRates->EndCutTime == 0 )
5205    {
5206        pRates->EndCutTime = pRates->BeginCutTime + maxduration;
5207    }
5208    else
5209    {
5210        calcduration = pRates->EndCutTime - pRates->BeginCutTime;
5211
5212        if( calcduration > maxduration )
5213        {
5214            pRates->EndCutTime = pRates->BeginCutTime + maxduration;
5215        }
5216    }
5217
5218    /* Should never happen : constraints are too strong */
5219    if( pRates->EndCutTime == pRates->BeginCutTime )
5220    {
5221        return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5222    }
5223
5224    /* estimated resulting file size */
5225    pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
5226        * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
5227        * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0));
5228
5229    return M4NO_ERROR;
5230}
5231
5232/**
5233 ******************************************************************************
5234 * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext)
5235 * @brief   Check parameters to start
5236 * @note
5237 * @param   pContext           (IN) MCS context
5238 * @return  M4NO_ERROR:         No error
5239 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
5240 * @return  M4ERR_STATE:        MCS is not in an appropriate state for
5241 *                              this function to be called
5242 * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH:
5243 *                              Audio bitrate too high (we limit to 96 kbps)
5244 * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW:
5245 *                              Audio bitrate is too low (16 kbps min for aac,
5246 *                              12.2 for amr, 8 for mp3)
5247 * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT:
5248 *                              Begin cut and End cut are equals
5249 * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION:
5250 *                              Begin cut time is larger than the input
5251 *                              clip duration
5252 * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT:
5253 *                              End cut time is smaller than begin cut time
5254 * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL:
5255 *                              Not enough space to store whole output
5256 *                              file at given bitrates
5257 * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH:
5258 *                              Video bitrate too high (we limit to 800 kbps)
5259 * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:
5260 *                              Video bitrate too low
5261 ******************************************************************************
5262 */
5263M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext )
5264{
5265    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
5266    M4MCS_EncodingParams VerifyRates;
5267    M4OSA_ERR err;
5268
5269    /**
5270    * Check input parameters */
5271    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
5272        "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL");
5273
5274#ifdef M4MCS_SUPPORT_STILL_PICTURE
5275
5276    if( pC->m_bIsStillPicture )
5277    {
5278        /**
5279        * Call the corresponding still picture MCS function*/
5280        return M4MCS_stillPicCheckParamsAndStart(pC);
5281    }
5282
5283#endif /*M4MCS_SUPPORT_STILL_PICTURE*/
5284
5285    /**
5286    * Check state automaton */
5287
5288    if( M4MCS_kState_SET != pC->State )
5289    {
5290        M4OSA_TRACE1_1(
5291            "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE",
5292            pC->State);
5293        return M4ERR_STATE;
5294    }
5295
5296    /* Audio bitrate should not stay undefined at this point */
5297    if( ( pC->noaudio == M4OSA_FALSE)
5298        && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL)
5299        && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
5300    {
5301        M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate");
5302        return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
5303    }
5304
5305    /* Video bitrate should not stay undefined at this point */
5306    if( ( pC->novideo == M4OSA_FALSE)
5307        && (pC->EncodingVideoFormat != M4ENCODER_kNULL)
5308        && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
5309    {
5310        M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate");
5311        return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
5312    }
5313
5314    /* Set end cut time if necessary (not an error) */
5315    if( pC->uiEndCutTime == 0 )
5316    {
5317        pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
5318    }
5319
5320    /* Force a re-set to check validity of parameters */
5321    VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate;
5322    VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate;
5323    VerifyRates.BeginCutTime = pC->uiBeginCutTime;
5324    VerifyRates.EndCutTime = pC->uiEndCutTime;
5325    VerifyRates.OutputFileSize = pC->uiMaxFileSize;
5326    VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale;
5327
5328    err = M4MCS_setEncodingParams(pContext, &VerifyRates);
5329
5330    /**
5331    * Check parameters consistency */
5332    if( err != M4NO_ERROR )
5333    {
5334        M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found");
5335        return err;
5336    }
5337
5338    /**
5339    * All is OK : update state automaton */
5340    pC->uiEncVideoBitrate = pC->uiVideoBitrate;
5341    pC->AudioEncParams.Bitrate = pC->uiAudioBitrate;
5342
5343#ifdef M4MCS_WITH_FAST_OPEN
5344    /**
5345    * Remake the open if it was done in fast mode */
5346
5347    if( M4OSA_TRUE == pC->bFileOpenedInFastMode )
5348    {
5349        /* Close the file opened in fast mode */
5350        M4MCS_intCleanUp_ReadersDecoders(pC);
5351
5352        pC->State = M4MCS_kState_CREATED;
5353
5354        /* Reopen it in normal mode */
5355        err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType,
5356            pC->pOutputFile, pC->pTemporaryFile);
5357
5358        if( err != M4NO_ERROR )
5359        {
5360            M4OSA_TRACE1_1(
5361                "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err);
5362            return err;
5363        }
5364    }
5365
5366#endif /* M4MCS_WITH_FAST_OPEN */
5367
5368    pC->State = M4MCS_kState_READY;
5369
5370    return M4NO_ERROR;
5371}
5372
5373/**
5374 ******************************************************************************
5375 * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC)
5376 ******************************************************************************
5377 */
5378static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC )
5379{
5380    M4OSA_ERR err;
5381    M4ENCODER_Header *encHeader;
5382
5383    /**
5384    * Prepare the video decoder */
5385    err = M4MCS_intPrepareVideoDecoder(pC);
5386
5387    if( M4NO_ERROR != err )
5388    {
5389        M4OSA_TRACE1_1(
5390            "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x",
5391            err);
5392        return err;
5393    }
5394
5395    if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
5396        && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
5397    {
5398        pC->bH264Trim = M4OSA_TRUE;
5399    }
5400
5401    /**
5402    * Prepare the video encoder */
5403    err = M4MCS_intPrepareVideoEncoder(pC);
5404
5405    if( M4NO_ERROR != err )
5406    {
5407        M4OSA_TRACE1_1(
5408            "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x",
5409            err);
5410        return err;
5411    }
5412
5413    if( ( pC->uiBeginCutTime != 0)
5414        && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
5415        && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
5416    {
5417
5418        err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
5419            M4ENCODER_kOptionID_H264ProcessNALUContext,
5420            (M4OSA_DataOption)pC->m_pInstance);
5421
5422        if( err != M4NO_ERROR )
5423        {
5424            M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
5425                err);
5426            return err;
5427        }
5428
5429        err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
5430            M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr,
5431            (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU);
5432
5433        if( err != M4NO_ERROR )
5434        {
5435            M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
5436                err);
5437            return err;
5438        }
5439
5440        err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt,
5441            M4ENCODER_kOptionID_EncoderHeader,
5442            (M4OSA_DataOption) &encHeader);
5443
5444        if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) )
5445        {
5446            M4OSA_TRACE1_1(
5447                "M4MCS_close: failed to get the encoder header (err 0x%x)",
5448                err);
5449            /**< no return here, we still have stuff to deallocate after close, even if it fails.*/
5450        }
5451        else
5452        {
5453            // Handle DSI first bits
5454#define SPS_START_POS 6
5455
5456            pC->m_pInstance->m_encoderSPSSize =
5457                ( encHeader->pBuf[SPS_START_POS] << 8)
5458                + encHeader->pBuf[SPS_START_POS + 1];
5459            pC->m_pInstance->m_pEncoderSPS =
5460                (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2;
5461
5462            pC->m_pInstance->m_encoderPPSSize =
5463                ( encHeader->pBuf[SPS_START_POS + 3
5464                + pC->m_pInstance->m_encoderSPSSize] << 8)
5465                + encHeader->pBuf[SPS_START_POS + 4
5466                + pC->m_pInstance->m_encoderSPSSize];
5467            pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5
5468                + pC->m_pInstance->m_encoderSPSSize;
5469
5470            /* Check the DSI integrity */
5471            if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize
5472                + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) )
5473            {
5474                M4OSA_TRACE1_3(
5475                    "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d",
5476                    encHeader->Size, pC->m_pInstance->m_encoderSPSSize,
5477                    pC->m_pInstance->m_encoderPPSSize);
5478                return M4ERR_PARAMETER;
5479            }
5480        }
5481    }
5482
5483    /**
5484    * Prepare audio processing */
5485    err = M4MCS_intPrepareAudioProcessing(pC);
5486
5487    if( M4NO_ERROR != err )
5488    {
5489        M4OSA_TRACE1_1(
5490            "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x",
5491            err);
5492        return err;
5493    }
5494
5495    /**
5496    * Prepare the writer */
5497    err = M4MCS_intPrepareWriter(pC);
5498
5499    if( M4NO_ERROR != err )
5500    {
5501        M4OSA_TRACE1_1(
5502            "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err);
5503        return err;
5504    }
5505
5506    /**
5507    * Jump the audio stream to the begin cut time (all AUs are RAP)
5508    * Must be done after the 3gpp writer init, because it may write the first
5509    * audio AU in some cases */
5510    err = M4MCS_intPrepareAudioBeginCut(pC);
5511
5512    if( M4NO_ERROR != err )
5513    {
5514        M4OSA_TRACE1_1(
5515            "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x",
5516            err);
5517        return err;
5518    }
5519
5520    /**
5521    * Update state automaton */
5522    if( 0 == pC->uiBeginCutTime )
5523    {
5524        pC->dViDecStartingCts = 0.0;
5525        /**
5526        * No begin cut, do the encoding */
5527        pC->State = M4MCS_kState_PROCESSING;
5528    }
5529    else
5530    {
5531        /**
5532        * Remember that we must start the decode/encode process at the begin cut time */
5533        pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime;
5534
5535        /**
5536        * Jumping */
5537        pC->State = M4MCS_kState_BEGINVIDEOJUMP;
5538    }
5539
5540    /**
5541    * Return with no error */
5542    M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR");
5543    return M4NO_ERROR;
5544}
5545
5546/**
5547 ******************************************************************************
5548 * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC);
5549 * @brief    Prepare the video decoder.
5550 * @param    pC          (IN) MCS private context
5551 * @return   M4NO_ERROR  No error
5552 * @return   M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED
5553 * @return   Any error returned by an underlaying module
5554 ******************************************************************************
5555 */
5556static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC )
5557{
5558    M4OSA_ERR err;
5559    M4OSA_Void *decoderUserData;
5560    M4DECODER_OutputFilter FilterOption;
5561
5562    if( pC->novideo )
5563        return M4NO_ERROR;
5564
5565    /**
5566    * Create the decoder, if it has not been created yet (to get video properties for example) */
5567    if( M4OSA_NULL == pC->pViDecCtxt )
5568    {
5569#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
5570
5571        decoderUserData = pC->m_pCurrentVideoDecoderUserData;
5572
5573#else
5574
5575        decoderUserData = M4OSA_NULL;
5576
5577#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */
5578
5579        err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt,
5580            &pC->pReaderVideoStream->m_basicProperties, pC->m_pReaderDataIt,
5581            &pC->ReaderVideoAU, decoderUserData);
5582
5583        if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err )
5584        {
5585            /**
5586            * Our decoder is not compatible with H263 profile other than 0.
5587            * So it returns this internal error code.
5588            * We translate it to our own error code */
5589            M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\
5590                           returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED");
5591            return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED;
5592        }
5593        else if( M4NO_ERROR != err )
5594        {
5595            M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
5596                           m_pVideoDecoder->m_pFctCreate returns 0x%x", err);
5597            return err;
5598        }
5599
5600        if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType )
5601        {
5602            FilterOption.m_pFilterFunction =
5603                (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420;
5604            FilterOption.m_pFilterUserData = M4OSA_NULL;
5605            err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt,
5606                M4DECODER_kOptionID_OutputFilter,
5607                (M4OSA_DataOption) &FilterOption);
5608
5609            if( M4NO_ERROR != err )
5610            {
5611                M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
5612                               m_pVideoDecoder->m_pFctSetOption returns 0x%x", err);
5613                return err;
5614            }
5615        }
5616    }
5617
5618    /**
5619    * Return with no error */
5620    M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR");
5621    return M4NO_ERROR;
5622}
5623
5624/**
5625 ******************************************************************************
5626 * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC);
5627 * @brief    Prepare the video encoder.
5628 * @param    pC          (IN) MCS private context
5629 * @return   M4NO_ERROR  No error
5630 * @return   Any error returned by an underlaying module
5631 ******************************************************************************
5632 */
5633static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC )
5634{
5635    M4OSA_ERR err;
5636    M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */
5637    M4ENCODER_Params EncParams1;
5638    M4OSA_Double dFrameRate;            /**< tmp variable */
5639
5640    if( pC->novideo )
5641        return M4NO_ERROR;
5642
5643    if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
5644    {
5645        /* Approximative cts increment */
5646        pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate;
5647
5648        if( pC->uiBeginCutTime == 0 )
5649        {
5650            M4OSA_TRACE3_0(
5651                "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing.");
5652            return M4NO_ERROR;
5653        }
5654        else
5655        {
5656            M4OSA_TRACE3_0(
5657                "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults.");
5658
5659            /* Set useful parameters to encode the first I-frame */
5660            EncParams.InputFormat = M4ENCODER_kIYUV420;
5661
5662            switch( pC->InputFileProperties.VideoStreamType )
5663            {
5664                case M4VIDEOEDITING_kH263:
5665                    EncParams.Format = M4ENCODER_kH263;
5666                    break;
5667
5668                case M4VIDEOEDITING_kMPEG4:
5669                case M4VIDEOEDITING_kMPEG4_EMP:
5670                    EncParams.Format = M4ENCODER_kMPEG4;
5671                    break;
5672
5673                case M4VIDEOEDITING_kH264:
5674                    EncParams.Format = M4ENCODER_kH264;
5675                    break;
5676
5677                default:
5678                    M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\
5679                                   (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED",
5680                                   pC->InputFileProperties.VideoStreamType);
5681                    return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
5682            }
5683
5684            EncParams.FrameWidth = pC->EncodingWidth;
5685            EncParams.FrameHeight = pC->EncodingHeight;
5686            EncParams.Bitrate = pC->uiEncVideoBitrate;
5687            EncParams.bInternalRegulation =
5688                M4OSA_FALSE; /* do not constrain the I-frame */
5689            EncParams.FrameRate = pC->EncodingVideoFramerate;
5690
5691            /* Other encoding settings (quite all dummy...) */
5692            EncParams.uiHorizontalSearchRange = 0;    /* use default */
5693            EncParams.uiVerticalSearchRange = 0;      /* use default */
5694            EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
5695            EncParams.uiIVopPeriod = 0;               /* use default */
5696            EncParams.uiMotionEstimationTools =
5697                0; /* M4V_MOTION_EST_TOOLS_ALL */
5698            EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
5699            EncParams.uiStartingQuantizerValue = 5;   /* initial QP = 5 */
5700            EncParams.bDataPartitioning =
5701                M4OSA_FALSE; /* no data partitioning */
5702
5703            /* Rate factor */
5704            EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale;
5705            EncParams.uiRateFactor = 1;
5706        }
5707    }
5708    else
5709    {
5710        M4OSA_TRACE3_0(
5711            "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config.");
5712
5713        /**
5714        * Set encoder shell parameters according to MCS settings */
5715        EncParams.Format = pC->EncodingVideoFormat;
5716        EncParams.InputFormat = M4ENCODER_kIYUV420;
5717
5718        /**
5719        * Video frame size */
5720        EncParams.FrameWidth = pC->EncodingWidth;
5721        EncParams.FrameHeight = pC->EncodingHeight;
5722
5723        /**
5724        * Video bitrate has been previously computed */
5725        EncParams.Bitrate = pC->uiEncVideoBitrate;
5726
5727        /**
5728        * MCS use the "true" core internal bitrate regulation */
5729        EncParams.bInternalRegulation = M4OSA_TRUE;
5730
5731        /**
5732        * Other encoder settings */
5733        if( M4OSA_TRUE == pC->bActivateEmp )
5734        {
5735            EncParams.uiHorizontalSearchRange = 15;   /* set value */
5736            EncParams.uiVerticalSearchRange = 15;     /* set value */
5737            EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
5738            EncParams.uiIVopPeriod = 15; /* one I frame every 15 frames */
5739            EncParams.uiMotionEstimationTools =
5740                1; /* M4V_MOTION_EST_TOOLS_NO_4MV */
5741            EncParams.bAcPrediction = M4OSA_FALSE;    /* no AC prediction */
5742            EncParams.uiStartingQuantizerValue = 10;  /* initial QP = 10 */
5743            EncParams.bDataPartitioning =
5744                M4OSA_FALSE; /* no data partitioning */
5745        }
5746        else
5747        {
5748            EncParams.uiHorizontalSearchRange = 0;    /* use default */
5749            EncParams.uiVerticalSearchRange = 0;      /* use default */
5750            EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
5751            EncParams.uiIVopPeriod = 0;               /* use default */
5752            EncParams.uiMotionEstimationTools =
5753                0; /* M4V_MOTION_EST_TOOLS_ALL */
5754            EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
5755            EncParams.uiStartingQuantizerValue = 10;  /* initial QP = 10 */
5756            EncParams.bDataPartitioning =
5757                M4OSA_FALSE; /* no data partitioning */
5758        }
5759
5760        /**
5761        * Video encoder frame rate and rate factor */
5762        EncParams.FrameRate = pC->EncodingVideoFramerate;
5763        EncParams.uiTimeScale = pC->outputVideoTimescale;
5764
5765        switch( pC->EncodingVideoFramerate )
5766        {
5767            case M4ENCODER_k5_FPS:
5768                dFrameRate = 5.0;
5769                break;
5770
5771            case M4ENCODER_k7_5_FPS:
5772                dFrameRate = 7.5;
5773                break;
5774
5775            case M4ENCODER_k10_FPS:
5776                dFrameRate = 10.0;
5777                break;
5778
5779            case M4ENCODER_k12_5_FPS:
5780                dFrameRate = 12.5;
5781                break;
5782
5783            case M4ENCODER_k15_FPS:
5784                dFrameRate = 15.0;
5785                break;
5786
5787            case M4ENCODER_k20_FPS: /**< MPEG-4 only */
5788                dFrameRate = 20.0;
5789                break;
5790
5791            case M4ENCODER_k25_FPS: /**< MPEG-4 only */
5792                dFrameRate = 25.0;
5793                break;
5794
5795            case M4ENCODER_k30_FPS:
5796                dFrameRate = 30.0;
5797                break;
5798
5799            default:
5800                M4OSA_TRACE1_1(
5801                    "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\
5802                    (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
5803                    pC->EncodingVideoFramerate);
5804                return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
5805        }
5806
5807        /**
5808        * Compute the number of milliseconds between two frames */
5809        if( M4ENCODER_kH263 == EncParams.Format )
5810        {
5811            pC->dCtsIncrement = 1001.0 / dFrameRate;
5812        }
5813        else /**< MPEG4 or H.264 */
5814        {
5815            pC->dCtsIncrement = 1000.0 / dFrameRate;
5816        }
5817    }
5818
5819    /**
5820    * Create video encoder */
5821    err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt,
5822        pC->pWriterDataFcts, \
5823        M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \
5824        pC->pCurrentVideoEncoderUserData);
5825
5826    /**< We put the MCS context in place of the VPP context */
5827    if( M4NO_ERROR != err )
5828    {
5829        M4OSA_TRACE1_1(
5830            "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x",
5831            err);
5832        return err;
5833    }
5834
5835    pC->encoderState = M4MCS_kEncoderClosed;
5836
5837    if( M4OSA_TRUE == pC->bH264Trim )
5838        //if((M4ENCODER_kNULL == pC->EncodingVideoFormat)
5839        //    && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType))
5840    {
5841        EncParams1.InputFormat = EncParams.InputFormat;
5842        //EncParams1.InputFrameWidth = EncParams.InputFrameWidth;
5843        //EncParams1.InputFrameHeight = EncParams.InputFrameHeight;
5844        EncParams1.FrameWidth = EncParams.FrameWidth;
5845        EncParams1.FrameHeight = EncParams.FrameHeight;
5846        EncParams1.Bitrate = EncParams.Bitrate;
5847        EncParams1.FrameRate = EncParams.FrameRate;
5848        EncParams1.Format = M4ENCODER_kH264; //EncParams.Format;
5849
5850        err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
5851            &pC->WriterVideoAU, &EncParams1);
5852    }
5853    else
5854    {
5855        err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
5856            &pC->WriterVideoAU, &EncParams);
5857    }
5858
5859    if( M4NO_ERROR != err )
5860    {
5861        M4OSA_TRACE1_1(
5862            "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x",
5863            err);
5864        return err;
5865    }
5866
5867    pC->encoderState = M4MCS_kEncoderStopped;
5868
5869    if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart )
5870    {
5871        err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt);
5872
5873        if( M4NO_ERROR != err )
5874        {
5875            M4OSA_TRACE1_1(
5876                "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x",
5877                err);
5878            return err;
5879        }
5880    }
5881
5882    pC->encoderState = M4MCS_kEncoderRunning;
5883
5884    /******************************/
5885    /* Video resize management    */
5886    /******************************/
5887    /**
5888    * Compare video input size and video output size to check if resize is needed */
5889    if( ( (M4OSA_UInt32)EncParams.FrameWidth
5890        != pC->pReaderVideoStream->m_videoWidth)
5891        || ((M4OSA_UInt32)EncParams.FrameHeight
5892        != pC->pReaderVideoStream->m_videoHeight) )
5893    {
5894        /**
5895        * Allocate the intermediate video plane that will receive the decoded image before
5896         resizing */
5897        pC->pPreResizeFrame =
5898            (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3 * sizeof(M4VIFI_ImagePlane),
5899            M4MCS, (M4OSA_Char *)"m_pPreResizeFrame");
5900
5901        if( M4OSA_NULL == pC->pPreResizeFrame )
5902        {
5903            M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\
5904                           unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC");
5905            return M4ERR_ALLOC;
5906        }
5907
5908        pC->pPreResizeFrame[0].pac_data = M4OSA_NULL;
5909        pC->pPreResizeFrame[1].pac_data = M4OSA_NULL;
5910        pC->pPreResizeFrame[2].pac_data = M4OSA_NULL;
5911
5912        /**
5913        * Allocate the Y plane */
5914        pC->pPreResizeFrame[0].u_topleft = 0;
5915        pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream->
5916            m_videoWidth; /**< input width */
5917        pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream->
5918            m_videoHeight; /**< input height */
5919        pC->pPreResizeFrame[0].u_stride = pC->
5920            pPreResizeFrame[0].u_width; /**< simple case: stride equals width */
5921
5922        pC->pPreResizeFrame[0].pac_data =
5923            (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[0].u_stride \
5924            *pC->pPreResizeFrame[0].u_height, M4MCS,
5925            (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data");
5926
5927        if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data )
5928        {
5929            M4OSA_TRACE1_0(
5930                "M4MCS_intPrepareVideoEncoder():\
5931                     unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC");
5932            return M4ERR_ALLOC;
5933        }
5934
5935        /**
5936        * Allocate the U plane */
5937        pC->pPreResizeFrame[1].u_topleft = 0;
5938        pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width
5939            >> 1; /**< U width is half the Y width */
5940        pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height
5941            >> 1; /**< U height is half the Y height */
5942        pC->pPreResizeFrame[1].u_stride = pC->
5943            pPreResizeFrame[1].u_width; /**< simple case: stride equals width */
5944
5945        pC->pPreResizeFrame[1].pac_data =
5946            (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[1].u_stride \
5947            *pC->pPreResizeFrame[1].u_height, M4MCS,
5948            (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
5949
5950        if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data )
5951        {
5952            M4OSA_TRACE1_0(
5953                "M4MCS_intPrepareVideoEncoder():\
5954                 unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC");
5955            return M4ERR_ALLOC;
5956        }
5957
5958        /**
5959        * Allocate the V plane */
5960        pC->pPreResizeFrame[2].u_topleft = 0;
5961        pC->pPreResizeFrame[2].u_width = pC->
5962            pPreResizeFrame[1].u_width; /**< V width equals U width */
5963        pC->pPreResizeFrame[2].u_height = pC->
5964            pPreResizeFrame[1].u_height; /**< V height equals U height */
5965        pC->pPreResizeFrame[2].u_stride = pC->
5966            pPreResizeFrame[2].u_width; /**< simple case: stride equals width */
5967
5968        pC->pPreResizeFrame[2].pac_data =
5969            (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[2].u_stride \
5970            *pC->pPreResizeFrame[2].u_height, M4MCS,
5971            (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
5972
5973        if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data )
5974        {
5975            M4OSA_TRACE1_0(
5976                "M4MCS_intPrepareVideoEncoder():\
5977                 unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC");
5978            return M4ERR_ALLOC;
5979        }
5980    }
5981
5982    /**
5983    * Return with no error */
5984    M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR");
5985    return M4NO_ERROR;
5986}
5987
5988/**
5989 ******************************************************************************
5990 * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC);
5991 * @brief    Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder.
5992 * @param    pC          (IN) MCS private context
5993 * @return   M4NO_ERROR  No error
5994 * @return   Any error returned by an underlaying module
5995 ******************************************************************************
5996 */
5997static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC )
5998{
5999    M4OSA_ERR err;
6000
6001    SSRC_ReturnStatus_en
6002        ReturnStatus; /* Function return status                       */
6003    LVM_INT16 NrSamplesMin =
6004        0; /* Minimal number of samples on the input or on the output */
6005    LVM_INT32 ScratchSize; /* The size of the scratch memory               */
6006    LVM_INT16
6007        *pInputInScratch; /* Pointer to input in the scratch buffer       */
6008    LVM_INT16
6009        *pOutputInScratch; /* Pointer to the output in the scratch buffer  */
6010    SSRC_Params_t ssrcParams;          /* Memory for init parameters                    */
6011
6012#ifdef MCS_DUMP_PCM_TO_FILE
6013
6014    file_au_reader = fopen("mcs_ReaderOutput.raw", "wb");
6015    file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb");
6016    file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb");
6017
6018#endif
6019
6020    if( pC->noaudio )
6021        return M4NO_ERROR;
6022
6023    if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
6024    {
6025        M4OSA_TRACE3_0(
6026            "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing.");
6027        return M4NO_ERROR;
6028    }
6029
6030    /* ________________________________ */
6031    /*|                                |*/
6032    /*| Create and "start" the decoder |*/
6033    /*|________________________________|*/
6034
6035    if( M4OSA_NULL == pC->m_pAudioDecoder )
6036    {
6037        M4OSA_TRACE1_0(
6038            "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder.");
6039        return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
6040    }
6041
6042    if( M4OSA_NULL == pC->pAudioDecCtxt )
6043    {
6044        err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt,
6045            pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData);
6046
6047        if( M4NO_ERROR != err )
6048        {
6049            M4OSA_TRACE1_1(
6050                "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
6051                err);
6052            return err;
6053        }
6054    }
6055
6056    if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) {
6057        /* AMR DECODER CONFIGURATION */
6058
6059        /* nothing specific to do */
6060    }
6061    else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) {
6062        /* EVRC DECODER CONFIGURATION */
6063
6064        /* nothing specific to do */
6065    }
6066    else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) {
6067        /* MP3 DECODER CONFIGURATION */
6068
6069        /* nothing specific to do */
6070    }
6071    else
6072    {
6073        /* AAC DECODER CONFIGURATION */
6074        M4_AacDecoderConfig AacDecParam;
6075
6076        AacDecParam.m_AACDecoderProfile = AAC_kAAC;
6077        AacDecParam.m_DownSamplingMode = AAC_kDS_OFF;
6078
6079        if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
6080        {
6081            AacDecParam.m_OutputMode = AAC_kMono;
6082        }
6083        else
6084        {
6085            /* For this version, we encode only in AAC */
6086            if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
6087            {
6088                AacDecParam.m_OutputMode = AAC_kMono;
6089            }
6090            else
6091            {
6092                AacDecParam.m_OutputMode = AAC_kStereo;
6093            }
6094        }
6095
6096        pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6097            M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam);
6098    }
6099
6100    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6101           M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
6102
6103    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6104           M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
6105
6106    if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL )
6107    {
6108        /* Not implemented in all decoders */
6109        err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
6110
6111        if( M4NO_ERROR != err )
6112        {
6113            M4OSA_TRACE1_1(
6114                "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x",
6115                err);
6116            return err;
6117        }
6118    }
6119
6120    /**
6121    * Allocate output buffer for the audio decoder */
6122    pC->InputFileProperties.uiDecodedPcmSize =
6123        pC->pReaderAudioStream->m_byteFrameLength
6124        * pC->pReaderAudioStream->m_byteSampleSize
6125        * pC->pReaderAudioStream->m_nbChannels;
6126
6127    if( pC->InputFileProperties.uiDecodedPcmSize > 0 )
6128    {
6129        pC->AudioDecBufferOut.m_bufferSize =
6130            pC->InputFileProperties.uiDecodedPcmSize;
6131        pC->AudioDecBufferOut.m_dataAddress =
6132            (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->AudioDecBufferOut.m_bufferSize \
6133            *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize");
6134    }
6135
6136    if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress )
6137    {
6138        M4OSA_TRACE1_0(
6139            "M4MCS_intPrepareVideoDecoder():\
6140             unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
6141        return M4ERR_ALLOC;
6142    }
6143
6144    /* _________________________ */
6145    /*|                         |*/
6146    /*| Set the SSRC parameters |*/
6147    /*|_________________________|*/
6148
6149    switch( pC->pReaderAudioStream->m_samplingFrequency )
6150    {
6151        case 8000:
6152            ssrcParams.SSRC_Fs_In = LVM_FS_8000;
6153            break;
6154
6155        case 11025:
6156            ssrcParams.SSRC_Fs_In = LVM_FS_11025;
6157            break;
6158
6159        case 12000:
6160            ssrcParams.SSRC_Fs_In = LVM_FS_12000;
6161            break;
6162
6163        case 16000:
6164            ssrcParams.SSRC_Fs_In = LVM_FS_16000;
6165            break;
6166
6167        case 22050:
6168            ssrcParams.SSRC_Fs_In = LVM_FS_22050;
6169            break;
6170
6171        case 24000:
6172            ssrcParams.SSRC_Fs_In = LVM_FS_24000;
6173            break;
6174
6175        case 32000:
6176            ssrcParams.SSRC_Fs_In = LVM_FS_32000;
6177            break;
6178
6179        case 44100:
6180            ssrcParams.SSRC_Fs_In = LVM_FS_44100;
6181            break;
6182
6183        case 48000:
6184            ssrcParams.SSRC_Fs_In = LVM_FS_48000;
6185            break;
6186
6187        default:
6188            M4OSA_TRACE1_1(
6189                "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\
6190                 returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
6191                pC->pReaderAudioStream->m_samplingFrequency);
6192            return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
6193    }
6194
6195    if( 1 == pC->pReaderAudioStream->m_nbChannels )
6196    {
6197        ssrcParams.SSRC_NrOfChannels = LVM_MONO;
6198    }
6199    else
6200    {
6201        ssrcParams.SSRC_NrOfChannels = LVM_STEREO;
6202    }
6203
6204    /*FlB 26.02.2009: add mp3 as output format*/
6205    if( pC->AudioEncParams.Format == M4ENCODER_kAAC
6206        || pC->AudioEncParams.Format == M4ENCODER_kMP3 )
6207    {
6208        switch( pC->AudioEncParams.Frequency )
6209        {
6210            case M4ENCODER_k8000Hz:
6211                ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
6212                break;
6213
6214            case M4ENCODER_k11025Hz:
6215                ssrcParams.SSRC_Fs_Out = LVM_FS_11025;
6216                break;
6217
6218            case M4ENCODER_k12000Hz:
6219                ssrcParams.SSRC_Fs_Out = LVM_FS_12000;
6220                break;
6221
6222            case M4ENCODER_k16000Hz:
6223                ssrcParams.SSRC_Fs_Out = LVM_FS_16000;
6224                break;
6225
6226            case M4ENCODER_k22050Hz:
6227                ssrcParams.SSRC_Fs_Out = LVM_FS_22050;
6228                break;
6229
6230            case M4ENCODER_k24000Hz:
6231                ssrcParams.SSRC_Fs_Out = LVM_FS_24000;
6232                break;
6233
6234            case M4ENCODER_k32000Hz:
6235                ssrcParams.SSRC_Fs_Out = LVM_FS_32000;
6236                break;
6237
6238            case M4ENCODER_k44100Hz:
6239                ssrcParams.SSRC_Fs_Out = LVM_FS_44100;
6240                break;
6241
6242            case M4ENCODER_k48000Hz:
6243                ssrcParams.SSRC_Fs_Out = LVM_FS_48000;
6244                break;
6245
6246            default:
6247                M4OSA_TRACE1_1(
6248                    "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \
6249                    (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
6250                    pC->AudioEncParams.Frequency);
6251                return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
6252                break;
6253        }
6254    }
6255    else
6256    {
6257        ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
6258    }
6259
6260
6261
6262    ReturnStatus = 0;
6263
6264    switch( ssrcParams.SSRC_Fs_In )
6265    {
6266        case LVM_FS_8000:
6267            ssrcParams.NrSamplesIn = 320;
6268            break;
6269
6270        case LVM_FS_11025:
6271            ssrcParams.NrSamplesIn = 441;
6272            break;
6273
6274        case LVM_FS_12000:
6275            ssrcParams.NrSamplesIn = 480;
6276            break;
6277
6278        case LVM_FS_16000:
6279            ssrcParams.NrSamplesIn = 640;
6280            break;
6281
6282        case LVM_FS_22050:
6283            ssrcParams.NrSamplesIn = 882;
6284            break;
6285
6286        case LVM_FS_24000:
6287            ssrcParams.NrSamplesIn = 960;
6288            break;
6289
6290        case LVM_FS_32000:
6291            ssrcParams.NrSamplesIn = 1280;
6292            break;
6293
6294        case LVM_FS_44100:
6295            ssrcParams.NrSamplesIn = 1764;
6296            break;
6297
6298        case LVM_FS_48000:
6299            ssrcParams.NrSamplesIn = 1920;
6300            break;
6301
6302        default:
6303            ReturnStatus = -1;
6304            break;
6305    }
6306
6307    switch( ssrcParams.SSRC_Fs_Out )
6308    {
6309        case LVM_FS_8000:
6310            ssrcParams.NrSamplesOut = 320;
6311            break;
6312
6313        case LVM_FS_11025:
6314            ssrcParams.NrSamplesOut = 441;
6315            break;
6316
6317        case LVM_FS_12000:
6318            ssrcParams.NrSamplesOut = 480;
6319            break;
6320
6321        case LVM_FS_16000:
6322            ssrcParams.NrSamplesOut = 640;
6323            break;
6324
6325        case LVM_FS_22050:
6326            ssrcParams.NrSamplesOut = 882;
6327            break;
6328
6329        case LVM_FS_24000:
6330            ssrcParams.NrSamplesOut = 960;
6331            break;
6332
6333        case LVM_FS_32000:
6334            ssrcParams.NrSamplesOut = 1280;
6335            break;
6336
6337        case LVM_FS_44100:
6338            ssrcParams.NrSamplesOut = 1764;
6339            break;
6340
6341        case LVM_FS_48000:
6342            ssrcParams.NrSamplesOut = 1920;
6343            break;
6344
6345        default:
6346            ReturnStatus = -1;
6347            break;
6348    }
6349
6350
6351
6352    if( ReturnStatus != SSRC_OK )
6353    {
6354        M4OSA_TRACE1_1(
6355            "M4MCS_intPrepareAudioProcessing:\
6356             Error code %d returned by the SSRC_GetNrSamples function",
6357            ReturnStatus);
6358        return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
6359    }
6360
6361    NrSamplesMin =
6362        (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut)
6363        ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn);
6364
6365    while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE )
6366    { /* Don't take blocks smaller that the minimal block size */
6367        ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1);
6368        ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1);
6369        NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1);
6370    }
6371
6372
6373    pC->iSsrcNbSamplIn = (LVM_INT16)(
6374        ssrcParams.
6375        NrSamplesIn); /* multiplication by NrOfChannels is done below */
6376    pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut);
6377
6378    /**
6379    * Allocate buffer for the input of the SSRC */
6380    pC->pSsrcBufferIn =
6381        (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplIn * sizeof(short) \
6382        *pC->pReaderAudioStream->m_nbChannels, M4MCS,
6383        (M4OSA_Char *)"pSsrcBufferIn");
6384
6385    if( M4OSA_NULL == pC->pSsrcBufferIn )
6386    {
6387        M4OSA_TRACE1_0(
6388            "M4MCS_intPrepareVideoDecoder():\
6389             unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC");
6390        return M4ERR_ALLOC;
6391    }
6392    pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn;
6393
6394    /**
6395    * Allocate buffer for the output of the SSRC */
6396    pC->pSsrcBufferOut =
6397        (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplOut * sizeof(short) \
6398        *pC->pReaderAudioStream->m_nbChannels, M4MCS,
6399        (M4OSA_Char *)"pSsrcBufferOut");
6400
6401    if( M4OSA_NULL == pC->pSsrcBufferOut )
6402    {
6403        M4OSA_TRACE1_0(
6404            "M4MCS_intPrepareVideoDecoder():\
6405             unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC");
6406        return M4ERR_ALLOC;
6407    }
6408
6409
6410    pC->pLVAudioResampler = LVAudioResamplerCreate(
6411        16, /*gInputParams.lvBTChannelCount*/
6412        (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/,
6413        (M4OSA_Int32)(pC->AudioEncParams.Frequency)/*ssrcParams.SSRC_Fs_Out*/, 1);
6414
6415     if( M4OSA_NULL == pC->pLVAudioResampler)
6416     {
6417         return M4ERR_ALLOC;
6418     }
6419
6420    LVAudiosetSampleRate(pC->pLVAudioResampler,
6421        /*gInputParams.lvInSampleRate*/
6422        /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/
6423        pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/);
6424
6425    LVAudiosetVolume(pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */),
6426        (M4OSA_Int16)(0x1000/*0x7fff*/));
6427
6428
6429    /* ________________________ */
6430    /*|                        |*/
6431    /*| Init the audio encoder |*/
6432    /*|________________________|*/
6433
6434    /* Initialise the audio encoder */
6435
6436    err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt,
6437        pC->pCurrentAudioEncoderUserData);
6438
6439    if( M4NO_ERROR != err )
6440    {
6441        M4OSA_TRACE1_1(
6442            "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x",
6443            err);
6444        return err;
6445    }
6446
6447    /* Open the audio encoder */
6448    err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt,
6449        &pC->AudioEncParams, &pC->pAudioEncDSI,
6450        M4OSA_NULL /* no grabbing */);
6451
6452    if( M4NO_ERROR != err )
6453    {
6454        M4OSA_TRACE1_1(
6455            "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x",
6456            err);
6457        return err;
6458    }
6459
6460    /* Allocate the input buffer for the audio encoder */
6461    switch( pC->AudioEncParams.Format )
6462    {
6463        case M4ENCODER_kAMRNB:
6464            pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES;
6465            break;
6466
6467        case M4ENCODER_kAAC:
6468            pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES;
6469            break;
6470
6471            /*FlB 26.02.2009: add mp3 as output format*/
6472        case M4ENCODER_kMP3:
6473            pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES;
6474            break;
6475
6476         default:
6477         break;
6478    }
6479
6480    if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
6481        pC->audioEncoderGranularity *= sizeof(short);
6482    else
6483        pC->audioEncoderGranularity *= sizeof(short) * 2;
6484
6485    pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
6486    pC->pAudioEncoderBuffer =
6487        (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->audioEncoderGranularity, M4MCS,
6488        (M4OSA_Char *)"pC->pAudioEncoderBuffer");
6489
6490    /**
6491    * Return with no error */
6492    M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR");
6493    return M4NO_ERROR;
6494}
6495
6496/**
6497 ******************************************************************************
6498 * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC);
6499 * @brief    Prepare the writer.
6500 * @param    pC          (IN) MCS private context
6501 * @return   M4NO_ERROR  No error
6502 * @return   Any error returned by an underlaying module
6503 ******************************************************************************
6504 */
6505static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC )
6506{
6507    M4OSA_ERR err;
6508    M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */
6509    M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */
6510    M4SYS_StreamIDValue optionValue; /**< For the setoption calls */
6511    M4OSA_UInt32 TargetedFileSize;
6512    M4OSA_Bool bMULPPSSPS = M4OSA_FALSE;
6513
6514    /**
6515    * Init the writer */
6516    err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile,
6517        pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr);
6518
6519    if( M4NO_ERROR != err )
6520    {
6521        M4OSA_TRACE1_1(
6522            "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x",
6523            err);
6524        return err;
6525    }
6526
6527    /**
6528    * Link to the writer context in the writer interface */
6529    pC->pWriterDataFcts->pWriterContext = pC->pWriterContext;
6530
6531    /**
6532    * Set the product description string in the written file */
6533    err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6534        M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS    ");
6535
6536    if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6537        != err) ) /* this option may not be implemented by some writers */
6538    {
6539        M4OSA_TRACE1_1(
6540            "M4MCS_intPrepareWriter:\
6541             pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x",
6542            err);
6543        return err;
6544    }
6545
6546    /**
6547    * Set the product version in the written file */
6548    uiVersion =
6549        M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10
6550        + M4VIDEOEDITING_VERSION_REVISION;
6551    err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6552        M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion);
6553
6554    if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6555        != err) ) /* this option may not be implemented by some writers */
6556    {
6557        M4OSA_TRACE1_1(
6558            "M4MCS_intPrepareWriter: \
6559            pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x",
6560            err);
6561        return err;
6562    }
6563
6564    /**
6565    * In case of EMP, we have to explicitely give an emp ftyp to the writer */
6566    if( M4OSA_TRUE == pC->bActivateEmp )
6567    {
6568        M4VIDEOEDITING_FtypBox ftyp;
6569
6570        ftyp.major_brand = M4VIDEOEDITING_BRAND_3GP4;
6571        ftyp.minor_version = M4VIDEOEDITING_BRAND_0000;
6572        ftyp.nbCompatibleBrands = 2;
6573        ftyp.compatible_brands[0] = M4VIDEOEDITING_BRAND_3GP4;
6574        ftyp.compatible_brands[1] = M4VIDEOEDITING_BRAND_EMP;
6575
6576        err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6577            (M4OSA_UInt32)M4WRITER_kSetFtypBox, (M4OSA_DataOption) &ftyp);
6578
6579        if( M4NO_ERROR != err )
6580        {
6581            M4OSA_TRACE1_1(
6582                "M4MCS_intPrepareWriter:\
6583                 pWriterGlobalFcts->pFctSetOption(M4WRITER_kSetFtypBox) returns 0x%x!",
6584                err);
6585            return err;
6586        }
6587    }
6588
6589    /**
6590    * If there is a video input, allocate and fill the video stream structures for the writer */
6591    if( pC->novideo == M4OSA_FALSE )
6592    {
6593        /**
6594        * Fill Video properties structure for the AddStream method */
6595        pC->WriterVideoStreamInfo.height = pC->EncodingHeight;
6596        pC->WriterVideoStreamInfo.width = pC->EncodingWidth;
6597        pC->WriterVideoStreamInfo.fps =
6598            0; /**< Not used by the shell/core writer */
6599        pC->WriterVideoStreamInfo.Header.pBuf =
6600            M4OSA_NULL; /**< Will be updated later */
6601        pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */
6602
6603        /**
6604        * Fill Video stream description structure for the AddStream method */
6605        switch( pC->EncodingVideoFormat )
6606        {
6607            case M4ENCODER_kMPEG4:
6608                pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
6609                break;
6610
6611            case M4ENCODER_kH263:
6612                pC->WriterVideoStream.streamType = M4SYS_kH263;
6613                break;
6614
6615            case M4ENCODER_kH264:
6616                pC->WriterVideoStream.streamType = M4SYS_kH264;
6617                break;
6618
6619            case M4ENCODER_kNULL:
6620                switch( pC->InputFileProperties.VideoStreamType )
6621                {
6622                    case M4VIDEOEDITING_kMPEG4:
6623                    case M4VIDEOEDITING_kMPEG4_EMP: /* RC */
6624                        pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
6625                        break;
6626
6627                    case M4VIDEOEDITING_kH263:
6628                        pC->WriterVideoStream.streamType = M4SYS_kH263;
6629                        break;
6630
6631                    case M4VIDEOEDITING_kH264:
6632                        pC->WriterVideoStream.streamType = M4SYS_kH264;
6633                        break;
6634
6635                    default:
6636                        M4OSA_TRACE1_1(
6637                            "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \
6638                            unknown format (0x%x),\
6639                             returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
6640                            pC->EncodingVideoFormat);
6641                        return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
6642                }
6643                break;
6644
6645            default: /**< It should never happen, already tested */
6646                M4OSA_TRACE1_1(
6647                    "M4MCS_intPrepareWriter: unknown format (0x%x),\
6648                     returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
6649                    pC->EncodingVideoFormat);
6650                return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
6651        }
6652
6653        /**
6654        * Video bitrate value will be the real value */
6655        pC->WriterVideoStream.averageBitrate =
6656            (M4OSA_Int32)pC->uiEncVideoBitrate;
6657        pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate;
6658
6659        /**
6660        * most other parameters are "dummy" */
6661        pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
6662        pC->WriterVideoStream.timeScale =
6663            0; /**< Not used by the shell/core writer */
6664        pC->WriterVideoStream.profileLevel =
6665            0; /**< Not used by the shell/core writer */
6666        pC->WriterVideoStream.duration =
6667            0; /**< Not used by the shell/core writer */
6668        pC->WriterVideoStream.decoderSpecificInfoSize =
6669            sizeof(M4WRITER_StreamVideoInfos);
6670        pC->WriterVideoStream.decoderSpecificInfo =
6671            (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo);
6672
6673        /**
6674        * Update Encoder Header properties for Video stream if needed */
6675        if( M4ENCODER_kH263 == pC->EncodingVideoFormat )
6676        {
6677            /**
6678            * Creates the H263 DSI */
6679            pC->WriterVideoStreamInfo.Header.Size =
6680                7; /**< H263 output DSI is always 7 bytes */
6681            pDSI = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(7, M4MCS, (M4OSA_Char
6682                *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)");
6683
6684            if( M4OSA_NULL == pDSI )
6685            {
6686                M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\
6687                               returning M4ERR_ALLOC");
6688                return M4ERR_ALLOC;
6689            }
6690
6691            /**
6692            * Vendor is NXP Software: N, X, P, S. */
6693            pDSI[0] = 'N';
6694            pDSI[1] = 'X';
6695            pDSI[2] = 'P';
6696            pDSI[3] = 'S';
6697
6698            /**
6699            * Decoder version is 0 */
6700            pDSI[4] = 0;
6701
6702            /**
6703            * Level is the sixth byte of the DSI. */
6704            switch( pC->EncodingWidth )
6705            {
6706                case M4ENCODER_SQCIF_Width:
6707                case M4ENCODER_QCIF_Width:
6708                    if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS)
6709                        && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6710                    {
6711                        pDSI[5] = 10;
6712                    }
6713                    else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6714                        && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6715                    {
6716                        pDSI[5] = 45;
6717                    }
6718                    else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6719                        && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6720                    {
6721                        pDSI[5] = 20;
6722                    }
6723                    else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
6724                        && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6725                    {
6726                        pDSI[5] = 30;
6727                    }
6728                    else if( ( pC->uiEncVideoBitrate
6729                        <= M4ENCODER_k800_KBPS/*2048*/)
6730                        && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6731                    {
6732                        pDSI[5] = 40;
6733                    }
6734                    break;
6735
6736                case M4ENCODER_CIF_Width:
6737                    if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6738                        && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6739                    {
6740                        pDSI[5] = 20;
6741                    }
6742                    else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
6743                        && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6744                    {
6745                        pDSI[5] = 30;
6746                    }
6747                    else if( ( pC->uiEncVideoBitrate
6748                        <= M4ENCODER_k800_KBPS/*2048*/)
6749                        && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6750                    {
6751                        pDSI[5] = 40;
6752                    }
6753                    break;
6754
6755                    default:
6756                    break;
6757            }
6758
6759            /**
6760            * Profile is the seventh byte of the DSI. */
6761            pDSI[6] = 0;
6762
6763            pC->WriterVideoStreamInfo.Header.pBuf = pDSI;
6764        }
6765        else if( M4ENCODER_kNULL == pC->EncodingVideoFormat )
6766        {
6767            /* If we copy the stream from the input, we copy its DSI */
6768
6769            pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream->
6770                m_basicProperties.m_decoderSpecificInfoSize;
6771            pC->WriterVideoStreamInfo.Header.pBuf =
6772                (M4OSA_MemAddr8)pC->pReaderVideoStream->
6773                m_basicProperties.m_pDecoderSpecificInfo;
6774
6775        }
6776        /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */
6777
6778        /*+CRLV6775 - H.264 Trimming  */
6779        if( pC->bH264Trim == M4OSA_TRUE )
6780        {
6781            bMULPPSSPS = M4OSA_TRUE;
6782            err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6783                (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS,
6784                (M4OSA_DataOption) &bMULPPSSPS);
6785
6786            if( ( M4NO_ERROR != err)
6787                && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6788                != err) ) /* this option may not be implemented by some writers */
6789            {
6790                M4OSA_TRACE1_1(
6791                    "M4MCS_intPrepareWriter:\
6792                     pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x",
6793                    err);
6794                return err;
6795            }
6796        }
6797        /*-CRLV6775 - H.264 Trimming  */
6798        /**
6799        * Add the video stream */
6800        err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
6801            &pC->WriterVideoStream);
6802
6803        if( M4NO_ERROR != err )
6804        {
6805            M4OSA_TRACE1_1(
6806                "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!",
6807                err);
6808            return err;
6809        }
6810
6811        /**
6812        * Update AU properties for video stream */
6813        pC->WriterVideoAU.stream = &(pC->WriterVideoStream);
6814        pC->WriterVideoAU.dataAddress = M4OSA_NULL;
6815        pC->WriterVideoAU.size = 0;
6816        pC->WriterVideoAU.CTS = 0; /** Reset time */
6817        pC->WriterVideoAU.DTS = 0;
6818        pC->WriterVideoAU.attribute = AU_RAP;
6819        pC->WriterVideoAU.nbFrag = 0; /** No fragment */
6820        pC->WriterVideoAU.frag = M4OSA_NULL;
6821
6822        /**
6823        * Set the writer max video AU size */
6824        optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
6825        optionValue.value = pC->uiVideoMaxAuSize;
6826        err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6827            (M4OSA_UInt32)M4WRITER_kMaxAUSize,
6828            (M4OSA_DataOption) &optionValue);
6829
6830        if( M4NO_ERROR != err )
6831        {
6832            M4OSA_TRACE1_1(
6833                "M4MCS_intPrepareWriter: \
6834                pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
6835                err);
6836            return err;
6837        }
6838
6839        /**
6840        * Set the writer max video chunk size */
6841        optionValue.value = pC->uiVideoMaxChunckSize;
6842        err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6843            (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
6844            (M4OSA_DataOption) &optionValue);
6845
6846        if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6847            != err) ) /* this option may not be implemented by some writers */
6848        {
6849            M4OSA_TRACE1_1(
6850                "M4MCS_intPrepareWriter:\
6851                 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
6852                err);
6853            return err;
6854        }
6855    }
6856
6857    /**
6858    * If there is an audio input, allocate and fill the audio stream structures for the writer */
6859    if( pC->noaudio == M4OSA_FALSE )
6860    {
6861        M4WRITER_StreamAudioInfos streamAudioInfo;
6862
6863        streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */
6864        streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */
6865        streamAudioInfo.nbChannels = 1;      /**< unused by our shell writer */
6866
6867        pC->WriterAudioStream.averageBitrate =
6868            0; /**< It is not used by the shell, the DSI is taken into account instead */
6869        pC->WriterAudioStream.maxBitrate =
6870            0; /**< Not used by the shell/core writer */
6871
6872        /**
6873        * Fill Audio stream description structure for the AddStream method */
6874        switch( pC->AudioEncParams.Format )
6875        {
6876            case M4ENCODER_kAMRNB:
6877                pC->WriterAudioStream.streamType = M4SYS_kAMR;
6878                break;
6879
6880            case M4ENCODER_kAAC:
6881                pC->WriterAudioStream.streamType = M4SYS_kAAC;
6882                pC->WriterAudioStream.averageBitrate =
6883                    pC->AudioEncParams.Bitrate;
6884                pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate;
6885                break;
6886
6887                /*FlB 26.02.2009: add mp3 as output format*/
6888            case M4ENCODER_kMP3:
6889                pC->WriterAudioStream.streamType = M4SYS_kMP3;
6890                break;
6891
6892            case M4ENCODER_kAudioNULL:
6893                switch( pC->InputFileProperties.AudioStreamType )
6894                {
6895                case M4VIDEOEDITING_kAMR_NB:
6896                    pC->WriterAudioStream.streamType = M4SYS_kAMR;
6897                    break;
6898                    /*FlB 26.02.2009: add mp3 as output format*/
6899                case M4VIDEOEDITING_kMP3:
6900                    pC->WriterAudioStream.streamType = M4SYS_kMP3;
6901                    break;
6902
6903                case M4VIDEOEDITING_kAAC:
6904                case M4VIDEOEDITING_kAACplus:
6905                case M4VIDEOEDITING_keAACplus:
6906                    pC->WriterAudioStream.streamType = M4SYS_kAAC;
6907                    pC->WriterAudioStream.averageBitrate =
6908                        pC->AudioEncParams.Bitrate;
6909                    pC->WriterAudioStream.maxBitrate =
6910                        pC->AudioEncParams.Bitrate;
6911                    break;
6912
6913                case M4VIDEOEDITING_kEVRC:
6914                    pC->WriterAudioStream.streamType = M4SYS_kEVRC;
6915                    break;
6916
6917                case M4VIDEOEDITING_kNoneAudio:
6918                case M4VIDEOEDITING_kPCM:
6919                case M4VIDEOEDITING_kNullAudio:
6920                case M4VIDEOEDITING_kUnsupportedAudio:
6921                    break;
6922                }
6923                break;
6924
6925            default: /**< It should never happen, already tested */
6926                M4OSA_TRACE1_1(
6927                    "M4MCS_intPrepareWriter: \
6928                    unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
6929                    pC->AudioEncParams.Format);
6930                return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
6931        }
6932
6933        /**
6934        * MCS produces only AMR-NB output */
6935        pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
6936        pC->WriterAudioStream.duration =
6937            0; /**< Not used by the shell/core writer */
6938        pC->WriterAudioStream.profileLevel =
6939            0; /**< Not used by the shell/core writer */
6940        pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency;
6941
6942        if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
6943        {
6944            /* If we copy the stream from the input, we copy its DSI */
6945            streamAudioInfo.Header.Size = pC->pReaderAudioStream->
6946                m_basicProperties.m_decoderSpecificInfoSize;
6947            streamAudioInfo.Header.pBuf =
6948                (M4OSA_MemAddr8)pC->pReaderAudioStream->
6949                m_basicProperties.m_pDecoderSpecificInfo;
6950        }
6951        else
6952        {
6953            if( pC->pAudioEncDSI.pInfo != M4OSA_NULL )
6954            {
6955                /* Use the DSI given by the encoder open() */
6956                streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize;
6957                streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo;
6958            }
6959            else
6960            {
6961                /* Writer will put a default Philips DSI */
6962                streamAudioInfo.Header.Size = 0;
6963                streamAudioInfo.Header.pBuf = M4OSA_NULL;
6964            }
6965        }
6966
6967        /**
6968        * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos
6969         in the DSI pointer... */
6970        pC->WriterAudioStream.decoderSpecificInfo =
6971            (M4OSA_MemAddr32) &streamAudioInfo;
6972
6973        /**
6974        * Add the audio stream to the writer */
6975        err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
6976            &pC->WriterAudioStream);
6977
6978        if( M4NO_ERROR != err )
6979        {
6980            M4OSA_TRACE1_1(
6981                "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x",
6982                err);
6983            return err;
6984        }
6985
6986        /**
6987        * Link the AU and the stream */
6988        pC->WriterAudioAU.stream = &(pC->WriterAudioStream);
6989        pC->WriterAudioAU.dataAddress = M4OSA_NULL;
6990        pC->WriterAudioAU.size = 0;
6991        pC->WriterAudioAU.CTS = 0; /** Reset time */
6992        pC->WriterAudioAU.DTS = 0;
6993        pC->WriterAudioAU.attribute = 0;
6994        pC->WriterAudioAU.nbFrag = 0; /** No fragment */
6995        pC->WriterAudioAU.frag = M4OSA_NULL;
6996
6997        /**
6998        * Set the writer audio max AU size */
6999        /* As max bitrate is now 320kbps instead of 128kbps, max AU
7000         * size has to be increased adapt the max AU size according to the stream type and the
7001         * channels numbers*/
7002        /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite)
7003         */
7004        //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE;
7005        switch( pC->WriterAudioStream.streamType )
7006        {
7007            case M4SYS_kAMR:
7008                pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES
7009                    * (( pC->InputFileProperties.uiNbChannels
7010                    * sizeof(short)) + 3);
7011                break;
7012
7013            case M4SYS_kMP3:
7014                pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES
7015                    * (( pC->InputFileProperties.uiNbChannels
7016                    * sizeof(short)) + 3);
7017                break;
7018
7019            case M4SYS_kAAC:
7020                pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES
7021                    * (( pC->InputFileProperties.uiNbChannels
7022                    * sizeof(short)) + 3);
7023                break;
7024                /*case M4SYS_kEVRC:
7025                pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES*
7026                ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3);
7027                break;*/
7028            default: /**< It should never happen, already tested */
7029                M4OSA_TRACE1_1(
7030                    "M4MCS_intPrepareWriter: unknown format (0x%x),\
7031                     returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
7032                    pC->WriterAudioStream.streamType);
7033                return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
7034        }
7035
7036        optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
7037        optionValue.value = pC->uiAudioMaxAuSize;
7038        err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7039            (M4OSA_UInt32)M4WRITER_kMaxAUSize,
7040            (M4OSA_DataOption) &optionValue);
7041
7042        if( M4NO_ERROR != err )
7043        {
7044            M4OSA_TRACE1_1(
7045                "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
7046                M4WRITER_kMaxAUSize) returns 0x%x",
7047                err);
7048            return err;
7049        }
7050
7051        optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE;
7052        err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7053            (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
7054            (M4OSA_DataOption) &optionValue);
7055
7056        if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
7057            != err) ) /* this option may not be implemented by some writers */
7058        {
7059            M4OSA_TRACE1_1(
7060                "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
7061                M4WRITER_kMaxChunckSize) returns 0x%x",
7062                err);
7063            return err;
7064        }
7065    }
7066
7067    /*
7068    * Set the limitation size of the writer */
7069    TargetedFileSize = pC->uiMaxFileSize;
7070    /* add 1 kB margin */
7071    if( TargetedFileSize > 8192 )
7072        TargetedFileSize -= 1024;
7073
7074    err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7075        (M4OSA_UInt32)M4WRITER_kMaxFileSize,
7076        (M4OSA_DataOption) &TargetedFileSize);
7077
7078    if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
7079        != err) ) /* this option may not be implemented by some writers */
7080    {
7081        M4OSA_TRACE1_1(
7082            "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\
7083            (M4WRITER_kMaxFileSize) returns 0x%x!",
7084            err);
7085        return err;
7086    }
7087
7088    /**
7089    * Close the stream registering in order to be ready to write data */
7090    err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext);
7091
7092    if( M4NO_ERROR != err )
7093    {
7094        M4OSA_TRACE1_1(
7095            "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x",
7096            err);
7097        return err;
7098    }
7099
7100    /**
7101    * Return with no error */
7102    M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR");
7103    return M4NO_ERROR;
7104}
7105
7106/**
7107 ******************************************************************************
7108 * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC);
7109 * @brief    DO the audio begin cut.
7110 * @param    pC          (IN) MCS private context
7111 * @return   M4NO_ERROR  No error
7112 * @return   Any error returned by an underlaying module
7113 ******************************************************************************
7114 */
7115static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC )
7116{
7117    M4OSA_ERR err;
7118    M4OSA_Int32 iCts;
7119    M4OSA_UInt32 uiFrameSize;
7120
7121    if( pC->noaudio )
7122        return M4NO_ERROR;
7123
7124    /**
7125    * Check if an audio begin cut is needed */
7126    if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) )
7127    {
7128        /**
7129        * Return with no error */
7130        M4OSA_TRACE3_0(
7131            "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)");
7132        return M4NO_ERROR;
7133    }
7134
7135    /**
7136    * Jump at the begin cut time */
7137    iCts = pC->uiBeginCutTime;
7138    err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
7139        (M4_StreamHandler *)pC->pReaderAudioStream, &iCts);
7140
7141    if( M4NO_ERROR != err )
7142    {
7143        M4OSA_TRACE1_1(
7144            "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!",
7145            err);
7146        return err;
7147    }
7148
7149    /**
7150    * Remember audio begin cut offset */
7151    pC->iAudioCtsOffset = iCts;
7152
7153    /**
7154    * AMR-NB & EVRC: there may be many frames per AU.
7155    * In that case we need to slice the first AU to keep the 20 ms cut precision */
7156    if( ( M4DA_StreamTypeAudioAmrNarrowBand
7157        == pC->pReaderAudioStream->m_basicProperties.m_streamType)
7158        || (M4DA_StreamTypeAudioEvrc
7159        == pC->pReaderAudioStream->m_basicProperties.m_streamType) )
7160    {
7161        /**
7162        * If the next frame CTS is lower than the begin cut time,
7163        * we must read the AU and parse its frames to reach the
7164        * nearest to the begin cut */
7165        if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime )
7166        {
7167            /**
7168            * Read the first audio AU after the jump */
7169            err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7170                (M4_StreamHandler *)pC->pReaderAudioStream,
7171                &pC->ReaderAudioAU);
7172
7173            if( M4WAR_NO_MORE_AU == err )
7174            {
7175                M4OSA_TRACE1_0(
7176                    "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\
7177                     returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR");
7178                return
7179                    M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
7180            }
7181            else if( M4NO_ERROR != err )
7182            {
7183                M4OSA_TRACE1_1(
7184                    "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\
7185                     returns 0x%x",
7186                    err);
7187                return err;
7188            }
7189
7190            /**
7191            * While the next AU has a lower CTS than the begin cut time, we advance to
7192            the next frame */
7193            while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime )
7194            {
7195                /**
7196                * Get the size of the frame */
7197                switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
7198                {
7199                    case M4DA_StreamTypeAudioAmrNarrowBand:
7200                        uiFrameSize = M4MCS_intGetFrameSize_AMRNB(
7201                            pC->ReaderAudioAU.m_dataAddress);
7202                        break;
7203
7204                    case M4DA_StreamTypeAudioEvrc:
7205                        uiFrameSize = M4MCS_intGetFrameSize_EVRC(
7206                            pC->ReaderAudioAU.m_dataAddress);
7207                        break;
7208
7209                    default:
7210                        uiFrameSize = 0;
7211                        break;
7212                }
7213
7214                if( 0 == uiFrameSize )
7215                {
7216                    /**
7217                    * Corrupted frame! We get out of this mess!
7218                    * We don't want to crash here... */
7219                    M4OSA_TRACE1_0(
7220                        "M4MCS_intPrepareAudioBeginCut(): \
7221                        M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR");
7222                    return
7223                        M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
7224                }
7225
7226                /**
7227                * Go to the next frame */
7228                pC->ReaderAudioAU.m_dataAddress += uiFrameSize;
7229                pC->ReaderAudioAU.m_size -= uiFrameSize;
7230
7231                /**
7232                * Get the CTS of the next frame */
7233                iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */
7234                pC->ReaderAudioAU.m_CTS = iCts;
7235                pC->ReaderAudioAU.m_DTS = iCts;
7236            }
7237
7238            /**
7239            * Update the audio begin cut offset */
7240            pC->iAudioCtsOffset = iCts;
7241        }
7242    }
7243
7244    /**
7245    * Return with no error */
7246    M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR");
7247    return M4NO_ERROR;
7248}
7249
7250/**
7251 ******************************************************************************
7252 * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress)
7253 ******************************************************************************
7254 */
7255static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC,
7256                                       M4OSA_UInt8 *pProgress )
7257{
7258    M4OSA_ERR err;
7259    M4OSA_UInt32 uiAudioStepCount = 0;
7260
7261    /* ---------- VIDEO TRANSCODING ---------- */
7262
7263    if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
7264        == pC->VideoState) ) /**< If the video encoding is going on */
7265    {
7266        if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
7267        {
7268            err = M4MCS_intVideoNullEncoding(pC);
7269        }
7270        else
7271        {
7272            err = M4MCS_intVideoTranscoding(pC);
7273        }
7274
7275        /**
7276        * No more space, quit properly */
7277        if( M4WAR_WRITER_STOP_REQ == err )
7278        {
7279            *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
7280                - pC->uiBeginCutTime) * 100)
7281                / (pC->uiEndCutTime - pC->uiBeginCutTime));
7282
7283            pC->State = M4MCS_kState_FINISHED;
7284
7285            /* bad file produced on very short 3gp file */
7286            if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 )
7287            {
7288                /* Nothing has been encoded -> bad produced file -> error returned */
7289                M4OSA_TRACE2_0(
7290                    "M4MCS_intStepEncoding(): video transcoding returns\
7291                     M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
7292                return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
7293            }
7294            else
7295            {
7296#ifndef M4MCS_AUDIOONLY
7297                /* clean AIR context needed to keep media aspect ratio*/
7298
7299                if( M4OSA_NULL != pC->m_air_context )
7300                {
7301                    err = M4AIR_cleanUp(pC->m_air_context);
7302
7303                    if( err != M4NO_ERROR )
7304                    {
7305                        M4OSA_TRACE1_1(
7306                            "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7307                            err);
7308                        return err;
7309                    }
7310                    pC->m_air_context = M4OSA_NULL;
7311                }
7312
7313#endif /*M4MCS_AUDIOONLY*/
7314
7315                M4OSA_TRACE2_0(
7316                    "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE");
7317                return M4MCS_ERR_NOMORE_SPACE;
7318            }
7319        }
7320
7321        /**< The input plane is null because the input image will be obtained by the
7322        VPP filter from the context */
7323        if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
7324        {
7325            M4OSA_TRACE1_1(
7326                "M4MCS_intStepEncoding(): video transcoding returns 0x%x!",
7327                err);
7328            return err;
7329        }
7330    }
7331
7332    /* ---------- AUDIO TRANSCODING ---------- */
7333
7334    if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
7335        == pC->AudioState) ) /**< If there is an audio stream */
7336    {
7337        while(
7338            /**< If the video encoding is running, encode audio until we reach video time */
7339            ( ( pC->novideo == M4OSA_FALSE)
7340            && (M4MCS_kStreamState_STARTED == pC->VideoState)
7341            && (pC->ReaderAudioAU.m_CTS
7342            + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) ||
7343            /**< If the video encoding is not running, perform 1 step of audio encoding */
7344            (( M4MCS_kStreamState_STARTED == pC->AudioState)
7345            && (uiAudioStepCount < 1)) )
7346        {
7347            uiAudioStepCount++;
7348
7349            /**< check if an adio effect has to be applied*/
7350            err = M4MCS_intCheckAudioEffects(pC);
7351
7352            if( M4NO_ERROR != err )
7353            {
7354                M4OSA_TRACE1_1(
7355                    "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x",
7356                    err);
7357                return err;
7358            }
7359
7360            if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
7361            {
7362                err = M4MCS_intAudioNullEncoding(pC);
7363            }
7364            else /**< Audio transcoding */
7365            {
7366                err = M4MCS_intAudioTranscoding(pC);
7367            }
7368
7369            /**
7370            * No more space, quit properly */
7371            if( M4WAR_WRITER_STOP_REQ == err )
7372            {
7373                *pProgress =
7374                    (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7375                    - pC->uiBeginCutTime) * 100)
7376                    / (pC->uiEndCutTime - pC->uiBeginCutTime));
7377
7378                pC->State = M4MCS_kState_FINISHED;
7379
7380                /* bad file produced on very short 3gp file */
7381                if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 )
7382                {
7383                    /* Nothing has been encoded -> bad produced file -> error returned */
7384                    M4OSA_TRACE2_0(
7385                        "M4MCS_intStepEncoding():\
7386                         audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
7387                    return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
7388                }
7389                else
7390                {
7391#ifndef M4MCS_AUDIOONLY
7392                    /* clean AIR context needed to keep media aspect ratio*/
7393
7394                    if( M4OSA_NULL != pC->m_air_context )
7395                    {
7396                        err = M4AIR_cleanUp(pC->m_air_context);
7397
7398                        if( err != M4NO_ERROR )
7399                        {
7400                            M4OSA_TRACE1_1(
7401                                "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7402                                err);
7403                            return err;
7404                        }
7405                        pC->m_air_context = M4OSA_NULL;
7406                    }
7407
7408#endif /*M4MCS_AUDIOONLY*/
7409
7410                    M4OSA_TRACE2_0(
7411                        "M4MCS_intStepEncoding(): \
7412                        audio transcoding returns M4MCS_ERR_NOMORE_SPACE");
7413                    return M4MCS_ERR_NOMORE_SPACE;
7414                }
7415            }
7416
7417            if( M4WAR_NO_MORE_AU == err )
7418            {
7419                pC->AudioState = M4MCS_kStreamState_FINISHED;
7420                M4OSA_TRACE3_0(
7421                    "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU");
7422                break;
7423            }
7424            else if( M4NO_ERROR != err )
7425            {
7426                M4OSA_TRACE1_1(
7427                    "M4MCS_intStepEncoding(): audio transcoding returns 0x%x",
7428                    err);
7429                return err;
7430            }
7431
7432            /**
7433            * Check for end cut */
7434            /* We absolutely want to have less or same audio duration as video ->
7435            (2*pC->m_audioAUDuration) */
7436            if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7437                + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime )
7438            {
7439                pC->AudioState = M4MCS_kStreamState_FINISHED;
7440                break;
7441            }
7442        }
7443    }
7444
7445    /* ---------- PROGRESS MANAGEMENT ---------- */
7446
7447    /**
7448    * Compute progress */
7449    if( pC->novideo )
7450    {
7451        if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime )
7452        {
7453            *pProgress = 0;
7454        }
7455        else
7456        {
7457            *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7458                - pC->uiBeginCutTime) * 100)
7459                / (pC->uiEndCutTime - pC->uiBeginCutTime));
7460        }
7461        //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS);
7462
7463    }
7464    else
7465    {
7466        if( pC->dViDecCurrentCts < pC->uiBeginCutTime )
7467        {
7468            *pProgress = 0;
7469        }
7470        else
7471        {
7472            *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
7473                - pC->uiBeginCutTime) * 100)
7474                / (pC->uiEndCutTime - pC->uiBeginCutTime));
7475        }
7476        //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts);
7477    }
7478
7479    /**
7480    * Sanity check */
7481    if( *pProgress > 99 )
7482    {
7483        *pProgress = 99;
7484    }
7485
7486    /**
7487    * Increment CTS for next step */
7488    if( pC->novideo == M4OSA_FALSE )
7489    {
7490        if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
7491        {
7492           pC->dViDecCurrentCts +=  1;
7493        }
7494        else
7495        {
7496            pC->dViDecCurrentCts += pC->dCtsIncrement;
7497        }
7498    }
7499
7500    /**
7501    * The transcoding is finished when no stream is being encoded anymore */
7502    if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState))
7503        && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) )
7504    {
7505        /* the AIR part can only be used when video codecs are compiled*/
7506#ifndef M4MCS_AUDIOONLY
7507        /* clean AIR context needed to keep media aspect ratio*/
7508
7509        if( M4OSA_NULL != pC->m_air_context )
7510        {
7511            err = M4AIR_cleanUp(pC->m_air_context);
7512
7513            if( err != M4NO_ERROR )
7514            {
7515                M4OSA_TRACE1_1(
7516                    "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7517                    err);
7518                return err;
7519            }
7520            pC->m_air_context = M4OSA_NULL;
7521        }
7522
7523#endif /*M4MCS_AUDIOONLY*/
7524        /**/
7525
7526        *pProgress = 100;
7527        pC->State = M4MCS_kState_FINISHED;
7528        M4OSA_TRACE2_0(
7529            "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE");
7530        return M4MCS_WAR_TRANSCODING_DONE;
7531    }
7532
7533    /**
7534    * Return with no error */
7535    M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR");
7536    return M4NO_ERROR;
7537}
7538
7539/**
7540 ******************************************************************************
7541 * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC)
7542 ******************************************************************************
7543 */
7544static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC )
7545{
7546    M4OSA_ERR err;
7547    M4OSA_Int32 iCts;
7548
7549    if( pC->novideo )
7550    {
7551        pC->State = M4MCS_kState_BEGINVIDEODECODE;
7552        return M4NO_ERROR;
7553    }
7554
7555    /**
7556    * Jump to the previous RAP in the clip (first get the time, then jump) */
7557    iCts = (M4OSA_Int32)pC->dViDecStartingCts;
7558    err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext,
7559        (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
7560
7561    if( M4WAR_READER_INFORMATION_NOT_PRESENT == err )
7562    {
7563        /* No RAP table, jump backward and predecode */
7564        iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT;
7565
7566        if( iCts < 0 )
7567            iCts = 0;
7568    }
7569    else if( M4NO_ERROR != err )
7570    {
7571        M4OSA_TRACE1_1(
7572            "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!",
7573            err);
7574        return err;
7575    }
7576
7577    /* + CRLV6775 -H.264 Trimming */
7578
7579    if( M4OSA_TRUE == pC->bH264Trim )
7580    {
7581
7582        // Save jump time for safety, this fix should be generic
7583
7584        M4OSA_Int32 iCtsOri = iCts;
7585
7586
7587        err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
7588            (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
7589
7590        if( M4NO_ERROR != err )
7591        {
7592            M4OSA_TRACE1_1(
7593                "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!",
7594                err);
7595            return err;
7596        }
7597
7598        if( pC->ReaderVideoAU1.m_structSize == 0 )
7599        {
7600            /**
7601            * Initializes an access Unit */
7602            err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7603                (M4_StreamHandler *)pC->pReaderVideoStream,
7604                &pC->ReaderVideoAU1);
7605
7606            if( M4NO_ERROR != err )
7607            {
7608                M4OSA_TRACE1_1(
7609                    "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
7610                    err);
7611                return err;
7612            }
7613            err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7614                (M4_StreamHandler *)pC->pReaderVideoStream,
7615                &pC->ReaderVideoAU1);
7616
7617            if( M4WAR_NO_MORE_AU == err )
7618            {
7619                M4OSA_TRACE2_0(
7620                    "M4MCS_intVideoNullEncoding(): \
7621                    m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
7622                /* The audio transcoding is finished */
7623                pC->VideoState = M4MCS_kStreamState_FINISHED;
7624                return err;
7625            }
7626            else if( M4NO_ERROR != err )
7627            {
7628                M4OSA_TRACE1_1(
7629                    "M4MCS_intVideoNullEncoding():\
7630                     m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
7631                    err);
7632                return err;
7633            }
7634
7635            pC->ReaderVideoAU1.m_structSize = 0;
7636        }
7637
7638        err = H264MCS_ProcessSPS_PPS(pC->m_pInstance,
7639            (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size);
7640
7641        if( M4NO_ERROR != err )
7642        {
7643            M4OSA_TRACE1_1(
7644                "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!",
7645                err);
7646            return err;
7647        }
7648
7649
7650        // Restore jump time for safety, this fix should be generic
7651
7652        iCts = iCtsOri;
7653
7654
7655    }
7656    /* - CRLV6775 -H.264 Trimming */
7657    err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
7658        (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
7659
7660    if( M4NO_ERROR != err )
7661    {
7662        M4OSA_TRACE1_1(
7663            "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", err);
7664        return err;
7665    }
7666
7667    /**
7668    * Decode one step */
7669    pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr);
7670
7671    /**
7672    * Be sure we don't decode too far */
7673    if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
7674    {
7675        pC->dViDecCurrentCts = pC->dViDecStartingCts;
7676    }
7677
7678    /**
7679    * Decode at least once with the bJump flag to true */
7680    M4OSA_TRACE3_1(
7681        "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f",
7682        pC->dViDecCurrentCts);
7683    pC->isRenderDup = M4OSA_FALSE;
7684    err =
7685        pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts,
7686        M4OSA_TRUE);
7687
7688    if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
7689        && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
7690    {
7691        M4OSA_TRACE1_1(
7692            "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err);
7693        return err;
7694    }
7695
7696    if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
7697    {
7698        M4OSA_TRACE2_0("Decoding output the same frame as before 1");
7699        pC->isRenderDup = M4OSA_TRUE;
7700    }
7701
7702    /**
7703    * Increment decoding cts for the next step */
7704    pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
7705
7706    /**
7707    * Update state automaton */
7708    if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
7709    {
7710        /**
7711        * Be sure we don't decode too far */
7712        pC->dViDecCurrentCts = pC->dViDecStartingCts;
7713        pC->State = M4MCS_kState_PROCESSING;
7714    }
7715    else
7716    {
7717        pC->State = M4MCS_kState_BEGINVIDEODECODE;
7718    }
7719
7720    /**
7721    * Return with no error */
7722    M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR");
7723    return M4NO_ERROR;
7724}
7725
7726/**
7727 ******************************************************************************
7728 * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC)
7729 ******************************************************************************
7730 */
7731static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC )
7732{
7733    M4OSA_ERR err;
7734    M4_MediaTime dDecTarget;
7735
7736    if( pC->novideo )
7737    {
7738        pC->State = M4MCS_kState_PROCESSING;
7739        return M4NO_ERROR;
7740    }
7741
7742    /**
7743    * Decode */
7744    dDecTarget = pC->dViDecCurrentCts;
7745    M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f",
7746        pC->dViDecCurrentCts);
7747    pC->isRenderDup = M4OSA_FALSE;
7748    err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget,
7749        M4OSA_FALSE);
7750
7751    if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
7752        && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
7753    {
7754        M4OSA_TRACE1_1(
7755            "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err);
7756        return err;
7757    }
7758
7759    if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
7760    {
7761        M4OSA_TRACE2_0("Decoding output the same frame as before 2");
7762        pC->isRenderDup = M4OSA_TRUE;
7763    }
7764
7765    /**
7766    * Increment decoding cts for the next step */
7767    pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
7768
7769    /**
7770    * Update state automaton, if needed */
7771    if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts)
7772        || (M4WAR_NO_MORE_AU == err) )
7773    {
7774        /**
7775        * Be sure we don't decode too far */
7776        pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts;
7777        pC->State = M4MCS_kState_PROCESSING;
7778    }
7779
7780    /**
7781    * Return with no error */
7782    M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR");
7783    return M4NO_ERROR;
7784}
7785
7786/*****************************/
7787/* define AMR silence frames */
7788/*****************************/
7789
7790#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13
7791#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160
7792
7793#ifdef M4VSS3GPP_SILENCE_FRAMES
7794
7795const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[
7796    M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] =
7797    {
7798        0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00
7799    };
7800#else
7801
7802extern
7803const
7804M4OSA_UInt8
7805M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE];
7806
7807#endif
7808
7809/*****************************/
7810/* define AAC silence frames */
7811/*****************************/
7812
7813#define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE      4
7814
7815#ifdef M4VSS3GPP_SILENCE_FRAMES
7816
7817const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[
7818    M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] =
7819    {
7820        0x00, 0xC8, 0x20, 0x07
7821    };
7822#else
7823
7824extern const M4OSA_UInt8
7825M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE];
7826
7827#endif
7828
7829#define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE        6
7830
7831#ifdef M4VSS3GPP_SILENCE_FRAMES
7832
7833const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[
7834    M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] =
7835    {
7836        0x21, 0x10, 0x03, 0x20, 0x54, 0x1C
7837    };
7838#else
7839
7840extern const
7841M4OSA_UInt8
7842M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE];
7843
7844#endif
7845
7846/**
7847 ******************************************************************************
7848 * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC)
7849 * @return   M4NO_ERROR:         No error
7850 ******************************************************************************
7851 */
7852
7853static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC )
7854{
7855    M4OSA_ERR err;
7856
7857    if( pC->noaudio )
7858        return M4NO_ERROR;
7859
7860    /* Check if all audio frame has been written (happens at begin cut) */
7861    if( pC->ReaderAudioAU.m_size == 0 )
7862    {
7863        /**
7864        * Initializes a new AU if needed */
7865        if( pC->ReaderAudioAU1.m_structSize == 0 )
7866        {
7867            /**
7868            * Initializes an access Unit */
7869            err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7870                (M4_StreamHandler *)pC->pReaderAudioStream,
7871                &pC->ReaderAudioAU1);
7872
7873            if( M4NO_ERROR != err )
7874            {
7875                M4OSA_TRACE1_1(
7876                    "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
7877                    err);
7878                return err;
7879            }
7880
7881            pC->m_pDataAddress1 =
7882                (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU1.m_maxsize,
7883                M4MCS, (M4OSA_Char *)"Temporary AU1 buffer");
7884
7885            if( pC->m_pDataAddress1 == M4OSA_NULL )
7886            {
7887                M4OSA_TRACE1_0(
7888                    "M4MCS_intAudioNullEncoding(): allocation error");
7889                return M4ERR_ALLOC;
7890            }
7891
7892            err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7893                (M4_StreamHandler *)pC->pReaderAudioStream,
7894                &pC->ReaderAudioAU1);
7895
7896            if( M4WAR_NO_MORE_AU == err )
7897            {
7898                M4OSA_TRACE2_0(
7899                    "M4MCS_intAudioNullEncoding():\
7900                     m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
7901                /* The audio transcoding is finished */
7902                pC->AudioState = M4MCS_kStreamState_FINISHED;
7903                return err;
7904            }
7905            else if( M4NO_ERROR != err )
7906            {
7907                M4OSA_TRACE1_1(
7908                    "M4MCS_intAudioNullEncoding(): \
7909                    m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
7910                    err);
7911                return err;
7912            }
7913            /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying ,
7914             constant memory reader case*/
7915            if( pC->ReaderAudioAU1.m_maxsize
7916        > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
7917            {
7918                /* Constant memory reader case, we need to reallocate the temporary buffers */
7919                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7920                    *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
7921                /* pC->m_pDataAddress1 and
7922                pC->m_pDataAddress2 must be reallocated at the same time */
7923                /* because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
7924                 maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
7925                  pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true */
7926                /* and the size of the second buffer is never changed. */
7927                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7928                    *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
7929                /* pC->m_pDataAddress1 and
7930                pC->m_pDataAddress2 must be reallocated at the same time */
7931                /* Update stream properties */
7932                pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
7933                    pC->ReaderAudioAU1.m_maxsize;
7934            }
7935            /**/
7936            memcpy((void *)pC->m_pDataAddress1,
7937                (void *)pC->ReaderAudioAU1.m_dataAddress,
7938                pC->ReaderAudioAU1.m_size);
7939        }
7940
7941        if( pC->ReaderAudioAU2.m_structSize == 0 )
7942        {
7943            /**
7944            * Initializes an access Unit */
7945            err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7946                (M4_StreamHandler *)pC->pReaderAudioStream,
7947                &pC->ReaderAudioAU2);
7948
7949            if( M4NO_ERROR != err )
7950            {
7951                M4OSA_TRACE1_1(
7952                    "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
7953                    err);
7954                return err;
7955            }
7956            pC->m_pDataAddress2 =
7957                (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU2.m_maxsize,
7958                M4MCS, (M4OSA_Char *)"Temporary AU buffer");
7959
7960            if( pC->m_pDataAddress2 == M4OSA_NULL )
7961            {
7962                M4OSA_TRACE1_0(
7963                    "M4MCS_intAudioNullEncoding(): allocation error");
7964                return M4ERR_ALLOC;
7965            }
7966        }
7967        /**
7968        * Read the next audio AU in the input file */
7969        if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS )
7970        {
7971            memcpy((void *) &pC->ReaderAudioAU,
7972                (void *) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit));
7973            err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7974                (M4_StreamHandler *)pC->pReaderAudioStream,
7975                &pC->ReaderAudioAU1);
7976
7977            if( pC->ReaderAudioAU1.m_maxsize
7978                > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
7979            {
7980                /* Constant memory reader case, we need to reallocate the temporary buffers */
7981                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7982                    *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
7983                /*   pC->m_pDataAddress1
7984                 * and pC->m_pDataAddress2 must be reallocated at the same time *
7985                 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
7986                 * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
7987                 * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true *
7988                 * and the size of the second buffer is never changed.
7989                 */
7990                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7991                    *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
7992                /* pC->m_pDataAddress1 and
7993                 * pC->m_pDataAddress2 must be reallocated at the same time
7994                 * Update stream properties
7995                 */
7996                pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
7997                    pC->ReaderAudioAU1.m_maxsize;
7998            }
7999            /**/
8000            memcpy((void *)pC->m_pDataAddress1,
8001                (void *)pC->ReaderAudioAU1.m_dataAddress,
8002                pC->ReaderAudioAU1.m_size);
8003            pC->m_audioAUDuration =
8004                pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS;
8005            pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2;
8006        }
8007        else
8008        {
8009            memcpy((void *) &pC->ReaderAudioAU,
8010                (void *) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit));
8011            err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8012                (M4_StreamHandler *)pC->pReaderAudioStream,
8013                &pC->ReaderAudioAU2);
8014            /* Crash in MCS while Audio AU copying ,
8015             * constant memory reader case
8016             */
8017            if( pC->ReaderAudioAU2.m_maxsize
8018                > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
8019            {
8020                /* Constant memory reader case, we need to reallocate the temporary buffers */
8021                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8022                    *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize);
8023                /* pC->m_pDataAddress1 and
8024                 * pC->m_pDataAddress2 must be reallocated at the same time
8025                 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum
8026                 * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream->
8027                 * m_basicProperties.m_maxAUSize)" is never true
8028                 * and the size of the second buffer is never changed.
8029                 */
8030                M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8031                    *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize);
8032                /* [ END ] 20091008  JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and
8033                 pC->m_pDataAddress2 must be reallocated at the same time */
8034                /* Update stream properties */
8035                pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
8036                    pC->ReaderAudioAU2.m_maxsize;
8037            }
8038            /**/
8039            memcpy((void *)pC->m_pDataAddress2,
8040                (void *)pC->ReaderAudioAU2.m_dataAddress,
8041                pC->ReaderAudioAU2.m_size);
8042            pC->m_audioAUDuration =
8043                pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS;
8044            pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1;
8045        }
8046
8047        if( M4WAR_NO_MORE_AU == err )
8048        {
8049            M4OSA_TRACE2_0(
8050                "M4MCS_intAudioNullEncoding(): \
8051                m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
8052            /* The audio transcoding is finished */
8053            pC->AudioState = M4MCS_kStreamState_FINISHED;
8054            return err;
8055        }
8056        else if( M4NO_ERROR != err )
8057        {
8058            M4OSA_TRACE1_1(
8059                "M4MCS_intAudioNullEncoding(): \
8060                m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
8061                err);
8062            return err;
8063        }
8064    }
8065
8066    /**
8067    * Prepare the writer AU */
8068    err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
8069        M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8070
8071    if( M4NO_ERROR != err )
8072    {
8073        M4OSA_TRACE1_1(
8074            "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
8075            err);
8076        return err;
8077    }
8078
8079    if( pC->uiAudioAUCount
8080        == 0 ) /* If it is the first AU, we set it to silence
8081        (else, errors 0x3841, 0x3847 in our AAC decoder) */
8082    {
8083        if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
8084            || pC->InputFileProperties.AudioStreamType
8085            == M4VIDEOEDITING_kAACplus
8086            || pC->InputFileProperties.AudioStreamType
8087            == M4VIDEOEDITING_keAACplus )
8088        {
8089            if( pC->InputFileProperties.uiNbChannels == 1 )
8090            {
8091                pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE;
8092                memcpy((void *)pC->WriterAudioAU.dataAddress,
8093                    (void *)M4VSS3GPP_AAC_AU_SILENCE_MONO,
8094                    pC->WriterAudioAU.size);
8095            }
8096            else if( pC->InputFileProperties.uiNbChannels == 2 )
8097            {
8098                pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE;
8099                memcpy((void *)pC->WriterAudioAU.dataAddress,
8100                    (void *)M4VSS3GPP_AAC_AU_SILENCE_STEREO,
8101                    pC->WriterAudioAU.size);
8102            }
8103            else
8104            {
8105                /* Must never happen ...*/
8106                M4OSA_TRACE1_0(
8107                    "M4MCS_intAudioNullEncoding: Bad number of channels in audio input");
8108                return M4MCS_ERR_INVALID_INPUT_FILE;
8109            }
8110        }
8111        else if( pC->InputFileProperties.AudioStreamType
8112            == M4VIDEOEDITING_kAMR_NB )
8113        {
8114            pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE;
8115            memcpy((void *)pC->WriterAudioAU.dataAddress,
8116                (void *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048,
8117                pC->WriterAudioAU.size);
8118            /* Some remaining AMR AU needs to be copied */
8119            if( pC->ReaderAudioAU.m_size != 0 )
8120            {
8121                /* Update Writer AU */
8122                pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size;
8123                memcpy((void *)(pC->WriterAudioAU.dataAddress
8124                    + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE),
8125                    (void *)pC->ReaderAudioAU.m_dataAddress,
8126                    pC->ReaderAudioAU.m_size);
8127            }
8128        }
8129        else
8130        {
8131            /*MP3 case: copy the AU*/
8132            M4OSA_TRACE3_1(
8133                "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
8134                pC->ReaderAudioAU.m_size);
8135            memcpy((void *)pC->WriterAudioAU.dataAddress,
8136                (void *)pC->ReaderAudioAU.m_dataAddress,
8137                pC->ReaderAudioAU.m_size);
8138            pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
8139        }
8140    }
8141    else
8142    {
8143        /**
8144        * Copy audio data from reader AU to writer AU */
8145        M4OSA_TRACE3_1(
8146            "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
8147            pC->ReaderAudioAU.m_size);
8148        memcpy((void *)pC->WriterAudioAU.dataAddress,
8149            (void *)pC->ReaderAudioAU.m_dataAddress,
8150            pC->ReaderAudioAU.m_size);
8151        pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
8152    }
8153
8154    /**
8155    * Convert CTS unit from milliseconds to timescale */
8156    pC->WriterAudioAU.CTS =
8157        (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset)
8158        * (pC->WriterAudioStream.timeScale / 1000.0)));
8159
8160    if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB
8161        && pC->uiAudioAUCount == 0 )
8162    {
8163        pC->iAudioCtsOffset -=
8164            20; /* Duration of a silence AMR AU, to handle the duration of the added
8165                silence frame */
8166    }
8167    pC->WriterAudioAU.nbFrag = 0;
8168    M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms",
8169        pC->WriterAudioAU.CTS);
8170
8171    /**
8172    * Write it to the output file */
8173    pC->uiAudioAUCount++;
8174    err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8175        M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8176
8177    if( M4NO_ERROR != err )
8178    {
8179        M4OSA_TRACE1_1(
8180            "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8181            err);
8182        return err;
8183    }
8184
8185    /* All the audio has been written */
8186    pC->ReaderAudioAU.m_size = 0;
8187
8188    /**
8189    * Return with no error */
8190    M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR");
8191    return M4NO_ERROR;
8192}
8193
8194/**
8195 ******************************************************************************
8196 * @brief    Init Audio Transcoding
8197 * @return   M4NO_ERROR:         No error
8198 ******************************************************************************
8199 */
8200static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC )
8201{
8202    M4OSA_ERR err;                        /**< General error */
8203
8204    M4OSA_UInt32
8205        uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */
8206    M4OSA_UInt32
8207        uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */
8208
8209    int ssrcErr;                          /**< Error while ssrc processing */
8210    M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */
8211    M4OSA_UInt32
8212        uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */
8213    M4OSA_MemAddr8
8214        pSsrcInput; /**< Pointer to the good buffer location for ssrc input */
8215    M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */
8216    M4OSA_UInt32
8217        uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */
8218
8219    M4OSA_UInt8
8220        needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */
8221    M4OSA_UInt32
8222        uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo
8223                                    <-> mono conversion is applied */
8224    M4OSA_MemAddr8 pChannelConvertorInput =
8225        M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */
8226    M4OSA_UInt32 uiChannelConvertorNbSamples =
8227        0; /**< Nb of pcm samples to convert in channel convertor */
8228    M4OSA_MemAddr8 pChannelConvertorOutput =
8229        M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */
8230
8231    M4OSA_Time
8232        frameTimeDelta; /**< Duration of the encoded (then written) data */
8233    M4OSA_UInt32
8234        uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */
8235    M4OSA_UInt32
8236        uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */
8237    M4OSA_MemAddr8
8238        pEncoderInput; /**< Pointer to the good buffer location for encoder input */
8239    M4ENCODER_AudioBuffer pEncInBuffer;   /**< Encoder input buffer for api */
8240    M4ENCODER_AudioBuffer pEncOutBuffer;  /**< Encoder output buffer for api */
8241
8242    M4OSA_Int16 *tempBuffOut = M4OSA_NULL;
8243    /*FlB 2009.03.04: apply audio effects if an effect is active*/
8244    M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber);
8245
8246    uint32_t errCode = M4NO_ERROR;
8247
8248    if( pC->noaudio )
8249        return M4NO_ERROR;
8250
8251    /* _________________ */
8252    /*|                 |*/
8253    /*| READ AND DECODE |*/
8254    /*|_________________|*/
8255
8256    /* Check if we have to empty the decoder out buffer first */
8257    if( M4OSA_NULL != pC->pPosInDecBufferOut )
8258    {
8259        goto m4mcs_intaudiotranscoding_feed_resampler;
8260    }
8261
8262    err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
8263        M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE);
8264
8265
8266    if( M4NO_ERROR != err )
8267    {
8268        M4OSA_TRACE1_1(
8269            "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x",
8270            err);
8271        return err;
8272    }
8273
8274#ifdef MCS_DUMP_PCM_TO_FILE
8275
8276    fwrite(pC->AudioDecBufferOut.m_dataAddress,
8277        pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder);
8278
8279#endif
8280
8281    pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
8282           M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode);
8283
8284    if ( M4WAR_NO_MORE_AU == errCode ) {
8285        pC->AudioState = M4MCS_kStreamState_FINISHED;
8286            M4OSA_TRACE2_0(
8287                "M4MCS_intAudioTranscoding():\
8288                 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
8289            return errCode;
8290   }
8291
8292    /* Set the current position in the decoder out buffer */
8293    pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress;
8294
8295    /* ________________ */
8296    /*|                |*/
8297    /*| FEED RESAMPLER |*/
8298    /*|________________|*/
8299
8300m4mcs_intaudiotranscoding_feed_resampler:
8301
8302    /* Check if we have to empty the ssrc out buffer first */
8303    if( M4OSA_NULL != pC->pPosInSsrcBufferOut )
8304    {
8305        goto m4mcs_intaudiotranscoding_prepare_input_buffer;
8306    }
8307
8308    /* Compute number of bytes remaining in the decoder buffer */
8309    uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short)
8310        * pC->pReaderAudioStream->m_nbChannels;
8311    uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress
8312        + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut;
8313
8314    /* Check if we can feed directly the Ssrc with the decoder out buffer */
8315    if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn)
8316        && (uiBytesDec >= uiSsrcInSize) )
8317    {
8318        pSsrcInput = pC->pPosInDecBufferOut;
8319
8320        /* update data consumed into decoder buffer after resampling */
8321        if( uiBytesDec == uiSsrcInSize )
8322            pC->pPosInDecBufferOut = M4OSA_NULL;
8323        else
8324            pC->pPosInDecBufferOut += uiSsrcInSize;
8325
8326        goto m4mcs_intaudiotranscoding_do_resampling;
8327    }
8328
8329    /**
8330    * Compute remaining space in Ssrc buffer in */
8331    uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn;
8332
8333    /**
8334    * Nb of bytes copied is the minimum between nb of bytes remaining in
8335    * decoder out buffer and space remaining in ssrc in buffer */
8336    uiDecoder2Ssrc_NbBytes =
8337        (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec;
8338
8339    /**
8340    * Copy from the decoder out buffer into the Ssrc in buffer */
8341    memcpy((void *)pC->pPosInSsrcBufferIn, (void *)pC->pPosInDecBufferOut,
8342        uiDecoder2Ssrc_NbBytes);
8343
8344    /**
8345    * Update the position in the decoder out buffer */
8346    pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes;
8347
8348    /**
8349    * Update the position in the Ssrc in buffer */
8350    pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes;
8351
8352    /**
8353    * Check if the decoder buffer out is empty */
8354    if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress)
8355        == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize )
8356    {
8357        pC->pPosInDecBufferOut = M4OSA_NULL;
8358    }
8359
8360    /* Check if the Ssrc in buffer is ready (= full) */
8361    if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn)
8362        < (M4OSA_Int32)uiSsrcInSize )
8363    {
8364        goto m4mcs_intaudiotranscoding_end;
8365    }
8366
8367    pSsrcInput = pC->pSsrcBufferIn;
8368
8369    /* update data consumed into ssrc buffer in after resampling (empty) */
8370    pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn;
8371
8372    /* ___________________ */
8373    /*|                   |*/
8374    /*| DO THE RESAMPLING |*/
8375    /*|___________________|*/
8376
8377m4mcs_intaudiotranscoding_do_resampling:
8378
8379    /**
8380    * No need for memcopy, we can feed Ssrc directly with the data in the audio
8381    decoder out buffer*/
8382
8383    ssrcErr = 0;
8384
8385    if( pC->pReaderAudioStream->m_nbChannels == 1 )
8386    {
8387        tempBuffOut =
8388            (short *)M4OSA_32bitAlignedMalloc((pC->iSsrcNbSamplOut * sizeof(short) * 2
8389            * ((*pC).InputFileProperties).uiNbChannels),
8390            M4VSS3GPP,(M4OSA_Char *) "tempBuffOut");
8391        memset((void *)tempBuffOut, 0,(pC->iSsrcNbSamplOut * sizeof(short) * 2
8392            * ((*pC).InputFileProperties).uiNbChannels));
8393
8394        LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput,
8395            pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
8396    }
8397    else
8398    {
8399        memset((void *)pC->pSsrcBufferOut, 0, (pC->iSsrcNbSamplOut * sizeof(short)
8400            * ((*pC).InputFileProperties).uiNbChannels));
8401
8402        LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut,
8403            (short *)pSsrcInput, pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
8404    }
8405
8406    if( pC->pReaderAudioStream->m_nbChannels == 1 )
8407    {
8408        From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut,
8409            (short)pC->iSsrcNbSamplOut);
8410        free(tempBuffOut);
8411    }
8412
8413
8414    if( 0 != ssrcErr )
8415    {
8416        M4OSA_TRACE1_1(
8417            "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \
8418            returning M4MCS_ERR_AUDIO_CONVERSION_FAILED",
8419            ssrcErr);
8420        return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
8421    }
8422
8423    pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut;
8424
8425    /* ______________________ */
8426    /*|                      |*/
8427    /*| PREPARE INPUT BUFFER |*/
8428    /*|______________________|*/
8429
8430m4mcs_intaudiotranscoding_prepare_input_buffer:
8431
8432    /* Set the flag for channel conversion requirement */
8433    if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
8434        && (pC->pReaderAudioStream->m_nbChannels == 2) )
8435    {
8436        needChannelConversion = 1;
8437        uiChannelConvertorCoeff = 4;
8438    }
8439    else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo)
8440        && (pC->pReaderAudioStream->m_nbChannels == 1) )
8441    {
8442        needChannelConversion = 2;
8443        uiChannelConvertorCoeff = 1;
8444    }
8445    else
8446    {
8447        needChannelConversion = 0;
8448        uiChannelConvertorCoeff = 2;
8449    }
8450
8451    /* Compute number of bytes remaining in the Ssrc buffer */
8452    uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short)
8453        * pC->pReaderAudioStream->m_nbChannels;
8454    uiBytesSsrc =
8455        ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut;
8456
8457    /* Check if the ssrc buffer is full */
8458    if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut )
8459    {
8460        uiSsrc2Encoder_NbBytes =
8461            pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2;
8462
8463        /* Check if we can feed directly the encoder with the ssrc out buffer */
8464        if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL)
8465            && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) )
8466        {
8467            /* update position in ssrc out buffer after encoding */
8468            if( uiBytesSsrc == uiSsrc2Encoder_NbBytes )
8469                pC->pPosInSsrcBufferOut = M4OSA_NULL;
8470            else
8471                pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
8472
8473            /* mark the encoder buffer ready (= full) */
8474            pC->pPosInAudioEncoderBuffer =
8475                pC->pAudioEncoderBuffer + pC->audioEncoderGranularity;
8476
8477            if( needChannelConversion > 0 )
8478            {
8479                /* channel convertor writes directly into encoder buffer */
8480                pEncoderInput = pC->pAudioEncoderBuffer;
8481
8482                pChannelConvertorInput = pC->pSsrcBufferOut;
8483                pChannelConvertorOutput = pC->pAudioEncoderBuffer;
8484                uiChannelConvertorNbSamples =
8485                    uiSsrc2Encoder_NbBytes / sizeof(short);
8486
8487                goto m4mcs_intaudiotranscoding_channel_convertor;
8488            }
8489            else
8490            {
8491                /* encode directly from ssrc out buffer */
8492                pEncoderInput = pC->pSsrcBufferOut;
8493
8494                goto m4mcs_intaudiotranscoding_encode_and_write;
8495            }
8496        }
8497    }
8498
8499    /**
8500    * Compute remaining space in encoder buffer in */
8501    if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL )
8502    {
8503        pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer;
8504    }
8505
8506    uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity)
8507        - pC->pPosInAudioEncoderBuffer;
8508    pEncoderInput = pC->pAudioEncoderBuffer;
8509
8510    /**
8511    * Nb of bytes copied is the minimum between nb of bytes remaining in
8512    * decoder out buffer and space remaining in ssrc in buffer */
8513    uiSsrc2Encoder_NbBytes =
8514        (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc)
8515        ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc;
8516
8517    if( needChannelConversion > 0 )
8518    {
8519        /* channel convertor writes directly into encoder buffer */
8520        pChannelConvertorInput = pC->pPosInSsrcBufferOut;
8521        pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer;
8522        uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short);
8523    }
8524    else
8525    {
8526        /* copy from the ssrc out buffer into the encoder in buffer */
8527        memcpy((void *)pC->pPosInAudioEncoderBuffer, (void *)pC->pPosInSsrcBufferOut,
8528            uiSsrc2Encoder_NbBytes);
8529    }
8530
8531    /* Update position in ssrc out buffer after encoding */
8532    pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
8533
8534    /* Update the position in the encoder in buffer */
8535    pC->pPosInAudioEncoderBuffer +=
8536        uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff;
8537
8538    /* Check if the ssrc buffer out is empty */
8539    if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut)
8540        == (M4OSA_Int32)uiSsrcOutSize )
8541    {
8542        pC->pPosInSsrcBufferOut = M4OSA_NULL;
8543    }
8544
8545    /* go to next statement */
8546    if( needChannelConversion > 0 )
8547        goto m4mcs_intaudiotranscoding_channel_convertor;
8548    else
8549        goto m4mcs_intaudiotranscoding_encode_and_write;
8550
8551    /* _________________ */
8552    /*|                 |*/
8553    /*| STEREO <-> MONO |*/
8554    /*|_________________|*/
8555
8556m4mcs_intaudiotranscoding_channel_convertor:
8557
8558    /* convert the input pcm stream to mono or to stereo */
8559    switch( needChannelConversion )
8560    {
8561        case 1: /* stereo to mono */
8562            From2iToMono_16((short *)pChannelConvertorInput,
8563                (short *)pChannelConvertorOutput,
8564                (short)(uiChannelConvertorNbSamples / 2));
8565            break;
8566
8567        case 2: /* mono to stereo */
8568            MonoTo2I_16((short *)pChannelConvertorInput,
8569                (short *)pChannelConvertorOutput,
8570                (short)uiChannelConvertorNbSamples);
8571            break;
8572    }
8573
8574    /* __________________ */
8575    /*|                  |*/
8576    /*| ENCODE AND WRITE |*/
8577    /*|__________________|*/
8578
8579m4mcs_intaudiotranscoding_encode_and_write:
8580
8581    /* Check if the encoder in buffer is ready (= full) */
8582    if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer)
8583        < (M4OSA_Int32)pC->audioEncoderGranularity )
8584    {
8585        goto m4mcs_intaudiotranscoding_end;
8586    }
8587
8588    /* [Mono] or [Stereo interleaved] : all is in one buffer */
8589    pEncInBuffer.pTableBuffer[0] = pEncoderInput;
8590    pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity;
8591    pEncInBuffer.pTableBuffer[1] = M4OSA_NULL;
8592    pEncInBuffer.pTableBufferSize[1] = 0;
8593
8594    /* Time in ms from data size, because it is PCM16 samples */
8595    frameTimeDelta =
8596        ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2)
8597        / sizeof(short) / pC->pReaderAudioStream->m_nbChannels;
8598
8599    /**
8600    * Prepare the writer AU */
8601    err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
8602        M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8603
8604    if( M4NO_ERROR != err )
8605    {
8606        M4OSA_TRACE1_1(
8607            "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
8608            err);
8609        return err;
8610    }
8611
8612    /*FlB 2009.03.04: apply audio effects if an effect is active*/
8613    if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects )
8614    {
8615        if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL )
8616        {
8617            M4MCS_ExternalProgress pProgress;
8618            M4OSA_UInt32 tempProgress = 0;
8619            pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS;
8620
8621            pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000)
8622                / pC->WriterAudioStream.timeScale;
8623            tempProgress = ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
8624                - pC->pEffects[*pActiveEffectNumber].uiStartTime
8625                - pC->uiBeginCutTime) * 1000;
8626            pProgress.uiProgress =
8627                (M4OSA_UInt32)(tempProgress / (M4OSA_UInt32)pC->pEffects[
8628                    *pActiveEffectNumber].uiDuration);
8629
8630                    err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct(
8631                        pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt,
8632                        (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0],
8633                        pEncInBuffer.pTableBufferSize[0], &pProgress);
8634
8635                    if( err != M4NO_ERROR )
8636                    {
8637                        M4OSA_TRACE1_1(
8638                            "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x",
8639                            err);
8640                        return err;
8641                    }
8642        }
8643    }
8644
8645    /**
8646    * Prepare output buffer */
8647    pEncOutBuffer.pTableBuffer[0] =
8648        (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress;
8649    pEncOutBuffer.pTableBufferSize[0] = 0;
8650
8651#ifdef MCS_DUMP_PCM_TO_FILE
8652
8653    fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1,
8654        file_pcm_encoder);
8655
8656#endif
8657
8658    if( M4OSA_FALSE == pC->b_isRawWriter )
8659    {
8660        /* This allow to write PCM data to file and to encode AMR data,
8661         when output file is not RAW */
8662        if( pC->pOutputPCMfile != M4OSA_NULL )
8663        {
8664            pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile,
8665                pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]);
8666        }
8667
8668        /**
8669        * Encode the PCM audio */
8670        err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt,
8671            &pEncInBuffer, &pEncOutBuffer);
8672
8673        if( M4NO_ERROR != err )
8674        {
8675            M4OSA_TRACE1_1(
8676                "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x",
8677                err);
8678            return err;
8679        }
8680
8681        /* update data consumed into encoder buffer in after encoding (empty) */
8682        pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
8683
8684        /**
8685        * Set AU cts and size */
8686        pC->WriterAudioAU.size =
8687            pEncOutBuffer.
8688            pTableBufferSize[0]; /**< Get the size of encoded data */
8689        pC->WriterAudioAU.CTS += frameTimeDelta;
8690
8691        /**
8692        * Update duration of the encoded AU */
8693        pC->m_audioAUDuration =
8694            ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale;
8695
8696        /**
8697        * Write the encoded AU to the output file */
8698        pC->uiAudioAUCount++;
8699        err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8700            M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8701
8702        if( M4NO_ERROR != err )
8703        {
8704            M4OSA_TRACE1_1(
8705                "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8706                err);
8707            return err;
8708        }
8709    }
8710    else
8711    {
8712        /* update data consumed into encoder buffer in after encoding (empty) */
8713        pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
8714
8715        pC->WriterAudioAU.dataAddress =
8716            (M4OSA_MemAddr32)
8717            pEncoderInput; /* will be converted back to u8* in file write */
8718        pC->WriterAudioAU.size = pC->audioEncoderGranularity;
8719        pC->uiAudioAUCount++;
8720
8721        err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8722            M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8723
8724        if( M4NO_ERROR != err )
8725        {
8726            M4OSA_TRACE1_1(
8727                "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8728                err);
8729            return err;
8730        }
8731    }
8732
8733    /* _______________ */
8734    /*|               |*/
8735    /*| ONE PASS DONE |*/
8736    /*|_______________|*/
8737
8738m4mcs_intaudiotranscoding_end:
8739
8740    /**
8741    * Return with no error */
8742    M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR");
8743    return M4NO_ERROR;
8744}
8745
8746/**
8747 ******************************************************************************
8748 * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize)
8749 * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU
8750 * because max AU size can be reevaluated during reading
8751 * @return   M4NO_ERROR:         No error
8752 ******************************************************************************
8753 */
8754static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr,
8755                                             M4OSA_UInt32 newSize )
8756{
8757    if( *addr != M4OSA_NULL )
8758    {
8759        free(*addr);
8760        *addr = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(newSize, M4MCS,
8761            (M4OSA_Char *)"Reallocation of temporary AU buffer");
8762
8763        if( *addr == M4OSA_NULL )
8764        {
8765            return M4ERR_ALLOC;
8766        }
8767    }
8768
8769    return M4NO_ERROR;
8770}
8771
8772/**
8773 ******************************************************************************
8774 * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC)
8775 * @author   Alexis Vapillon (NXP Software Vision)
8776 * @return   M4NO_ERROR:         No error
8777 ******************************************************************************
8778 */
8779static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC )
8780{
8781    M4OSA_ERR err = M4NO_ERROR;
8782    /* Duration of the AU (find the next AU duration
8783     * to obtain a more precise video end cut)
8784     */
8785    M4OSA_UInt32 videoAUDuration = 0;
8786
8787    M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL;
8788    M4OSA_Int32 lastdecodedCTS = 0;
8789    M4_AccessUnit lReaderVideoAU; /**< Read video access unit */
8790
8791    if( pC->novideo )
8792        return M4NO_ERROR;
8793
8794    /* H.264 Trimming */
8795    if( ( ( pC->bH264Trim == M4OSA_TRUE)
8796        && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames)
8797        && (pC->uiBeginCutTime > 0))
8798        || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) )
8799    {
8800        err = M4MCS_intVideoTranscoding(pC);
8801        return err;
8802    }
8803
8804
8805    if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0))
8806    {
8807        // StageFright encoder does prefetch, the one frame we requested will not be written until
8808        // the encoder is closed, so do it now rather than in MCS_close
8809        if( ( M4NO_ERROR != err)
8810            || (M4MCS_kEncoderRunning != pC->encoderState) )
8811        {
8812            M4OSA_TRACE1_2(
8813                "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding "
8814                "returns 0x%X w/ encState=%d", err, pC->encoderState);
8815
8816            return err;
8817        }
8818
8819        /* Stop and close the encoder now to flush the frame (prefetch) */
8820        if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
8821        {
8822            err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt);
8823
8824            if( M4NO_ERROR != err )
8825            {
8826                M4OSA_TRACE1_1(
8827                    "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X",
8828                    err);
8829                return err;
8830            }
8831        }
8832        pC->encoderState = M4MCS_kEncoderStopped;
8833        err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt);
8834
8835        if( M4NO_ERROR != err )
8836        {
8837            M4OSA_TRACE1_1(
8838                "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X",
8839                err);
8840            return err;
8841        }
8842        pC->encoderState = M4MCS_kEncoderClosed;
8843    }
8844
8845
8846    if( ( pC->bH264Trim == M4OSA_TRUE)
8847        && (pC->bLastDecodedFrameCTS == M4OSA_FALSE)
8848        && (pC->uiBeginCutTime > 0) )
8849    {
8850
8851        pC->bLastDecodedFrameCTS = M4OSA_TRUE;
8852        err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt,
8853            M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS);
8854
8855        if( M4NO_ERROR != err )
8856        {
8857            M4OSA_TRACE1_1(
8858                "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!",
8859                err);
8860            return err;
8861        }
8862
8863        err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
8864            (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS);
8865
8866        if( M4NO_ERROR != err )
8867        {
8868            M4OSA_TRACE1_1(
8869                "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!",
8870                err);
8871            return err;
8872        }
8873
8874
8875        /* Initializes an access Unit */
8876
8877        err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
8878            (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
8879
8880        if( M4NO_ERROR != err )
8881        {
8882            M4OSA_TRACE1_1(
8883                "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
8884                err);
8885            return err;
8886        }
8887
8888        err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8889            (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
8890
8891        if( M4WAR_NO_MORE_AU == err )
8892        {
8893            M4OSA_TRACE2_0(
8894                "M4MCS_intVideoNullEncoding():\
8895                 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
8896            /* The audio transcoding is finished */
8897            pC->VideoState = M4MCS_kStreamState_FINISHED;
8898            return err;
8899        }
8900        else if( M4NO_ERROR != err )
8901        {
8902            M4OSA_TRACE1_1(
8903                "M4MCS_intVideoNullEncoding():\
8904                 m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
8905                err);
8906            return err;
8907        }
8908
8909        M4OSA_TRACE1_1(
8910            "### [TS_CHECK] M4MCS_intVideoNullEncoding  video AU CTS: %d ",
8911            lReaderVideoAU.m_CTS);
8912
8913
8914    }
8915
8916
8917    pC->bLastDecodedFrameCTS = M4OSA_TRUE;
8918
8919
8920    /* Find the next AU duration to obtain a more precise video end cut*/
8921    /**
8922    * Initializes a new AU if needed */
8923
8924    if( pC->ReaderVideoAU1.m_structSize == 0 )
8925    {
8926        /**
8927        * Initializes an access Unit */
8928        err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
8929            (M4_StreamHandler *)pC->pReaderVideoStream,
8930            &pC->ReaderVideoAU1);
8931
8932        if( M4NO_ERROR != err )
8933        {
8934            M4OSA_TRACE1_1(
8935                "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
8936                err);
8937            return err;
8938        }
8939
8940        pC->m_pDataVideoAddress1 =
8941            (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU1.m_maxsize, M4MCS,
8942            (M4OSA_Char *)"Temporary video AU1 buffer");
8943
8944        if( pC->m_pDataVideoAddress1 == M4OSA_NULL )
8945        {
8946            M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
8947            return M4ERR_ALLOC;
8948        }
8949
8950        err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8951            (M4_StreamHandler *)pC->pReaderVideoStream,
8952            &pC->ReaderVideoAU1);
8953
8954        if( M4WAR_NO_MORE_AU == err )
8955        {
8956            M4OSA_TRACE2_0(
8957                "M4MCS_intVideoNullEncoding():\
8958                 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
8959            /* The audio transcoding is finished */
8960            pC->VideoState = M4MCS_kStreamState_FINISHED;
8961            return err;
8962        }
8963        else if( M4NO_ERROR != err )
8964        {
8965            M4OSA_TRACE1_1(
8966                "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\
8967                 returns 0x%x", err);
8968            return err;
8969        }
8970
8971        if( pC->ReaderVideoAU1.m_maxsize
8972            > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
8973        {
8974            /* Constant memory reader case, we need to reallocate the temporary buffers */
8975            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8976                *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
8977            /* pC->m_pDataVideoAddress1
8978            and pC->m_pDataVideoAddress2 must be reallocated at the same time */
8979            /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
8980             Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
8981             m_basicProperties.m_maxAUSize)" is never true */
8982            /* and the size of the second buffer is never changed. */
8983            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8984                *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
8985            /* pC->m_pDataVideoAddress1 and
8986            pC->m_pDataVideoAddress2 must be reallocated at the same time */
8987            /* Update stream properties */
8988            pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
8989                pC->ReaderVideoAU1.m_maxsize;
8990        }
8991        memcpy((void *)pC->m_pDataVideoAddress1,
8992            (void *)pC->ReaderVideoAU1.m_dataAddress,
8993            pC->ReaderVideoAU1.m_size);
8994    }
8995
8996    if( pC->ReaderVideoAU2.m_structSize == 0 )
8997    {
8998        /**
8999        * Initializes an access Unit */
9000        err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
9001            (M4_StreamHandler *)pC->pReaderVideoStream,
9002            &pC->ReaderVideoAU2);
9003
9004        if( M4NO_ERROR != err )
9005        {
9006            M4OSA_TRACE1_1(
9007                "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
9008                err);
9009            return err;
9010        }
9011        pC->m_pDataVideoAddress2 =
9012            (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU2.m_maxsize, M4MCS,
9013            (M4OSA_Char *)"Temporary video AU buffer");
9014
9015        if( pC->m_pDataVideoAddress2 == M4OSA_NULL )
9016        {
9017            M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
9018            return M4ERR_ALLOC;
9019        }
9020    }
9021    /**
9022    * Read the next video AU in the input file */
9023    if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS )
9024    {
9025        memcpy((void *) &pC->ReaderVideoAU,
9026            (void *) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit));
9027        err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
9028            (M4_StreamHandler *)pC->pReaderVideoStream,
9029            &pC->ReaderVideoAU1);
9030
9031        if( pC->ReaderVideoAU1.m_maxsize
9032            > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
9033        {
9034            /* Constant memory reader case, we need to reallocate the temporary buffers */
9035            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9036                *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
9037            /* pC->m_pDataVideoAddress1 and
9038             pC->m_pDataVideoAddress2 must be reallocated at the same time */
9039            /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
9040             Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
9041             m_basicProperties.m_maxAUSize)" is never true */
9042            /* and the size of the second buffer is never changed. */
9043            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9044                *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
9045            /* pC->m_pDataVideoAddress1 and
9046            pC->m_pDataVideoAddress2 must be reallocated at the same time */
9047            /* Update stream properties */
9048            pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
9049                pC->ReaderVideoAU1.m_maxsize;
9050        }
9051        memcpy((void *)pC->m_pDataVideoAddress1,
9052            (void *)pC->ReaderVideoAU1.m_dataAddress,
9053            pC->ReaderVideoAU1.m_size);
9054        videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS;
9055        pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2;
9056    }
9057    else
9058    {
9059        memcpy((void *) &pC->ReaderVideoAU,
9060            (void *) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit));
9061        err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
9062            (M4_StreamHandler *)pC->pReaderVideoStream,
9063            &pC->ReaderVideoAU2);
9064
9065        if( pC->ReaderVideoAU2.m_maxsize
9066            > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
9067        {
9068            /* Constant memory reader case, we need to reallocate the temporary buffers */
9069            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9070                *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize);
9071            /* pC->m_pDataVideoAddress1 and
9072             pC->m_pDataVideoAddress2 must be reallocated at the same time */
9073            /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
9074             Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
9075             m_basicProperties.m_maxAUSize)" is never true */
9076            /* and the size of the second buffer is never changed. */
9077            M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9078                *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize);
9079            /* pC->m_pDataVideoAddress1 and
9080            pC->m_pDataVideoAddress2 must be reallocated at the same time */
9081            /* Update stream properties */
9082            pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
9083                pC->ReaderVideoAU2.m_maxsize;
9084        }
9085        memcpy((void *)pC->m_pDataVideoAddress2,
9086            (void *)pC->ReaderVideoAU2.m_dataAddress,
9087            pC->ReaderVideoAU2.m_size);
9088        videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS;
9089        pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1;
9090    }
9091
9092    if( M4WAR_NO_MORE_AU == err )
9093    {
9094        M4OSA_TRACE2_0(
9095            "M4MCS_intVideoNullEncoding():\
9096             m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
9097        /* The video transcoding is finished */
9098        pC->VideoState = M4MCS_kStreamState_FINISHED;
9099        return err;
9100    }
9101    else if( M4NO_ERROR != err )
9102    {
9103        M4OSA_TRACE1_1(
9104            "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x",
9105            err);
9106        return err;
9107    }
9108    else
9109    {
9110        /**
9111        * Prepare the writer AU */
9112        err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
9113            M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
9114
9115        if( M4NO_ERROR != err )
9116        {
9117            M4OSA_TRACE1_1(
9118                "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x",
9119                err);
9120            return err;
9121        }
9122            /**
9123            * Copy video data from reader AU to writer AU */
9124            M4OSA_TRACE3_1(
9125                "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d",
9126                pC->ReaderVideoAU.m_size);
9127            /* + CRLV6775 -H.264 Trimming */
9128            if( M4OSA_TRUE == pC->bH264Trim )
9129            {
9130                if( pC->H264MCSTempBufferSize
9131                    < (pC->ReaderVideoAU.m_size + 2048) )
9132                {
9133                    pC->H264MCSTempBufferSize =
9134                        (pC->ReaderVideoAU.m_size + 2048);
9135
9136                    if( pC->H264MCSTempBuffer != M4OSA_NULL )
9137                    {
9138                        free(pC->H264MCSTempBuffer);
9139                    }
9140                    pC->H264MCSTempBuffer =
9141                        (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->H264MCSTempBufferSize,
9142                        M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer");
9143
9144                    if( pC->H264MCSTempBuffer == M4OSA_NULL )
9145                    {
9146                        M4OSA_TRACE1_0(
9147                            "M4MCS_intVideoNullEncoding(): allocation error");
9148                        return M4ERR_ALLOC;
9149                    }
9150                }
9151
9152                pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize;
9153
9154                err = H264MCS_ProcessNALU(pC->m_pInstance,
9155                    (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress,
9156                    pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer,
9157                    (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize);
9158
9159                if( pC->m_pInstance->is_done == 1 )
9160                {
9161                    M4MCS_convetFromByteStreamtoNALStream(
9162                        (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress ,
9163                        pC->ReaderVideoAU.m_size);
9164
9165                    memcpy((void *)pC->WriterVideoAU.dataAddress,
9166                        (void *)(pC->ReaderVideoAU.m_dataAddress + 4),
9167                        pC->ReaderVideoAU.m_size - 4);
9168                    pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4;
9169                    WritebufferAdd =
9170                        (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
9171                }
9172                else
9173                {
9174                    memcpy((void *)pC->WriterVideoAU.dataAddress,
9175                        (void *)(pC->H264MCSTempBuffer + 4),
9176                        pC->H264MCSTempBufferDataSize - 4);
9177                    pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4;
9178                    WritebufferAdd =
9179                        (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
9180                }
9181            }
9182            /* H.264 Trimming */
9183            else
9184            {
9185                memcpy((void *)pC->WriterVideoAU.dataAddress,
9186                    (void *)pC->ReaderVideoAU.m_dataAddress,
9187                    pC->ReaderVideoAU.m_size);
9188                pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size;
9189            }
9190            /**
9191            * Convert CTS unit from milliseconds to timescale */
9192            pC->WriterVideoAU.CTS =
9193                (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts)
9194                * (pC->WriterVideoStream.timeScale / 1000.0)));
9195            pC->WriterVideoAU.nbFrag = 0;
9196            pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute;
9197
9198            M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms",
9199                pC->WriterVideoAU.CTS);
9200
9201        /**
9202        * Write it to the output file */
9203        pC->uiVideoAUCount++;
9204        err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
9205            M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
9206
9207        if( M4NO_ERROR != err )
9208        {
9209            M4OSA_TRACE1_1(
9210                "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x",
9211                err);
9212            return err;
9213        }
9214        /* + CRLV6775 -H.264 Trimming */
9215        if( M4OSA_TRUE == pC->bH264Trim )
9216        {
9217            if( pC->m_pInstance->is_done == 1 )
9218            {
9219                memcpy((void *)(WritebufferAdd - 4),
9220                    (void *)(pC->ReaderVideoAU.m_dataAddress), 4);
9221            }
9222            else
9223            {
9224                memcpy((void *)(WritebufferAdd - 4),
9225                    (void *)(pC->H264MCSTempBuffer), 4);
9226            }
9227        } /* H.264 Trimming */
9228    }
9229    /**
9230    * Check for end cut. */
9231    /* Bug fix 11/12/2008: We absolutely want to have less or same video duration ->
9232    (2*videoAUDuration) to have a more precise end cut*/
9233    if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime )
9234    {
9235        pC->VideoState = M4MCS_kStreamState_FINISHED;
9236    }
9237
9238    /**
9239    * Return with no error */
9240    M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR");
9241    return M4NO_ERROR;
9242}
9243
9244/**
9245 ******************************************************************************
9246 * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC)
9247 * @author   Alexis Vapillon (NXP Software Vision)
9248 * @return   M4NO_ERROR:         No error
9249 ******************************************************************************
9250 */
9251static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC )
9252{
9253    M4OSA_ERR err = M4NO_ERROR;
9254    M4_MediaTime mtTranscodedTime = 0.0;
9255    M4ENCODER_FrameMode FrameMode;
9256    M4OSA_Int32 derive = 0;
9257
9258    /**
9259    * Get video CTS to decode */
9260    mtTranscodedTime = pC->dViDecCurrentCts;
9261    FrameMode = M4ENCODER_kNormalFrame;
9262
9263    /**
9264    * Decode video */
9265    M4OSA_TRACE3_1(
9266        "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)",
9267        mtTranscodedTime);
9268    pC->isRenderDup = M4OSA_FALSE;
9269    err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime,
9270        M4OSA_FALSE);
9271
9272    if( M4WAR_NO_MORE_AU == err )
9273    {
9274        FrameMode =
9275            M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
9276            ask for the end of the encoding */
9277        pC->VideoState = M4MCS_kStreamState_FINISHED;
9278    }
9279    else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
9280    {
9281        M4OSA_TRACE2_0("Decoding output the same frame as before 3");
9282        pC->isRenderDup = M4OSA_TRUE;
9283    }
9284    else if( M4NO_ERROR != err )
9285    {
9286        M4OSA_TRACE1_1(
9287            "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!",
9288            err);
9289        return err;
9290    }
9291
9292    /**
9293    * Check for end cut.
9294    * We must check here if the end cut is reached, because in that case we must
9295    * call the last encode step (-> bLastFrame set to true) */
9296    if( ( pC->dViDecCurrentCts + pC->dCtsIncrement ) >= (pC->uiEndCutTime
9297        + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) )
9298    {
9299        FrameMode =
9300            M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
9301            ask for the end of the encoding */
9302        pC->VideoState = M4MCS_kStreamState_FINISHED;
9303        derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5)
9304            - (pC->uiEndCutTime
9305            + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)));
9306    }
9307
9308    /* Update starting CTS to have a more precise value (
9309    the begin cut is not a real CTS)*/
9310    if( pC->uiVideoAUCount == 0 )
9311    {
9312        pC->dViDecStartingCts = mtTranscodedTime;
9313        pC->dViDecCurrentCts = pC->dViDecStartingCts;
9314    }
9315
9316    /**
9317    * Encode video */
9318    M4OSA_TRACE3_1(
9319        "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\
9320         = %.2f",pC->ReaderVideoAU.m_CTS);
9321    pC->uiVideoAUCount++;
9322    /* update the given duration (the begin cut is not a real CTS)*/
9323    err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL,
9324        (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)),
9325        FrameMode);
9326
9327    return err;
9328}
9329
9330/**
9331 ******************************************************************************
9332 * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext)
9333 * @author   Dounya Manai (NXP Software Vision)
9334 * @brief    Retrieve the properties of the audio and video streams from the input file.
9335 * @param    pContext            (IN) MCS context
9336 * @return   M4NO_ERROR:         No error
9337 * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
9338 ******************************************************************************
9339 */
9340static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC )
9341{
9342    M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo;
9343    M4READER_3GP_H263Properties H263prop;
9344    M4OSA_ERR err;
9345    M4OSA_UInt32 videoBitrate;
9346    M4DECODER_AVCProfileLevel AVCProfle;
9347#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
9348
9349    M4DECODER_VideoSize videoSize;
9350
9351#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
9352
9353    M4_AACType iAacType = 0;
9354
9355    /**
9356    * Check input parameters */
9357    M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER,
9358        "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL");
9359
9360    /**
9361    * Reset common characteristics */
9362    pC->InputFileProperties.bAnalysed = M4OSA_FALSE;
9363    pC->InputFileProperties.FileType = 0;
9364    pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR;
9365    pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR;
9366    pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION;
9367    pC->InputFileProperties.uiClipDuration = 0;
9368
9369    memset((void *) &pC->InputFileProperties.ftyp,
9370        0, sizeof(M4VIDEOEDITING_FtypBox));
9371
9372    /**
9373    * Reset video characteristics */
9374    pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
9375    pC->InputFileProperties.uiClipVideoDuration = 0;
9376    pC->InputFileProperties.uiVideoBitrate = 0;
9377    pC->InputFileProperties.uiVideoMaxAuSize = 0;
9378    pC->InputFileProperties.uiVideoWidth = 0;
9379    pC->InputFileProperties.uiVideoHeight = 0;
9380    pC->InputFileProperties.uiVideoTimeScale = 0;
9381    pC->InputFileProperties.fAverageFrameRate = 0.0;
9382    pC->InputFileProperties.ProfileAndLevel =
9383        M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range;
9384    pC->InputFileProperties.uiH263level = 0;
9385    pC->InputFileProperties.uiVideoProfile = 0;
9386    pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE;
9387    pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE;
9388    pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE;
9389
9390    /**
9391    * Reset audio characteristics */
9392    pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
9393    pC->InputFileProperties.uiClipAudioDuration = 0;
9394    pC->InputFileProperties.uiAudioBitrate = 0;
9395    pC->InputFileProperties.uiAudioMaxAuSize = 0;
9396    pC->InputFileProperties.uiNbChannels = 0;
9397    pC->InputFileProperties.uiSamplingFrequency = 0;
9398    pC->InputFileProperties.uiExtendedSamplingFrequency = 0;
9399    pC->InputFileProperties.uiDecodedPcmSize = 0;
9400
9401    /* Reset compatibility chart (not used in MCS) */
9402    pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE;
9403    pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE;
9404    pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE;
9405    pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
9406
9407    /**
9408    * Video stream properties */
9409    if( M4OSA_NULL != pC->pReaderVideoStream )
9410    {
9411        switch( pC->pReaderVideoStream->m_basicProperties.m_streamType )
9412        {
9413            case M4DA_StreamTypeVideoMpeg4:
9414                pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4;
9415                break;
9416
9417            case M4DA_StreamTypeVideoH263:
9418                pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263;
9419                break;
9420
9421            case M4DA_StreamTypeVideoMpeg4Avc:
9422                pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264;
9423                break;
9424
9425            case M4DA_StreamTypeUnknown:
9426            default:
9427                pC->InputFileProperties.VideoStreamType =
9428                    M4VIDEOEDITING_kUnsupportedVideo;
9429                break;
9430        }
9431
9432        /* if bitrate not available retrieve an estimation of the overall bitrate */
9433        pC->InputFileProperties.uiVideoBitrate =
9434            pC->pReaderVideoStream->m_basicProperties.m_averageBitRate;
9435
9436        if( 0 == pC->InputFileProperties.uiVideoBitrate )
9437        {
9438            pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9439                M4READER_kOptionID_Bitrate, &videoBitrate);
9440
9441            if( M4OSA_NULL != pC->pReaderAudioStream )
9442            {
9443                /* we get the overall bitrate, substract the audio bitrate if any */
9444                videoBitrate -=
9445                    pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
9446            }
9447            pC->InputFileProperties.uiVideoBitrate = videoBitrate;
9448        }
9449
9450        /**
9451        * Retrieve the Profile & Level */
9452        if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType)
9453            && (M4VIDEOEDITING_kH264
9454            != pC->InputFileProperties.VideoStreamType) )
9455        {
9456#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
9457            /* Use the DSI parsing function from the external video shell decoder.
9458            See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the
9459            same issue. */
9460
9461            err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream->
9462                m_basicProperties.m_pDecoderSpecificInfo,
9463                pC->pReaderVideoStream->
9464                m_basicProperties.m_decoderSpecificInfoSize,
9465                &DecConfInfo, &videoSize);
9466
9467            if( M4NO_ERROR != err )
9468            {
9469                M4OSA_TRACE1_1(
9470                    "M4MCS_intGetInputClipProperties():\
9471                     M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X",
9472                    err);
9473                return err;
9474            }
9475
9476            pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth;
9477            pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight;
9478
9479#else
9480            /*FB 2009-02-09: add a check on the video decoder context to
9481            avoid crash when the MCS is used only with audio codecs compilated*/
9482
9483            if( pC->m_pVideoDecoder != M4OSA_NULL )
9484            {
9485                if( M4OSA_NULL == pC->pViDecCtxt )
9486                {
9487                    err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt,
9488                        &pC->pReaderVideoStream->m_basicProperties,
9489                        pC->m_pReaderDataIt, &pC->ReaderVideoAU,
9490                        M4OSA_NULL);
9491
9492                    if( M4NO_ERROR != err )
9493                    {
9494                        M4OSA_TRACE1_1(
9495                            "M4MCS_intGetInputClipProperties:\
9496                             m_pVideoDecoder->m_pFctCreate returns 0x%x!",
9497                            err);
9498                        return err;
9499                    }
9500                }
9501
9502                err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt,
9503                    M4DECODER_MPEG4_kOptionID_DecoderConfigInfo,
9504                    &DecConfInfo);
9505
9506                if( M4NO_ERROR != err )
9507                {
9508                    M4OSA_TRACE1_1(
9509                        "M4MCS_intGetInputClipProperties:\
9510                         m_pVideoDecoder->m_pFctGetOption returns 0x%x!",
9511                        err);
9512                    return err;
9513                }
9514            }
9515
9516#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
9517
9518            pC->InputFileProperties.uiVideoProfile = DecConfInfo.uiProfile;
9519            pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale;
9520            pC->InputFileProperties.bMPEG4dataPartition =
9521                DecConfInfo.bDataPartition;
9522            pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC;
9523            pC->InputFileProperties.bMPEG4resynchMarker =
9524                DecConfInfo.uiUseOfResynchMarker;
9525
9526            /* Supported enum value for profile and level */
9527            switch( pC->InputFileProperties.uiVideoProfile )
9528            {
9529                case 0x08:
9530                    pC->InputFileProperties.ProfileAndLevel =
9531                        M4VIDEOEDITING_kMPEG4_SP_Level_0;
9532                    break;
9533
9534                case 0x09:
9535                    pC->InputFileProperties.ProfileAndLevel =
9536                        M4VIDEOEDITING_kMPEG4_SP_Level_0b;
9537                    break;
9538
9539                case 0x01:
9540                    pC->InputFileProperties.ProfileAndLevel =
9541                        M4VIDEOEDITING_kMPEG4_SP_Level_1;
9542                    break;
9543
9544                case 0x02:
9545                    pC->InputFileProperties.ProfileAndLevel =
9546                        M4VIDEOEDITING_kMPEG4_SP_Level_2;
9547                    break;
9548
9549                case 0x03:
9550                    pC->InputFileProperties.ProfileAndLevel =
9551                        M4VIDEOEDITING_kMPEG4_SP_Level_3;
9552                    break;
9553
9554                case 0x04:
9555                    pC->InputFileProperties.ProfileAndLevel =
9556                        M4VIDEOEDITING_kMPEG4_SP_Level_4a;
9557                    break;
9558
9559                case 0x05:
9560                    pC->InputFileProperties.ProfileAndLevel =
9561                        M4VIDEOEDITING_kMPEG4_SP_Level_5;
9562                    break;
9563            }
9564        }
9565        else if( M4VIDEOEDITING_kH263
9566            == pC->InputFileProperties.VideoStreamType )
9567        {
9568            err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9569                M4READER_3GP_kOptionID_H263Properties, &H263prop);
9570
9571            if( M4NO_ERROR != err )
9572            {
9573                M4OSA_TRACE1_1(
9574                    "M4MCS_intGetInputClipProperties: m_pReader->m_pFctGetOption returns 0x%x!",
9575                    err);
9576                return err;
9577            }
9578
9579            pC->InputFileProperties.uiH263level = H263prop.uiLevel;
9580            pC->InputFileProperties.uiVideoProfile = H263prop.uiProfile;
9581
9582            /* Supported enum value for profile and level */
9583            if( pC->InputFileProperties.uiVideoProfile == 0 )
9584            {
9585                switch( pC->InputFileProperties.uiH263level )
9586                {
9587                    case 10:
9588                        pC->InputFileProperties.ProfileAndLevel =
9589                            M4VIDEOEDITING_kH263_Profile_0_Level_10;
9590                        break;
9591
9592                    case 20:
9593                        pC->InputFileProperties.ProfileAndLevel =
9594                            M4VIDEOEDITING_kH263_Profile_0_Level_20;
9595                        break;
9596
9597                    case 30:
9598                        pC->InputFileProperties.ProfileAndLevel =
9599                            M4VIDEOEDITING_kH263_Profile_0_Level_30;
9600                        break;
9601
9602                    case 40:
9603                        pC->InputFileProperties.ProfileAndLevel =
9604                            M4VIDEOEDITING_kH263_Profile_0_Level_40;
9605                        break;
9606
9607                    case 45:
9608                        pC->InputFileProperties.ProfileAndLevel =
9609                            M4VIDEOEDITING_kH263_Profile_0_Level_45;
9610                        break;
9611                }
9612            }
9613
9614            /* For h263 set default timescale : 30000:1001 */
9615            pC->InputFileProperties.uiVideoTimeScale = 30000;
9616        }
9617        else if( M4VIDEOEDITING_kH264
9618            == pC->InputFileProperties.VideoStreamType )
9619        {
9620            AVCProfle = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range;
9621            pC->InputFileProperties.uiVideoTimeScale = 30000;
9622#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
9623
9624            err = M4DECODER_EXTERNAL_ParseAVCDSI(pC->pReaderVideoStream->
9625                m_basicProperties.m_pDecoderSpecificInfo,
9626                pC->pReaderVideoStream->
9627                m_basicProperties.m_decoderSpecificInfoSize,
9628                &AVCProfle);
9629
9630            if( M4NO_ERROR != err )
9631            {
9632                M4OSA_TRACE1_1(
9633                    "M4MCS_intGetInputClipProperties():\
9634                     M4DECODER_EXTERNAL_ParseAVCDSI returns 0x%08X",
9635                    err);
9636                return err;
9637            }
9638
9639#else
9640
9641            if( pC->m_pVideoDecoder != M4OSA_NULL )
9642            {
9643                if( M4OSA_NULL == pC->pViDecCtxt )
9644                {
9645                    err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt,
9646                        &pC->pReaderVideoStream->m_basicProperties,
9647                        pC->m_pReaderDataIt, &pC->ReaderVideoAU,
9648                        M4OSA_NULL);
9649
9650                    if( M4NO_ERROR != err )
9651                    {
9652                        M4OSA_TRACE1_1(
9653                            "M4MCS_intGetInputClipProperties:\
9654                             m_pVideoDecoder->m_pFctCreate returns 0x%x!",
9655                            err);
9656                        return err;
9657                    }
9658                }
9659                err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt,
9660                    M4DECODER_kOptionID_AVCProfileAndLevel, &AVCProfle);
9661
9662                if( M4NO_ERROR != err )
9663                {
9664                    M4OSA_TRACE1_1(
9665                        "M4MCS_intGetInputClipProperties:\
9666                         m_pVideoDecoder->m_pFctGetOption returns 0x%x!",
9667                        err);
9668                    return err;
9669                }
9670            }
9671
9672#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
9673
9674            switch( AVCProfle )
9675            {
9676                case M4DECODER_AVC_kProfile_0_Level_1:
9677                    pC->InputFileProperties.ProfileAndLevel =
9678                        M4VIDEOEDITING_kH264_Profile_0_Level_1;
9679                    break;
9680
9681                case M4DECODER_AVC_kProfile_0_Level_1b:
9682                    pC->InputFileProperties.ProfileAndLevel =
9683                        M4VIDEOEDITING_kH264_Profile_0_Level_1b;
9684                    break;
9685
9686                case M4DECODER_AVC_kProfile_0_Level_1_1:
9687                    pC->InputFileProperties.ProfileAndLevel =
9688                        M4VIDEOEDITING_kH264_Profile_0_Level_1_1;
9689                    break;
9690
9691                case M4DECODER_AVC_kProfile_0_Level_1_2:
9692                    pC->InputFileProperties.ProfileAndLevel =
9693                        M4VIDEOEDITING_kH264_Profile_0_Level_1_2;
9694                    break;
9695
9696                case M4DECODER_AVC_kProfile_0_Level_1_3:
9697                    pC->InputFileProperties.ProfileAndLevel =
9698                        M4VIDEOEDITING_kH264_Profile_0_Level_1_3;
9699                    break;
9700
9701                case M4DECODER_AVC_kProfile_0_Level_2:
9702                    pC->InputFileProperties.ProfileAndLevel =
9703                        M4VIDEOEDITING_kH264_Profile_0_Level_2;
9704                    break;
9705
9706                case M4DECODER_AVC_kProfile_0_Level_2_1:
9707                    pC->InputFileProperties.ProfileAndLevel =
9708                        M4VIDEOEDITING_kH264_Profile_0_Level_2_1;
9709                    break;
9710
9711                case M4DECODER_AVC_kProfile_0_Level_2_2:
9712                    pC->InputFileProperties.ProfileAndLevel =
9713                        M4VIDEOEDITING_kH264_Profile_0_Level_2_2;
9714                    break;
9715
9716                case M4DECODER_AVC_kProfile_0_Level_3:
9717                    pC->InputFileProperties.ProfileAndLevel =
9718                        M4VIDEOEDITING_kH264_Profile_0_Level_3;
9719                    break;
9720
9721                case M4DECODER_AVC_kProfile_0_Level_3_1:
9722                    pC->InputFileProperties.ProfileAndLevel =
9723                        M4VIDEOEDITING_kH264_Profile_0_Level_3_1;
9724                    break;
9725
9726                case M4DECODER_AVC_kProfile_0_Level_3_2:
9727                    pC->InputFileProperties.ProfileAndLevel =
9728                        M4VIDEOEDITING_kH264_Profile_0_Level_3_2;
9729                    break;
9730
9731                case M4DECODER_AVC_kProfile_0_Level_4:
9732                    pC->InputFileProperties.ProfileAndLevel =
9733                        M4VIDEOEDITING_kH264_Profile_0_Level_4;
9734                    break;
9735
9736                case M4DECODER_AVC_kProfile_0_Level_4_1:
9737                    pC->InputFileProperties.ProfileAndLevel =
9738                        M4VIDEOEDITING_kH264_Profile_0_Level_4_1;
9739                    break;
9740
9741                case M4DECODER_AVC_kProfile_0_Level_4_2:
9742                    pC->InputFileProperties.ProfileAndLevel =
9743                        M4VIDEOEDITING_kH264_Profile_0_Level_4_2;
9744                    break;
9745
9746                case M4DECODER_AVC_kProfile_0_Level_5:
9747                    pC->InputFileProperties.ProfileAndLevel =
9748                        M4VIDEOEDITING_kH264_Profile_0_Level_5;
9749                    break;
9750
9751                case M4DECODER_AVC_kProfile_0_Level_5_1:
9752                    pC->InputFileProperties.ProfileAndLevel =
9753                        M4VIDEOEDITING_kH264_Profile_0_Level_5_1;
9754                    break;
9755
9756                case M4DECODER_AVC_kProfile_and_Level_Out_Of_Range:
9757                default:
9758                    pC->InputFileProperties.ProfileAndLevel =
9759                        M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range;
9760            }
9761        }
9762
9763        /* Here because width x height is correct only after dsi parsing
9764        (done in create decoder) */
9765        pC->InputFileProperties.uiVideoHeight =
9766            pC->pReaderVideoStream->m_videoHeight;
9767        pC->InputFileProperties.uiVideoWidth =
9768            pC->pReaderVideoStream->m_videoWidth;
9769        pC->InputFileProperties.uiClipVideoDuration =
9770            (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration;
9771        pC->InputFileProperties.fAverageFrameRate =
9772            pC->pReaderVideoStream->m_averageFrameRate;
9773        pC->InputFileProperties.uiVideoMaxAuSize =
9774            pC->pReaderVideoStream->m_basicProperties.m_maxAUSize;
9775    }
9776    else
9777    {
9778        if( M4OSA_TRUE == pC->bUnsupportedVideoFound )
9779        {
9780            pC->InputFileProperties.VideoStreamType =
9781                M4VIDEOEDITING_kUnsupportedVideo;
9782        }
9783        else
9784        {
9785            pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
9786        }
9787    }
9788
9789    /**
9790    * Audio stream properties */
9791    if( M4OSA_NULL != pC->pReaderAudioStream )
9792    {
9793        switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
9794        {
9795            case M4DA_StreamTypeAudioAmrNarrowBand:
9796                pC->InputFileProperties.AudioStreamType =
9797                    M4VIDEOEDITING_kAMR_NB;
9798                break;
9799
9800            case M4DA_StreamTypeAudioAac:
9801                pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC;
9802                break;
9803
9804            case M4DA_StreamTypeAudioMp3:
9805                pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3;
9806                break;
9807
9808            case M4DA_StreamTypeAudioEvrc:
9809                pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC;
9810                break;
9811
9812            case M4DA_StreamTypeUnknown:
9813            default:
9814                pC->InputFileProperties.AudioStreamType =
9815                    M4VIDEOEDITING_kUnsupportedAudio;
9816                break;
9817        }
9818
9819        if( ( M4OSA_NULL != pC->m_pAudioDecoder)
9820            && (M4OSA_NULL == pC->pAudioDecCtxt) )
9821        {
9822            M4OSA_TRACE3_1(
9823                "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x",
9824                pC->m_pCurrentAudioDecoderUserData);
9825            /* Trick, I use pUserData to retrieve aac properties, waiting for some
9826             better implementation... */
9827            if( M4DA_StreamTypeAudioAac
9828                == pC->pReaderAudioStream->m_basicProperties.m_streamType )
9829            {
9830                if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) {
9831                    err = M4MCS_intCheckAndGetCodecAacProperties(pC);
9832                }
9833                else
9834                {
9835                    err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
9836                        &pC->pAudioDecCtxt, pC->pReaderAudioStream,
9837                        pC->m_pCurrentAudioDecoderUserData);
9838
9839                    if( M4NO_ERROR == err )
9840                    {
9841                        /* AAC properties*/
9842                        //get from Reader; temporary, till Audio decoder shell API available to
9843                        //get the AAC properties
9844                        pC->AacProperties.aNumChan =
9845                            pC->pReaderAudioStream->m_nbChannels;
9846                        pC->AacProperties.aSampFreq =
9847                            pC->pReaderAudioStream->m_samplingFrequency;
9848
9849                        err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(
9850                            pC->pAudioDecCtxt, M4AD_kOptionID_StreamType,
9851                            (M4OSA_DataOption) &iAacType);
9852
9853                        if( M4NO_ERROR != err )
9854                        {
9855                            M4OSA_TRACE1_1(
9856                                "M4MCS_intGetInputClipProperties:\
9857                                 m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x",
9858                                err);
9859                            iAacType = M4_kAAC; //set to default
9860                            err = M4NO_ERROR;
9861                        }
9862                        else
9863                        {
9864                            M4OSA_TRACE3_1(
9865                                "M4MCS_intGetInputClipProperties:\
9866                                 m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d",
9867                                iAacType);
9868                        }
9869
9870                        switch( iAacType )
9871                        {
9872                            case M4_kAAC:
9873                                pC->AacProperties.aSBRPresent = 0;
9874                                pC->AacProperties.aPSPresent = 0;
9875                                break;
9876
9877                            case M4_kAACplus:
9878                                pC->AacProperties.aSBRPresent = 1;
9879                                pC->AacProperties.aPSPresent = 0;
9880                                pC->AacProperties.aExtensionSampFreq =
9881                                    pC->pReaderAudioStream->
9882                                    m_samplingFrequency; //TODO
9883                                break;
9884
9885                            case M4_keAACplus:
9886                                pC->AacProperties.aSBRPresent = 1;
9887                                pC->AacProperties.aPSPresent = 1;
9888                                pC->AacProperties.aExtensionSampFreq =
9889                                    pC->pReaderAudioStream->
9890                                    m_samplingFrequency; //TODO
9891                                break;
9892                              case M4_kUnknown:
9893                              break;
9894                              default:
9895                              break;
9896                            }
9897                            M4OSA_TRACE3_2(
9898                                "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d",
9899                                pC->AacProperties.aNumChan,
9900                                pC->AacProperties.aSampFreq);
9901                    }
9902                }
9903            }
9904            else
9905                err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
9906                &pC->pAudioDecCtxt, pC->pReaderAudioStream,
9907                pC->m_pCurrentAudioDecoderUserData);
9908
9909            if( M4NO_ERROR != err )
9910            {
9911                M4OSA_TRACE1_1(
9912                    "M4MCS_intGetInputClipProperties:\
9913                     m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
9914                    err);
9915                return err;
9916            }
9917        }
9918
9919        //EVRC
9920        if( pC->pReaderAudioStream->m_basicProperties.m_streamType
9921            == M4DA_StreamTypeAudioEvrc )
9922        {
9923            /* decoder not implemented yet, provide some default values for the null encoding */
9924            pC->pReaderAudioStream->m_nbChannels = 1;
9925            pC->pReaderAudioStream->m_samplingFrequency = 8000;
9926        }
9927
9928        /**
9929        * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according
9930         the GetProperties function */
9931        if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate )
9932        {
9933            if( M4VIDEOEDITING_kAMR_NB
9934                == pC->InputFileProperties.AudioStreamType )
9935            {
9936                /**
9937                * Better returning a guessed 12.2 kbps value than a sure-to-be-false
9938                0 kbps value! */
9939                pC->InputFileProperties.uiAudioBitrate =
9940                    M4VIDEOEDITING_k12_2_KBPS;
9941            }
9942            else if( M4VIDEOEDITING_kEVRC
9943                == pC->InputFileProperties.AudioStreamType )
9944            {
9945                /**
9946                * Better returning a guessed 8.5 kbps value than a sure-to-be-false
9947                0 kbps value! */
9948                pC->InputFileProperties.uiAudioBitrate =
9949                    M4VIDEOEDITING_k9_2_KBPS;
9950            }
9951            else
9952            {
9953                M4OSA_UInt32 FileBitrate;
9954
9955                /* Can happen also for aac, in this case we calculate an approximative */
9956                /* value from global bitrate and video bitrate */
9957                err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9958                    M4READER_kOptionID_Bitrate,
9959                    (M4OSA_DataOption) &FileBitrate);
9960
9961                if( M4NO_ERROR != err )
9962                {
9963                    M4OSA_TRACE1_1(
9964                        "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x",
9965                        err);
9966                    return err;
9967                }
9968                pC->InputFileProperties.uiAudioBitrate =
9969                    FileBitrate
9970                    - pC->
9971                    InputFileProperties.
9972                    uiVideoBitrate /* normally setted to 0, if no video */;
9973            }
9974        }
9975        else
9976        {
9977            pC->InputFileProperties.uiAudioBitrate =
9978                pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
9979        }
9980
9981        pC->InputFileProperties.uiNbChannels =
9982            pC->pReaderAudioStream->m_nbChannels;
9983        pC->InputFileProperties.uiSamplingFrequency =
9984            pC->pReaderAudioStream->m_samplingFrequency;
9985        pC->InputFileProperties.uiClipAudioDuration =
9986            (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration;
9987        pC->InputFileProperties.uiAudioMaxAuSize =
9988            pC->pReaderAudioStream->m_basicProperties.m_maxAUSize;
9989
9990        /* Bug: with aac, value is 0 until decoder start() is called */
9991        pC->InputFileProperties.uiDecodedPcmSize =
9992            pC->pReaderAudioStream->m_byteFrameLength
9993            * pC->pReaderAudioStream->m_byteSampleSize
9994            * pC->pReaderAudioStream->m_nbChannels;
9995
9996        /* New aac properties */
9997        if( M4DA_StreamTypeAudioAac
9998            == pC->pReaderAudioStream->m_basicProperties.m_streamType )
9999        {
10000            pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan;
10001            pC->InputFileProperties.uiSamplingFrequency =
10002                pC->AacProperties.aSampFreq;
10003
10004            if( pC->AacProperties.aSBRPresent )
10005            {
10006                pC->InputFileProperties.AudioStreamType =
10007                    M4VIDEOEDITING_kAACplus;
10008                pC->InputFileProperties.uiExtendedSamplingFrequency =
10009                    pC->AacProperties.aExtensionSampFreq;
10010            }
10011
10012            if( pC->AacProperties.aPSPresent )
10013            {
10014                pC->InputFileProperties.AudioStreamType =
10015                    M4VIDEOEDITING_keAACplus;
10016            }
10017        }
10018    }
10019    else
10020    {
10021        if( M4OSA_TRUE == pC->bUnsupportedAudioFound )
10022        {
10023            pC->InputFileProperties.AudioStreamType =
10024                M4VIDEOEDITING_kUnsupportedAudio;
10025        }
10026        else
10027        {
10028            pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
10029        }
10030    }
10031
10032    /* Get 'ftyp' atom */
10033    err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
10034        M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp);
10035
10036    if( M4NO_ERROR == err )
10037    {
10038        M4OSA_UInt8 i;
10039
10040        for ( i = 0; i < pC->InputFileProperties.ftyp.nbCompatibleBrands; i++ )
10041            if( M4VIDEOEDITING_BRAND_EMP
10042                == pC->InputFileProperties.ftyp.compatible_brands[i] )
10043                pC->InputFileProperties.VideoStreamType =
10044                M4VIDEOEDITING_kMPEG4_EMP;
10045    }
10046
10047    /* Analysis is successful */
10048    if( pC->InputFileProperties.uiClipVideoDuration
10049        > pC->InputFileProperties.uiClipAudioDuration )
10050        pC->InputFileProperties.uiClipDuration =
10051        pC->InputFileProperties.uiClipVideoDuration;
10052    else
10053        pC->InputFileProperties.uiClipDuration =
10054        pC->InputFileProperties.uiClipAudioDuration;
10055
10056    pC->InputFileProperties.FileType = pC->InputFileType;
10057    pC->InputFileProperties.bAnalysed = M4OSA_TRUE;
10058
10059    return M4NO_ERROR;
10060}
10061
10062/**
10063 ******************************************************************************
10064 * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame)
10065 * @brief   Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer
10066 * @note
10067 * @param   pCpAudioFrame   (IN) AMRNB frame
10068 * @return  M4NO_ERROR: No error
10069 ******************************************************************************
10070 */
10071static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame )
10072{
10073    M4OSA_UInt32 frameSize = 0;
10074    M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3;
10075
10076    switch( frameType )
10077    {
10078        case 0:
10079            frameSize = 95;
10080            break; /*  4750 bps */
10081
10082        case 1:
10083            frameSize = 103;
10084            break; /*  5150 bps */
10085
10086        case 2:
10087            frameSize = 118;
10088            break; /*  5900 bps */
10089
10090        case 3:
10091            frameSize = 134;
10092            break; /*  6700 bps */
10093
10094        case 4:
10095            frameSize = 148;
10096            break; /*  7400 bps */
10097
10098        case 5:
10099            frameSize = 159;
10100            break; /*  7950 bps */
10101
10102        case 6:
10103            frameSize = 204;
10104            break; /* 10200 bps */
10105
10106        case 7:
10107            frameSize = 244;
10108            break; /* 12000 bps */
10109
10110        case 8:
10111            frameSize = 39;
10112            break; /* SID (Silence) */
10113
10114        case 15:
10115            frameSize = 0;
10116            break; /* No data */
10117
10118        default:
10119            M4OSA_TRACE3_0(
10120                "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0.");
10121            return 0;
10122    }
10123
10124    return (1 + (( frameSize + 7) / 8));
10125}
10126
10127/**
10128 ******************************************************************************
10129 * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame)
10130 * @brief   Return the length, in bytes, of the EVRC frame contained in the given buffer
10131 * @note
10132 *     0 1 2 3
10133 *    +-+-+-+-+
10134 *    |fr type|              RFC 3558
10135 *    +-+-+-+-+
10136 *
10137 * Frame Type: 4 bits
10138 *    The frame type indicates the type of the corresponding codec data
10139 *    frame in the RTP packet.
10140 *
10141 * For EVRC and SMV codecs, the frame type values and size of the
10142 * associated codec data frame are described in the table below:
10143 *
10144 * Value   Rate      Total codec data frame size (in octets)
10145 * ---------------------------------------------------------
10146 *   0     Blank      0    (0 bit)
10147 *   1     1/8        2    (16 bits)
10148 *   2     1/4        5    (40 bits; not valid for EVRC)
10149 *   3     1/2       10    (80 bits)
10150 *   4     1         22    (171 bits; 5 padded at end with zeros)
10151 *   5     Erasure    0    (SHOULD NOT be transmitted by sender)
10152 *
10153 * @param   pCpAudioFrame   (IN) EVRC frame
10154 * @return  M4NO_ERROR: No error
10155 ******************************************************************************
10156 */
10157static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame )
10158{
10159    M4OSA_UInt32 frameSize = 0;
10160    M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F;
10161
10162    switch( frameType )
10163    {
10164        case 0:
10165            frameSize = 0;
10166            break; /*  blank */
10167
10168        case 1:
10169            frameSize = 16;
10170            break; /*  1/8 */
10171
10172        case 2:
10173            frameSize = 40;
10174            break; /*  1/4 */
10175
10176        case 3:
10177            frameSize = 80;
10178            break; /*  1/2 */
10179
10180        case 4:
10181            frameSize = 171;
10182            break; /*  1 */
10183
10184        case 5:
10185            frameSize = 0;
10186            break; /*  erasure */
10187
10188        default:
10189            M4OSA_TRACE3_0(
10190                "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0.");
10191            return 0;
10192    }
10193
10194    return (1 + (( frameSize + 7) / 8));
10195}
10196
10197/**
10198 ******************************************************************************
10199 * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext)
10200 * @brief    Check if max file size is greater enough to encode a file with the
10201 *           current selected bitrates and duration.
10202 * @param    pContext            (IN) MCS context
10203 * @return   M4NO_ERROR
10204 * @return   M4MCS_ERR_MAXFILESIZE_TOO_SMALL
10205 ******************************************************************************
10206 */
10207static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext )
10208{
10209    M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
10210
10211    M4OSA_UInt32 duration;
10212    M4OSA_UInt32 audiobitrate;
10213    M4OSA_UInt32 videobitrate;
10214
10215    /* free file size : OK */
10216    if( pC->uiMaxFileSize == 0 )
10217        return M4NO_ERROR;
10218
10219    /* duration */
10220    if( pC->uiEndCutTime == 0 )
10221    {
10222        duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime;
10223    }
10224    else
10225    {
10226        duration = pC->uiEndCutTime - pC->uiBeginCutTime;
10227    }
10228
10229    /* audio bitrate */
10230    if( pC->noaudio )
10231    {
10232        audiobitrate = 0;
10233    }
10234    else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
10235    {
10236        audiobitrate = pC->InputFileProperties.uiAudioBitrate;
10237    }
10238    else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate )
10239    {
10240        switch( pC->AudioEncParams.Format )
10241        {
10242            case M4ENCODER_kAMRNB:
10243                audiobitrate = M4VIDEOEDITING_k12_2_KBPS;
10244                break;
10245                //EVRC
10246                //            case M4ENCODER_kEVRC:
10247                //                audiobitrate = M4VIDEOEDITING_k9_2_KBPS;
10248                //                break;
10249
10250            default: /* AAC and MP3*/
10251                audiobitrate =
10252                    (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
10253                    ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
10254                break;
10255        }
10256    }
10257    else
10258    {
10259        audiobitrate = pC->uiAudioBitrate;
10260    }
10261
10262    /* video bitrate */
10263    if( pC->novideo )
10264    {
10265        videobitrate = 0;
10266    }
10267    else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
10268    {
10269        videobitrate = pC->InputFileProperties.uiVideoBitrate;
10270    }
10271    else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate )
10272    {
10273        videobitrate = M4VIDEOEDITING_k16_KBPS;
10274    }
10275    else
10276    {
10277        videobitrate = pC->uiVideoBitrate;
10278    }
10279
10280    /* max file size */
10281    if( (M4OSA_UInt32)pC->uiMaxFileSize
10282        < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
10283        * (audiobitrate + videobitrate) * (duration / 8000.0)) )
10284        return M4MCS_ERR_MAXFILESIZE_TOO_SMALL;
10285    else
10286        return M4NO_ERROR;
10287}
10288
10289/**
10290 ******************************************************************************
10291 * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode)
10292 * @brief    Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate
10293 * @param    freebitrate: unsigned int value
10294 * @param    mode: -1:previous,0:current,1:next
10295 * @return   bitrate value in enum list M4VIDEOEDITING_Bitrate
10296 ******************************************************************************
10297 */
10298static M4VIDEOEDITING_Bitrate
10299M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode )
10300{
10301    M4OSA_Int32 bitarray [] =
10302    {
10303        0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS,
10304        M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS,
10305        M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS,
10306        M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS,
10307        M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS,
10308        M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS,
10309        M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS,
10310        M4VIDEOEDITING_k5_MBPS,
10311        M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */
10312        M4OSA_INT32_MAX
10313    };
10314
10315    const M4OSA_UInt32 nbbitrates = 14;
10316    M4OSA_UInt32 i;
10317
10318    for ( i = 0; freebitrate >= bitarray[i]; i++ );
10319
10320    switch( mode )
10321    {
10322        case -1: /* previous */
10323            if( i <= 2 )
10324                return 0;
10325            else
10326                return bitarray[i - 2];
10327            break;
10328
10329        case 0: /* current */
10330            if( i <= 1 )
10331                return 0;
10332            else
10333                return bitarray[i - 1];
10334            break;
10335
10336        case 1: /* next */
10337            if( i >= nbbitrates )
10338                return M4OSA_INT32_MAX;
10339            else
10340                return bitarray[i];
10341            break;
10342    }
10343
10344    return 0;
10345}
10346
10347/**
10348 ******************************************************************************
10349 * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC);
10350 * @brief    Free all resources allocated by M4MCS_open()
10351 * @param    pContext            (IN) MCS context
10352 * @return   M4NO_ERROR:         No error
10353 ******************************************************************************
10354 */
10355static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC )
10356{
10357    M4OSA_ERR err = M4NO_ERROR;
10358
10359    M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC);
10360
10361    /* ----- Free reader stuff, if needed ----- */
10362
10363    if( M4OSA_NULL != pC->
10364        pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */
10365    {
10366        err = pC->m_pReader->m_pFctClose(pC->pReaderContext);
10367
10368        if( M4NO_ERROR != err )
10369        {
10370            M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x",
10371                err);
10372            /**< don't return, we still have stuff to free */
10373        }
10374
10375        err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext);
10376        pC->pReaderContext = M4OSA_NULL;
10377
10378        if( M4NO_ERROR != err )
10379        {
10380            M4OSA_TRACE1_1(
10381                "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err);
10382            /**< don't return, we still have stuff to free */
10383        }
10384    }
10385
10386    if( pC->m_pDataAddress1 != M4OSA_NULL )
10387    {
10388        free(pC->m_pDataAddress1);
10389        pC->m_pDataAddress1 = M4OSA_NULL;
10390    }
10391
10392    if( pC->m_pDataAddress2 != M4OSA_NULL )
10393    {
10394        free(pC->m_pDataAddress2);
10395        pC->m_pDataAddress2 = M4OSA_NULL;
10396    }
10397    /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/
10398    if( pC->m_pDataVideoAddress1 != M4OSA_NULL )
10399    {
10400        free(pC->m_pDataVideoAddress1);
10401        pC->m_pDataVideoAddress1 = M4OSA_NULL;
10402    }
10403
10404    if( pC->m_pDataVideoAddress2 != M4OSA_NULL )
10405    {
10406        free(pC->m_pDataVideoAddress2);
10407        pC->m_pDataVideoAddress2 = M4OSA_NULL;
10408    }
10409    /**/
10410    /* ----- Free video decoder stuff, if needed ----- */
10411
10412    if( M4OSA_NULL != pC->pViDecCtxt )
10413    {
10414        err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
10415        pC->pViDecCtxt = M4OSA_NULL;
10416
10417        if( M4NO_ERROR != err )
10418        {
10419            M4OSA_TRACE1_1(
10420                "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x",
10421                err);
10422            /**< don't return, we still have stuff to free */
10423        }
10424    }
10425
10426    /* ----- Free the audio decoder stuff ----- */
10427
10428    if( M4OSA_NULL != pC->pAudioDecCtxt )
10429    {
10430        err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt);
10431        pC->pAudioDecCtxt = M4OSA_NULL;
10432
10433        if( M4NO_ERROR != err )
10434        {
10435            M4OSA_TRACE1_1(
10436                "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
10437                err);
10438            /**< don't return, we still have stuff to free */
10439        }
10440    }
10441
10442    if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress )
10443    {
10444        free(pC->AudioDecBufferOut.m_dataAddress);
10445        pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
10446    }
10447
10448    return M4NO_ERROR;
10449}
10450
10451
10452/**
10453
10454 ******************************************************************************
10455 * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
10456 *                             M4OSA_Void* pFileOut, M4OSA_Void* pTempFile);
10457 * @brief   Set the MCS input and output files. It is the same as M4MCS_open without
10458 *                                M4MCS_WITH_FAST_OPEN flag
10459It is used in VideoArtist
10460 * @note    It opens the input file, but the output file is not created yet.
10461 * @param   pContext            (IN) MCS context
10462 * @param   pFileIn             (IN) Input file to transcode (The type of this parameter
10463 *                                    (URL, pipe...) depends on the OSAL implementation).
10464 * @param   mediaType           (IN) Container type (.3gp,.amr, ...) of input file.
10465 * @param   pFileOut            (IN) Output file to create  (The type of this parameter
10466 *                                (URL, pipe...) depends on the OSAL implementation).
10467 * @param   pTempFile           (IN) Temporary file for the constant memory writer to store
10468 *                                 metadata ("moov.bin").
10469 * @return  M4NO_ERROR:         No error
10470 * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
10471 * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
10472 * @return  M4ERR_ALLOC:        There is no more available memory
10473 * @return  M4ERR_FILE_NOT_FOUND:   The input file has not been found
10474 * @return  M4MCS_ERR_INVALID_INPUT_FILE:   The input file is not a valid file, or is corrupted
10475 * @return  M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM:  The input file contains no
10476 *                                                         supported audio or video stream
10477 ******************************************************************************
10478 */
10479M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
10480                                 M4VIDEOEDITING_FileType InputFileType,
10481                                  M4OSA_Void* pFileOut, M4OSA_Void* pTempFile)
10482{
10483    M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext);
10484    M4OSA_ERR err;
10485
10486    M4READER_MediaFamily mediaFamily;
10487    M4_StreamHandler* pStreamHandler;
10488
10489    M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\
10490     pFileOut=0x%x", pContext, pFileIn, pFileOut);
10491
10492    /**
10493    * Check input parameters */
10494    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
10495     "M4MCS_open_normalMode: pContext is M4OSA_NULL");
10496    M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER,
10497     "M4MCS_open_normalMode: pFileIn is M4OSA_NULL");
10498
10499    if ((InputFileType == M4VIDEOEDITING_kFileType_JPG)
10500        ||(InputFileType == M4VIDEOEDITING_kFileType_PNG)
10501        ||(InputFileType == M4VIDEOEDITING_kFileType_GIF)
10502        ||(InputFileType == M4VIDEOEDITING_kFileType_BMP))
10503    {
10504        M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\
10505             supported with this function");
10506        return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
10507    }
10508
10509    /**
10510    * Check state automaton */
10511    if (M4MCS_kState_CREATED != pC->State)
10512    {
10513        M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE",
10514             pC->State);
10515        return M4ERR_STATE;
10516    }
10517
10518    /* Copy function input parameters into our context */
10519    pC->pInputFile     = pFileIn;
10520    pC->InputFileType  = InputFileType;
10521    pC->pOutputFile    = pFileOut;
10522    pC->pTemporaryFile = pTempFile;
10523
10524    /***********************************/
10525    /* Open input file with the reader */
10526    /***********************************/
10527
10528    err = M4MCS_setCurrentReader(pContext, pC->InputFileType);
10529    M4ERR_CHECK_RETURN(err);
10530
10531    /**
10532    * Reset reader related variables */
10533    pC->VideoState          = M4MCS_kStreamState_NOSTREAM;
10534    pC->AudioState          = M4MCS_kStreamState_NOSTREAM;
10535    pC->pReaderVideoStream  = M4OSA_NULL;
10536    pC->pReaderAudioStream  = M4OSA_NULL;
10537
10538    /*******************************************************/
10539    /* Initializes the reader shell and open the data file */
10540    /*******************************************************/
10541    err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext);
10542    if (M4NO_ERROR != err)
10543    {
10544        M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err);
10545        return err;
10546    }
10547
10548    /**
10549    * Link the reader interface to the reader context */
10550    pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext;
10551
10552    /**
10553    * Set the reader shell file access functions */
10554    err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
10555         M4READER_kOptionID_SetOsaFileReaderFctsPtr,
10556        (M4OSA_DataOption)pC->pOsaFileReadPtr);
10557    if (M4NO_ERROR != err)
10558    {
10559        M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err);
10560        return err;
10561    }
10562
10563    /**
10564    * Open the input file */
10565    err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile);
10566    if (M4NO_ERROR != err)
10567    {
10568        M4OSA_UInt32 uiDummy, uiCoreId;
10569        M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err);
10570
10571        if (err == ((M4OSA_UInt32)M4ERR_UNSUPPORTED_MEDIA_TYPE)) {
10572            M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_FILE_DRM_PROTECTED");
10573            return M4MCS_ERR_FILE_DRM_PROTECTED;
10574        } else {
10575            /**
10576            * If the error is from the core reader, we change it to a public VXS error */
10577            M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
10578            if (M4MP4_READER == uiCoreId)
10579            {
10580                M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE");
10581                return M4MCS_ERR_INVALID_INPUT_FILE;
10582            }
10583        }
10584        return err;
10585    }
10586
10587    /**
10588    * Get the streams from the input file */
10589    while (M4NO_ERROR == err)
10590    {
10591        err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily,
10592            &pStreamHandler);
10593
10594        /**
10595        * In case we found a BIFS stream or something else...*/
10596        if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
10597            || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)))
10598        {
10599            err = M4NO_ERROR;
10600            continue;
10601        }
10602
10603        if (M4NO_ERROR == err) /**< One stream found */
10604        {
10605            /**
10606            * Found the first video stream */
10607            if ((M4READER_kMediaFamilyVideo == mediaFamily) \
10608                && (M4OSA_NULL == pC->pReaderVideoStream))
10609            {
10610                if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) ||
10611                    (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType)
10612#ifdef M4VSS_SUPPORT_VIDEO_AVC
10613                    ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType))
10614#else
10615                    ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)
10616                    &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL)))
10617#endif
10618                {
10619                    M4OSA_TRACE3_0("M4MCS_open_normalMode():\
10620                     Found a H263 or MPEG-4 video stream in input 3gpp clip");
10621
10622                    /**
10623                    * Keep pointer to the video stream */
10624                    pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler;
10625                    pC->bUnsupportedVideoFound = M4OSA_FALSE;
10626                    pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
10627
10628                    /**
10629                    * Init our video stream state variable */
10630                    pC->VideoState = M4MCS_kStreamState_STARTED;
10631
10632                    /**
10633                    * Reset the stream reader */
10634                    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10635                         (M4_StreamHandler*)pC->pReaderVideoStream);
10636                    if (M4NO_ERROR != err)
10637                    {
10638                        M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10639                             m_pReader->m_pFctReset(video) returns 0x%x", err);
10640                        return err;
10641                    }
10642
10643                    /**
10644                    * Initializes an access Unit */
10645                    err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
10646                         &pC->ReaderVideoAU);
10647                    if (M4NO_ERROR != err)
10648                    {
10649                        M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10650                             m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err);
10651                        return err;
10652                    }
10653                }
10654                else /**< Not H263 or MPEG-4 (H264, etc.) */
10655                {
10656                    M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10657                         Found an unsupported video stream (0x%x) in input 3gpp clip",
10658                             pStreamHandler->m_streamType);
10659
10660                    pC->bUnsupportedVideoFound = M4OSA_TRUE;
10661                    pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
10662                }
10663            }
10664            /**
10665            * Found the first audio stream */
10666            else if ((M4READER_kMediaFamilyAudio == mediaFamily)
10667                && (M4OSA_NULL == pC->pReaderAudioStream))
10668            {
10669                if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) ||
10670                    (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) ||
10671                    (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) ||
10672                    (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) )
10673                {
10674                    M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \
10675                        or MP3 audio stream in input clip");
10676
10677                    /**
10678                    * Keep pointer to the audio stream */
10679                    pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler;
10680                    pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
10681                    pC->bUnsupportedAudioFound = M4OSA_FALSE;
10682
10683                    /**
10684                    * Init our audio stream state variable */
10685                    pC->AudioState = M4MCS_kStreamState_STARTED;
10686
10687                    /**
10688                    * Reset the stream reader */
10689                    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10690                         (M4_StreamHandler*)pC->pReaderAudioStream);
10691                    if (M4NO_ERROR != err)
10692                    {
10693                        M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10694                             m_pReader->m_pFctReset(audio) returns 0x%x", err);
10695                        return err;
10696                    }
10697
10698                    /**
10699                    * Initializes an access Unit */
10700                    err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
10701                         &pC->ReaderAudioAU);
10702                    if (M4NO_ERROR != err)
10703                    {
10704                        M4OSA_TRACE1_1("M4MCS_open_normalMode(): \
10705                            m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err);
10706                        return err;
10707                    }
10708
10709                    /**
10710                    * Output max AU size is equal to input max AU size (this value
10711                    * will be changed if there is audio transcoding) */
10712                    pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize;
10713
10714                }
10715                else
10716                {
10717                    /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */
10718                    M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\
10719                         (0x%x) in input 3gpp clip", pStreamHandler->m_streamType);
10720
10721                    pC->bUnsupportedAudioFound = M4OSA_TRUE;
10722                    pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
10723                }
10724            }
10725        }
10726    } /**< end of while (M4NO_ERROR == err) */
10727
10728    /**
10729    * Check we found at least one supported stream */
10730    if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream))
10731    {
10732        M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \
10733            M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM");
10734        return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
10735    }
10736
10737#ifndef M4VSS_ENABLE_EXTERNAL_DECODERS
10738    if(pC->VideoState == M4MCS_kStreamState_STARTED)
10739    {
10740        err = M4MCS_setCurrentVideoDecoder(pContext,
10741            pC->pReaderVideoStream->m_basicProperties.m_streamType);
10742        M4ERR_CHECK_RETURN(err);
10743    }
10744#endif
10745
10746    if(pC->AudioState == M4MCS_kStreamState_STARTED)
10747    {
10748        //EVRC
10749        if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType)
10750         /* decoder not supported yet, but allow to do null encoding */
10751        {
10752            err = M4MCS_setCurrentAudioDecoder(pContext,
10753                 pC->pReaderAudioStream->m_basicProperties.m_streamType);
10754            M4ERR_CHECK_RETURN(err);
10755        }
10756    }
10757
10758    /**
10759    * Get the audio and video stream properties */
10760    err = M4MCS_intGetInputClipProperties(pC);
10761    if (M4NO_ERROR != err)
10762    {
10763        M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10764             M4MCS_intGetInputClipProperties returns 0x%x", err);
10765        return err;
10766    }
10767
10768    /**
10769    * Set the begin cut decoding increment according to the input frame rate */
10770    if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */
10771    {
10772        pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \
10773            / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */
10774    }
10775    else
10776    {
10777        pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/
10778    }
10779
10780    /**
10781    * Update state automaton */
10782    pC->State = M4MCS_kState_OPENED;
10783
10784    /**
10785    * Return with no error */
10786    M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR");
10787    return M4NO_ERROR;
10788}
10789
10790M4OSA_ERR M4MCS_intCheckAndGetCodecAacProperties(
10791                                 M4MCS_InternalContext *pC) {
10792
10793    M4OSA_ERR err = M4NO_ERROR;
10794    M4AD_Buffer outputBuffer;
10795    uint32_t optionValue =0;
10796
10797    M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecAacProperties :start");
10798
10799    // Decode first audio frame from clip to get properties from codec
10800
10801    err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
10802                    &pC->pAudioDecCtxt,
10803                    pC->pReaderAudioStream, &(pC->AacProperties));
10804
10805    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10806           M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
10807
10808    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10809           M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
10810
10811    if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
10812
10813        err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
10814        if( M4NO_ERROR != err ) {
10815
10816            M4OSA_TRACE1_1(
10817                "M4MCS_intCheckAndGetCodecAACProperties: m_pFctStartAudioDec \
10818                 returns 0x%x", err);
10819            return err;
10820        }
10821    }
10822
10823    /**
10824    * Allocate output buffer for the audio decoder */
10825    outputBuffer.m_bufferSize =
10826        pC->pReaderAudioStream->m_byteFrameLength
10827        * pC->pReaderAudioStream->m_byteSampleSize
10828        * pC->pReaderAudioStream->m_nbChannels;
10829
10830    if( outputBuffer.m_bufferSize > 0 ) {
10831
10832        outputBuffer.m_dataAddress =
10833            (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
10834            *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize");
10835
10836        if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
10837
10838            M4OSA_TRACE1_0(
10839                "M4MCS_intCheckAndGetCodecAACProperties():\
10840                 unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC");
10841            return M4ERR_ALLOC;
10842        }
10843    }
10844
10845    err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
10846        M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
10847
10848    if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
10849
10850        // Get the properties from codec node
10851        pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10852           M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
10853
10854        pC->AacProperties.aNumChan = optionValue;
10855        // Reset Reader structure value also
10856        pC->pReaderAudioStream->m_nbChannels = optionValue;
10857
10858        pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10859         M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
10860
10861        pC->AacProperties.aSampFreq = optionValue;
10862        // Reset Reader structure value also
10863        pC->pReaderAudioStream->m_samplingFrequency = optionValue;
10864
10865    } else if( err != M4NO_ERROR) {
10866        M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecAACProperties:\
10867            m_pFctStepAudioDec returns err = 0x%x", err);
10868    }
10869
10870    free(outputBuffer.m_dataAddress);
10871
10872    // Reset the stream reader
10873    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10874                 (M4_StreamHandler *)pC->pReaderAudioStream);
10875
10876    if (M4NO_ERROR != err) {
10877        M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecAACProperties\
10878            Error in reseting reader: 0x%x", err);
10879    }
10880
10881    return err;
10882
10883}
10884