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