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