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