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 /** Set the target video level, because input 3gp file may 3750 * have wrong video level value (some encoders do not respect 3751 * level restrictions like video resolution when content is created). 3752 **/ 3753 pC->encodingVideoLevel = pParams->outputVideoLevel; 3754 3755 // Clip's original width and height may not be 3756 // multiple of 16. 3757 // Ensure encoding width and height are multiple of 16 3758 3759 uint32_t remainder = pC->EncodingWidth % 16; 3760 if (remainder != 0) { 3761 if (remainder >= 8) { 3762 // Roll forward 3763 pC->EncodingWidth = 3764 pC->EncodingWidth + (16-remainder); 3765 } else { 3766 // Roll backward 3767 pC->EncodingWidth = 3768 pC->EncodingWidth - remainder; 3769 } 3770 uiFrameWidth = pC->EncodingWidth; 3771 } 3772 3773 remainder = pC->EncodingHeight % 16; 3774 if (remainder != 0) { 3775 if (remainder >= 8) { 3776 // Roll forward 3777 pC->EncodingHeight = 3778 pC->EncodingHeight + (16-remainder); 3779 } else { 3780 // Roll backward 3781 pC->EncodingHeight = 3782 pC->EncodingHeight - remainder; 3783 } 3784 uiFrameHeight = pC->EncodingHeight; 3785 } 3786 3787 } 3788 else 3789 { 3790 /** 3791 * Set output video profile and level */ 3792 pC->encodingVideoProfile = pParams->outputVideoProfile; 3793 pC->encodingVideoLevel = pParams->outputVideoLevel; 3794 3795 switch( pParams->OutputVideoFrameSize ) 3796 { 3797 case M4VIDEOEDITING_kSQCIF: 3798 uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width; 3799 uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height; 3800 break; 3801 3802 case M4VIDEOEDITING_kQQVGA: 3803 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width; 3804 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height; 3805 break; 3806 3807 case M4VIDEOEDITING_kQCIF: 3808 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width; 3809 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height; 3810 break; 3811 3812 case M4VIDEOEDITING_kQVGA: 3813 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width; 3814 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height; 3815 break; 3816 3817 case M4VIDEOEDITING_kCIF: 3818 uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width; 3819 uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height; 3820 break; 3821 3822 case M4VIDEOEDITING_kVGA: 3823 uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width; 3824 uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height; 3825 break; 3826 /* +PR LV5807 */ 3827 case M4VIDEOEDITING_kWVGA: 3828 uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width; 3829 uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height; 3830 break; 3831 3832 case M4VIDEOEDITING_kNTSC: 3833 uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width; 3834 uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height; 3835 break; 3836 /* -PR LV5807*/ 3837 /* +CR Google */ 3838 case M4VIDEOEDITING_k640_360: 3839 uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width; 3840 uiFrameHeight = 3841 pC->EncodingHeight = M4ENCODER_640_360_Height; 3842 break; 3843 3844 case M4VIDEOEDITING_k854_480: 3845 uiFrameWidth = 3846 pC->EncodingWidth = M4ENCODER_854_480_Width; 3847 uiFrameHeight = 3848 pC->EncodingHeight = M4ENCODER_854_480_Height; 3849 break; 3850 3851 case M4VIDEOEDITING_k1280_720: 3852 uiFrameWidth = 3853 pC->EncodingWidth = M4ENCODER_1280_720_Width; 3854 uiFrameHeight = 3855 pC->EncodingHeight = M4ENCODER_1280_720_Height; 3856 break; 3857 3858 case M4VIDEOEDITING_k1080_720: 3859 uiFrameWidth = 3860 pC->EncodingWidth = M4ENCODER_1080_720_Width; 3861 uiFrameHeight = 3862 pC->EncodingHeight = M4ENCODER_1080_720_Height; 3863 break; 3864 3865 case M4VIDEOEDITING_k960_720: 3866 uiFrameWidth = 3867 pC->EncodingWidth = M4ENCODER_960_720_Width; 3868 uiFrameHeight = 3869 pC->EncodingHeight = M4ENCODER_960_720_Height; 3870 break; 3871 3872 case M4VIDEOEDITING_k1920_1080: 3873 uiFrameWidth = 3874 pC->EncodingWidth = M4ENCODER_1920_1080_Width; 3875 uiFrameHeight = 3876 pC->EncodingHeight = M4ENCODER_1920_1080_Height; 3877 break; 3878 /* -CR Google */ 3879 default: 3880 M4OSA_TRACE1_1( 3881 "M4MCS_setOutputParams: Undefined output video frame size \ 3882 (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE", 3883 pParams->OutputVideoFrameSize); 3884 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; 3885 } 3886 } 3887 3888 /** 3889 * Compute video max au size and max chunck size. 3890 * We do it here because it depends on the frame size only, and 3891 * because we need it for the file size/video bitrate estimations */ 3892 pC->uiVideoMaxAuSize = 3893 (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \ 3894 *M4MCS_VIDEO_MIN_COMPRESSION_RATIO); 3895 pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize \ 3896 * 3897 M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */ 3898 3899 if( 0 == pC->uiVideoMaxAuSize ) 3900 { 3901 /* Size may be zero in case of null encoding with unrecognized stream */ 3902 M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\ 3903 M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE"); 3904 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; 3905 } 3906 3907 3908 /** 3909 * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */ 3910 3911 if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) 3912 { 3913 switch( pParams->OutputVideoFrameSize ) 3914 { 3915 case M4VIDEOEDITING_kSQCIF: 3916 case M4VIDEOEDITING_kQCIF: 3917 case M4VIDEOEDITING_kCIF: 3918 /* OK */ 3919 break; 3920 3921 default: 3922 M4OSA_TRACE1_0( 3923 "M4MCS_setOutputParams():\ 3924 returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263"); 3925 return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263; 3926 } 3927 } 3928 3929 /** 3930 * Check Video Frame rate correctness */ 3931 if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat ) 3932 { 3933 switch( pParams->OutputVideoFrameRate ) 3934 { 3935 case M4VIDEOEDITING_k5_FPS: 3936 pC->EncodingVideoFramerate = M4ENCODER_k5_FPS; 3937 break; 3938 3939 case M4VIDEOEDITING_k7_5_FPS: 3940 pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS; 3941 break; 3942 3943 case M4VIDEOEDITING_k10_FPS: 3944 pC->EncodingVideoFramerate = M4ENCODER_k10_FPS; 3945 break; 3946 3947 case M4VIDEOEDITING_k12_5_FPS: 3948 pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS; 3949 break; 3950 3951 case M4VIDEOEDITING_k15_FPS: 3952 pC->EncodingVideoFramerate = M4ENCODER_k15_FPS; 3953 break; 3954 3955 case M4VIDEOEDITING_k20_FPS: 3956 pC->EncodingVideoFramerate = M4ENCODER_k20_FPS; 3957 break; 3958 3959 case M4VIDEOEDITING_k25_FPS: 3960 pC->EncodingVideoFramerate = M4ENCODER_k25_FPS; 3961 break; 3962 3963 case M4VIDEOEDITING_k30_FPS: 3964 pC->EncodingVideoFramerate = M4ENCODER_k30_FPS; 3965 break; 3966 3967 default: 3968 M4OSA_TRACE1_1( 3969 "M4MCS_setOutputParams: Undefined output video frame rate\ 3970 (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", 3971 pParams->OutputVideoFrameRate); 3972 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; 3973 } 3974 } 3975 3976 /** 3977 * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */ 3978 if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) 3979 { 3980 switch( pC->EncodingVideoFramerate ) 3981 { 3982 case M4ENCODER_k5_FPS: 3983 case M4ENCODER_k7_5_FPS: 3984 case M4ENCODER_k10_FPS: 3985 case M4ENCODER_k15_FPS: 3986 case M4ENCODER_k30_FPS: 3987 /* OK */ 3988 break; 3989 3990 default: 3991 M4OSA_TRACE1_0( 3992 "M4MCS_setOutputParams():\ 3993 returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263"); 3994 return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263; 3995 } 3996 } 3997 } 3998 3999 /* Set audio parameters */ 4000 if( pC->noaudio == M4OSA_FALSE ) 4001 { 4002 /** 4003 * Check Audio Format correctness */ 4004 switch( pParams->OutputAudioFormat ) 4005 { 4006 case M4VIDEOEDITING_kAMR_NB: 4007 4008 err = M4MCS_setCurrentAudioEncoder(pContext, 4009 pParams->OutputAudioFormat); 4010 M4ERR_CHECK_RETURN(err); 4011 4012 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 4013 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4014 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 4015 pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID; 4016 break; 4017 4018 case M4VIDEOEDITING_kAAC: 4019 4020 err = M4MCS_setCurrentAudioEncoder(pContext, 4021 pParams->OutputAudioFormat); 4022 M4ERR_CHECK_RETURN(err); 4023 4024 pC->AudioEncParams.Format = M4ENCODER_kAAC; 4025 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4026 4027 switch( pParams->OutputAudioSamplingFrequency ) 4028 { 4029 case M4VIDEOEDITING_k8000_ASF: 4030 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4031 break; 4032 4033 case M4VIDEOEDITING_k16000_ASF: 4034 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4035 break; 4036 4037 case M4VIDEOEDITING_k22050_ASF: 4038 pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; 4039 break; 4040 4041 case M4VIDEOEDITING_k24000_ASF: 4042 pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; 4043 break; 4044 4045 case M4VIDEOEDITING_k32000_ASF: 4046 pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; 4047 break; 4048 4049 case M4VIDEOEDITING_k44100_ASF: 4050 pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; 4051 break; 4052 4053 case M4VIDEOEDITING_k48000_ASF: 4054 pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; 4055 break; 4056 4057 case M4VIDEOEDITING_k11025_ASF: 4058 case M4VIDEOEDITING_k12000_ASF: 4059 case M4VIDEOEDITING_kDefault_ASF: 4060 break; 4061 } 4062 pC->AudioEncParams.ChannelNum = 4063 (pParams->bAudioMono == M4OSA_TRUE) ? \ 4064 M4ENCODER_kMono : M4ENCODER_kStereo; 4065 pC->AudioEncParams.SpecifParam.AacParam.Regulation = 4066 M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir 4067 /* unused */ 4068 pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE; 4069 pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE; 4070 pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE; 4071 pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE; 4072 /* TODO change into highspeed asap */ 4073 pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = 4074 M4OSA_FALSE; 4075 break; 4076 4077 /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ 4078 case M4VIDEOEDITING_kMP3: 4079 err = M4MCS_setCurrentAudioEncoder(pContext, 4080 pParams->OutputAudioFormat); 4081 M4ERR_CHECK_RETURN(err); 4082 4083 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4084 pC->AudioEncParams.ChannelNum = 4085 (pParams->bAudioMono == M4OSA_TRUE) ? \ 4086 M4ENCODER_kMono : M4ENCODER_kStereo; 4087 4088 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4089 4090 switch( pParams->OutputAudioSamplingFrequency ) 4091 { 4092 case M4VIDEOEDITING_k8000_ASF: 4093 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4094 break; 4095 4096 case M4VIDEOEDITING_k11025_ASF: 4097 pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz; 4098 break; 4099 4100 case M4VIDEOEDITING_k12000_ASF: 4101 pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz; 4102 break; 4103 4104 case M4VIDEOEDITING_k16000_ASF: 4105 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4106 break; 4107 4108 case M4VIDEOEDITING_k22050_ASF: 4109 pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; 4110 break; 4111 4112 case M4VIDEOEDITING_k24000_ASF: 4113 pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; 4114 break; 4115 4116 case M4VIDEOEDITING_k32000_ASF: 4117 pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; 4118 break; 4119 4120 case M4VIDEOEDITING_k44100_ASF: 4121 pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; 4122 break; 4123 4124 case M4VIDEOEDITING_k48000_ASF: 4125 pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; 4126 break; 4127 4128 case M4VIDEOEDITING_kDefault_ASF: 4129 break; 4130 } 4131 4132 break; 4133 4134 case M4VIDEOEDITING_kNullAudio: 4135 if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 ) 4136 { 4137 /* no encoder needed */ 4138 pC->AudioEncParams.Format = M4ENCODER_kAudioNULL; 4139 pC->AudioEncParams.Frequency = 4140 pC->pReaderAudioStream->m_samplingFrequency; 4141 pC->AudioEncParams.ChannelNum = 4142 (pC->pReaderAudioStream->m_nbChannels == 1) ? \ 4143 M4ENCODER_kMono : M4ENCODER_kStereo; 4144 } 4145 else 4146 { 4147 pC->AudioEncParams.Frequency = 4148 pC->pReaderAudioStream->m_samplingFrequency; 4149 pC->AudioEncParams.ChannelNum = 4150 (pC->pReaderAudioStream->m_nbChannels == 1) ? \ 4151 M4ENCODER_kMono : M4ENCODER_kStereo; 4152 4153 switch( pC->InputFileProperties.AudioStreamType ) 4154 { 4155 case M4VIDEOEDITING_kAMR_NB: 4156 M4OSA_TRACE3_0( 4157 "M4MCS_setOutputParams calling \ 4158 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR"); 4159 err = M4MCS_setCurrentAudioEncoder(pContext, 4160 pC->InputFileProperties.AudioStreamType); 4161 M4ERR_CHECK_RETURN(err); 4162 4163 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 4164 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4165 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 4166 4167 if( pC->pReaderAudioStream->m_samplingFrequency 4168 != 8000 ) 4169 { 4170 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 4171 } 4172 pC->AudioEncParams.SpecifParam.AmrSID = 4173 M4ENCODER_kAmrNoSID; 4174 break; 4175 4176 case M4VIDEOEDITING_kAAC: 4177 M4OSA_TRACE3_0( 4178 "M4MCS_setOutputParams calling \ 4179 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC"); 4180 err = M4MCS_setCurrentAudioEncoder(pContext, 4181 pC->InputFileProperties.AudioStreamType); 4182 M4ERR_CHECK_RETURN(err); 4183 4184 pC->AudioEncParams.Format = M4ENCODER_kAAC; 4185 pC->AudioEncParams.SpecifParam.AacParam.Regulation = 4186 M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir 4187 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4188 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4189 4190 switch( pC->pReaderAudioStream-> 4191 m_samplingFrequency ) 4192 { 4193 case 16000: 4194 pC->AudioEncParams.Frequency = 4195 M4ENCODER_k16000Hz; 4196 break; 4197 4198 case 22050: 4199 pC->AudioEncParams.Frequency = 4200 M4ENCODER_k22050Hz; 4201 break; 4202 4203 case 24000: 4204 pC->AudioEncParams.Frequency = 4205 M4ENCODER_k24000Hz; 4206 break; 4207 4208 case 32000: 4209 pC->AudioEncParams.Frequency = 4210 M4ENCODER_k32000Hz; 4211 break; 4212 4213 case 44100: 4214 pC->AudioEncParams.Frequency = 4215 M4ENCODER_k44100Hz; 4216 break; 4217 4218 case 48000: 4219 pC->AudioEncParams.Frequency = 4220 M4ENCODER_k48000Hz; 4221 break; 4222 4223 default: 4224 pC->AudioEncParams.Format = M4ENCODER_kAAC; 4225 break; 4226 } 4227 /* unused */ 4228 pC->AudioEncParams.SpecifParam.AacParam.bIS = 4229 M4OSA_FALSE; 4230 pC->AudioEncParams.SpecifParam.AacParam.bMS = 4231 M4OSA_FALSE; 4232 pC->AudioEncParams.SpecifParam.AacParam.bPNS = 4233 M4OSA_FALSE; 4234 pC->AudioEncParams.SpecifParam.AacParam.bTNS = 4235 M4OSA_FALSE; 4236 /* TODO change into highspeed asap */ 4237 pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = 4238 M4OSA_FALSE; 4239 break; 4240 4241 case M4VIDEOEDITING_kMP3: 4242 M4OSA_TRACE3_0( 4243 "M4MCS_setOutputParams calling\ 4244 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3"); 4245 err = M4MCS_setCurrentAudioEncoder(pContext, 4246 pC->InputFileProperties.AudioStreamType); 4247 M4ERR_CHECK_RETURN(err); 4248 4249 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4250 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4251 4252 switch( pC->pReaderAudioStream-> 4253 m_samplingFrequency ) 4254 { 4255 case 8000: 4256 pC->AudioEncParams.Frequency = 4257 M4ENCODER_k8000Hz; 4258 break; 4259 4260 case 16000: 4261 pC->AudioEncParams.Frequency = 4262 M4ENCODER_k16000Hz; 4263 break; 4264 4265 case 22050: 4266 pC->AudioEncParams.Frequency = 4267 M4ENCODER_k22050Hz; 4268 break; 4269 4270 case 24000: 4271 pC->AudioEncParams.Frequency = 4272 M4ENCODER_k24000Hz; 4273 break; 4274 4275 case 32000: 4276 pC->AudioEncParams.Frequency = 4277 M4ENCODER_k32000Hz; 4278 break; 4279 4280 case 44100: 4281 pC->AudioEncParams.Frequency = 4282 M4ENCODER_k44100Hz; 4283 break; 4284 4285 case 48000: 4286 pC->AudioEncParams.Frequency = 4287 M4ENCODER_k48000Hz; 4288 break; 4289 4290 default: 4291 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4292 break; 4293 } 4294 break; 4295 4296 case M4VIDEOEDITING_kEVRC: 4297 case M4VIDEOEDITING_kUnsupportedAudio: 4298 default: 4299 M4OSA_TRACE1_1( 4300 "M4MCS_setOutputParams: Output audio format (%d) is\ 4301 incompatible with audio effects, returning \ 4302 M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 4303 pC->InputFileProperties.AudioStreamType); 4304 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 4305 } 4306 } 4307 break; 4308 /* EVRC 4309 // case M4VIDEOEDITING_kEVRC: 4310 // 4311 // err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\ 4312 // OutputAudioFormat); 4313 // M4ERR_CHECK_RETURN(err); 4314 // 4315 // pC->AudioEncParams.Format = M4ENCODER_kEVRC; 4316 // pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4317 // pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 4318 // break; */ 4319 4320 default: 4321 M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\ 4322 returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 4323 pParams->OutputAudioFormat); 4324 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 4325 } 4326 } 4327 4328 if( pParams->pOutputPCMfile != M4OSA_NULL ) 4329 { 4330 pC->pOutputPCMfile = pParams->pOutputPCMfile; 4331 4332 /* Open output PCM file */ 4333 pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile), 4334 pParams->pOutputPCMfile, M4OSA_kFileWrite); 4335 } 4336 else 4337 { 4338 pC->pOutputPCMfile = M4OSA_NULL; 4339 } 4340 4341 /*Store media rendering parameter into the internal context*/ 4342 pC->MediaRendering = pParams->MediaRendering; 4343 4344 /* Add audio effects*/ 4345 /*Copy MCS effects structure into internal context*/ 4346 if( pParams->nbEffects > 0 ) 4347 { 4348 M4OSA_UInt32 j = 0; 4349 pC->nbEffects = pParams->nbEffects; 4350 pC->pEffects = (M4MCS_EffectSettings *)M4OSA_32bitAlignedMalloc(pC->nbEffects \ 4351 *sizeof(M4MCS_EffectSettings), M4MCS, 4352 (M4OSA_Char *)"Allocation of effects list"); 4353 4354 if( pC->pEffects == M4OSA_NULL ) 4355 { 4356 M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error"); 4357 return M4ERR_ALLOC; 4358 } 4359 4360 for ( j = 0; j < pC->nbEffects; j++ ) 4361 { 4362 /* Copy effect to "local" structure */ 4363 memcpy((void *) &(pC->pEffects[j]), 4364 (void *) &(pParams->pEffects[j]), 4365 sizeof(M4MCS_EffectSettings)); 4366 4367 switch( pC->pEffects[j].AudioEffectType ) 4368 { 4369 case M4MCS_kAudioEffectType_None: 4370 M4OSA_TRACE3_1( 4371 "M4MCS_setOutputParams(): effect type %i is None", j); 4372 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4373 pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL; 4374 break; 4375 4376 case M4MCS_kAudioEffectType_FadeIn: 4377 M4OSA_TRACE3_1( 4378 "M4MCS_setOutputParams(): effect type %i is FadeIn", j); 4379 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4380 pC->pEffects[j].ExtAudioEffectFct = 4381 M4MCS_editAudioEffectFct_FadeIn; 4382 break; 4383 4384 case M4MCS_kAudioEffectType_FadeOut: 4385 M4OSA_TRACE3_1( 4386 "M4MCS_setOutputParams(): effect type %i is FadeOut", 4387 j); 4388 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4389 pC->pEffects[j].ExtAudioEffectFct = 4390 M4MCS_editAudioEffectFct_FadeOut; 4391 break; 4392 4393 case M4MCS_kAudioEffectType_External: 4394 M4OSA_TRACE3_1( 4395 "M4MCS_setOutputParams(): effect type %i is External", 4396 j); 4397 4398 if( pParams->pEffects != M4OSA_NULL ) 4399 { 4400 if( pParams->pEffects[j].ExtAudioEffectFct 4401 == M4OSA_NULL ) 4402 { 4403 M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\ 4404 associated to external effect number %i", j); 4405 return M4ERR_PARAMETER; 4406 } 4407 pC->pEffects[j].pExtAudioEffectFctCtxt = 4408 pParams->pEffects[j].pExtAudioEffectFctCtxt; 4409 4410 pC->pEffects[j].ExtAudioEffectFct = 4411 pParams->pEffects[j].ExtAudioEffectFct; 4412 } 4413 4414 break; 4415 4416 default: 4417 M4OSA_TRACE1_0( 4418 "M4MCS_setOutputParams(): effect type not recognized"); 4419 return M4ERR_PARAMETER; 4420 } 4421 } 4422 } 4423 else 4424 { 4425 pC->nbEffects = 0; 4426 pC->pEffects = M4OSA_NULL; 4427 } 4428 4429 /** 4430 * Update state automaton */ 4431 pC->State = M4MCS_kState_SET; 4432 4433 /** 4434 * Return with no error */ 4435 M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR"); 4436 return M4NO_ERROR; 4437 } 4438 4439 /** 4440 ****************************************************************************** 4441 * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) 4442 * @brief Set the values of the encoding parameters 4443 * @note Must be called before M4MCS_checkParamsAndStart(). 4444 * @param pContext (IN) MCS context 4445 * @param pRates (IN) Transcoding parameters 4446 * @return M4NO_ERROR: No error 4447 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 4448 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 4449 * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps) 4450 * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2 4451 * for amr, 8 for mp3) 4452 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals 4453 * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip 4454 * duration 4455 * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time 4456 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given 4457 * bitrates 4458 * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps) 4459 * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: Video bitrate too low 4460 ****************************************************************************** 4461 */ 4462 M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext, 4463 M4MCS_EncodingParams *pRates ) 4464 { 4465 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 4466 M4OSA_UInt32 j = 0; 4467 4468 M4OSA_TRACE2_2( 4469 "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x", 4470 pContext, pRates); 4471 4472 /** 4473 * Check input parameters */ 4474 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 4475 "M4MCS_setEncodingParams: pContext is M4OSA_NULL"); 4476 M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER, 4477 "M4MCS_setEncodingParams: pRates is M4OSA_NULL"); 4478 4479 #ifdef M4MCS_SUPPORT_STILL_PICTURE 4480 4481 if( pC->m_bIsStillPicture ) 4482 { 4483 /** 4484 * Call the corresponding still picture MCS function*/ 4485 return M4MCS_stillPicSetEncodingParams(pC, pRates); 4486 } 4487 4488 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 4489 4490 /** 4491 * Check state automaton */ 4492 4493 if( M4MCS_kState_SET != pC->State ) 4494 { 4495 M4OSA_TRACE1_1( 4496 "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE", 4497 pC->State); 4498 return M4ERR_STATE; 4499 } 4500 4501 /* Set given values */ 4502 pC->uiVideoBitrate = pRates->OutputVideoBitrate; 4503 pC->uiAudioBitrate = pRates->OutputAudioBitrate; 4504 pC->uiBeginCutTime = pRates->BeginCutTime; 4505 pC->uiEndCutTime = pRates->EndCutTime; 4506 pC->uiMaxFileSize = pRates->OutputFileSize; 4507 4508 /** 4509 * Check begin cut time validity */ 4510 if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration ) 4511 { 4512 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\ 4513 returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION", 4514 pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration); 4515 return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION; 4516 } 4517 4518 /** 4519 * If end cut time is too large, we set it to the clip duration */ 4520 if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration ) 4521 { 4522 pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; 4523 } 4524 4525 /** 4526 * Check end cut time validity */ 4527 if( pC->uiEndCutTime > 0 ) 4528 { 4529 if( pC->uiEndCutTime < pC->uiBeginCutTime ) 4530 { 4531 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \ 4532 returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT", 4533 pC->uiBeginCutTime, pC->uiEndCutTime); 4534 return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT; 4535 } 4536 4537 if( pC->uiEndCutTime == pC->uiBeginCutTime ) 4538 { 4539 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\ 4540 returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT", 4541 pC->uiBeginCutTime, pC->uiEndCutTime); 4542 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 4543 } 4544 } 4545 4546 /** 4547 * FlB 2009.03.04: check audio effects start time and duration validity*/ 4548 for ( j = 0; j < pC->nbEffects; j++ ) 4549 { 4550 M4OSA_UInt32 outputEndCut = pC->uiEndCutTime; 4551 4552 if( pC->uiEndCutTime == 0 ) 4553 { 4554 outputEndCut = pC->InputFileProperties.uiClipDuration; 4555 } 4556 4557 if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) ) 4558 { 4559 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\ 4560 duration (%d,%d), returning M4ERR_PARAMETER", 4561 pC->pEffects[j].uiStartTime, 4562 (pC->uiEndCutTime - pC->uiBeginCutTime)); 4563 return M4ERR_PARAMETER; 4564 } 4565 4566 if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \ 4567 (outputEndCut - pC->uiBeginCutTime) ) 4568 { 4569 /* Re-adjust the effect duration until the end of the output clip*/ 4570 pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \ 4571 pC->pEffects[j].uiStartTime; 4572 } 4573 } 4574 4575 /* Check audio bitrate consistency */ 4576 if( ( pC->noaudio == M4OSA_FALSE) 4577 && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) ) 4578 { 4579 if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 4580 { 4581 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 4582 { 4583 if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS ) 4584 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4585 4586 if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS ) 4587 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4588 } 4589 //EVRC 4590 // else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) 4591 // { 4592 // if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS) 4593 // return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4594 // if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS) 4595 // return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4596 // } 4597 /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ 4598 else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 4599 { 4600 if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz ) 4601 { 4602 /*Mpeg layer 1*/ 4603 if( pC->uiAudioBitrate > 320000 ) 4604 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4605 4606 if( pC->uiAudioBitrate < 32000 ) 4607 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4608 } 4609 else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz ) 4610 { 4611 /*Mpeg layer 2*/ 4612 if( pC->uiAudioBitrate > 160000 ) 4613 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4614 4615 if( ( pC->uiAudioBitrate < 8000 4616 && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4617 || (pC->uiAudioBitrate < 16000 4618 && pC->AudioEncParams.ChannelNum 4619 == M4ENCODER_kStereo) ) 4620 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4621 } 4622 else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz 4623 || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz 4624 || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz ) 4625 { 4626 /*Mpeg layer 2.5*/ 4627 if( pC->uiAudioBitrate > 64000 ) 4628 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4629 4630 if( ( pC->uiAudioBitrate < 8000 4631 && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4632 || (pC->uiAudioBitrate < 16000 4633 && pC->AudioEncParams.ChannelNum 4634 == M4ENCODER_kStereo) ) 4635 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4636 } 4637 else 4638 { 4639 M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\ 4640 (%d)", pC->AudioEncParams.Frequency); 4641 return M4ERR_PARAMETER; 4642 } 4643 } 4644 else 4645 { 4646 if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS ) 4647 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4648 4649 if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono ) 4650 { 4651 if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS ) 4652 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4653 } 4654 else 4655 { 4656 if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS ) 4657 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4658 } 4659 } 4660 } 4661 } 4662 else 4663 { 4664 /* NULL audio : copy input file bitrate */ 4665 pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate; 4666 } 4667 4668 /* Check video bitrate consistency */ 4669 if( ( pC->novideo == M4OSA_FALSE) 4670 && (pC->EncodingVideoFormat != M4ENCODER_kNULL) ) 4671 { 4672 if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 4673 { 4674 if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4675 return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH; 4676 4677 if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS ) 4678 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; 4679 } 4680 } 4681 else 4682 { 4683 /* NULL video : copy input file bitrate */ 4684 pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate; 4685 } 4686 4687 if( pRates->OutputVideoTimescale <= 30000 4688 && pRates->OutputVideoTimescale > 0 ) 4689 { 4690 pC->outputVideoTimescale = pRates->OutputVideoTimescale; 4691 } 4692 4693 /* Check file size */ 4694 return M4MCS_intCheckMaxFileSize(pC); 4695 } 4696 4697 /** 4698 ****************************************************************************** 4699 * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) 4700 * @brief Get the extended values of the encoding parameters 4701 * @note Could be called after M4MCS_setEncodingParams. 4702 * @param pContext (IN) MCS context 4703 * @param pRates (OUT) Transcoding parameters 4704 * @return M4NO_ERROR: No error 4705 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 4706 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 4707 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration 4708 * clip = encoding is impossible 4709 ****************************************************************************** 4710 */ 4711 M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext, 4712 M4MCS_EncodingParams *pRates ) 4713 { 4714 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 4715 4716 M4OSA_Int32 minaudiobitrate; 4717 M4OSA_Int32 minvideobitrate; 4718 M4OSA_Int32 maxcombinedbitrate; 4719 4720 M4OSA_Int32 calcbitrate; 4721 4722 M4OSA_UInt32 maxduration; 4723 M4OSA_UInt32 calcduration; 4724 4725 M4OSA_Bool fixed_audio = M4OSA_FALSE; 4726 M4OSA_Bool fixed_video = M4OSA_FALSE; 4727 4728 #ifdef M4MCS_SUPPORT_STILL_PICTURE 4729 4730 if( pC->m_bIsStillPicture ) 4731 { 4732 /** 4733 * Call the corresponding still picture MCS function*/ 4734 return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates); 4735 } 4736 4737 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 4738 4739 pRates->OutputVideoBitrate = 4740 M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0); 4741 pRates->OutputAudioBitrate = 4742 M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0); 4743 pRates->BeginCutTime = pC->uiBeginCutTime; 4744 pRates->EndCutTime = pC->uiEndCutTime; 4745 pRates->OutputFileSize = pC->uiMaxFileSize; 4746 4747 /** 4748 * Check state automaton */ 4749 if( M4MCS_kState_SET != pC->State ) 4750 { 4751 M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\ 4752 returning M4ERR_STATE", pC->State); 4753 return M4ERR_STATE; 4754 } 4755 4756 /* Compute min audio bitrate */ 4757 if( pC->noaudio ) 4758 { 4759 fixed_audio = M4OSA_TRUE; 4760 pRates->OutputAudioBitrate = 0; 4761 minaudiobitrate = 0; 4762 } 4763 else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 4764 { 4765 fixed_audio = M4OSA_TRUE; 4766 pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate; 4767 minaudiobitrate = pC->InputFileProperties.uiAudioBitrate; 4768 } 4769 else 4770 { 4771 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 4772 { 4773 fixed_audio = M4OSA_TRUE; 4774 pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS; 4775 minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS; 4776 } 4777 //EVRC 4778 // if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) 4779 // { 4780 // fixed_audio = M4OSA_TRUE; 4781 // pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS; 4782 // minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS; 4783 // } 4784 /*FlB 26.02.2009: add mp3 as mcs output format*/ 4785 else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 4786 { 4787 minaudiobitrate = 4788 M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1, 4789 for both mono and stereo channels*/ 4790 } 4791 else 4792 { 4793 minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4794 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; 4795 } 4796 } 4797 4798 /* Check audio bitrate is in the correct range */ 4799 if( fixed_audio == M4OSA_FALSE ) 4800 { 4801 if( ( pC->uiAudioBitrate > 0) 4802 && (pRates->OutputAudioBitrate < minaudiobitrate) ) 4803 { 4804 pRates->OutputAudioBitrate = minaudiobitrate; 4805 } 4806 4807 if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) 4808 { 4809 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4810 } 4811 } 4812 4813 /* Compute min video bitrate */ 4814 if( pC->novideo ) 4815 { 4816 fixed_video = M4OSA_TRUE; 4817 pRates->OutputVideoBitrate = 0; 4818 minvideobitrate = 0; 4819 } 4820 else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 4821 { 4822 fixed_video = M4OSA_TRUE; 4823 pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate; 4824 minvideobitrate = pC->InputFileProperties.uiVideoBitrate; 4825 } 4826 else 4827 { 4828 minvideobitrate = M4VIDEOEDITING_k16_KBPS; 4829 } 4830 4831 /* Check video bitrate is in the correct range */ 4832 if( fixed_video == M4OSA_FALSE ) 4833 { 4834 if( ( pC->uiVideoBitrate > 0) 4835 && (pRates->OutputVideoBitrate < minvideobitrate) ) 4836 { 4837 pRates->OutputVideoBitrate = minvideobitrate; 4838 } 4839 /*+ New Encoder bitrates */ 4840 if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4841 { 4842 pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; 4843 } 4844 /*- New Encoder bitrates */ 4845 } 4846 4847 /* Check cut times are in correct range */ 4848 if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration) 4849 || (( pRates->BeginCutTime >= pRates->EndCutTime) 4850 && (pRates->EndCutTime > 0)) ) 4851 { 4852 pRates->BeginCutTime = 0; 4853 pRates->EndCutTime = 0; 4854 } 4855 4856 if( pRates->EndCutTime == 0 ) 4857 calcduration = 4858 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 4859 else 4860 calcduration = pRates->EndCutTime - pRates->BeginCutTime; 4861 4862 /* priority 1 : max file size */ 4863 if( pRates->OutputFileSize == 0 ) 4864 { 4865 /* we can put maximum values for all undefined parameters */ 4866 if( pRates->EndCutTime == 0 ) 4867 { 4868 pRates->EndCutTime = pC->InputFileProperties.uiClipDuration; 4869 } 4870 4871 if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) 4872 && (fixed_audio == M4OSA_FALSE) ) 4873 { 4874 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4875 } 4876 4877 if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) 4878 && (fixed_video == M4OSA_FALSE) ) 4879 { 4880 /*+ New Encoder bitrates */ 4881 pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; 4882 /*- New Encoder bitrates */ 4883 } 4884 } 4885 else 4886 { 4887 /* compute max duration */ 4888 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 4889 / M4MCS_MOOV_OVER_FILESIZE_RATIO 4890 / (minvideobitrate + minaudiobitrate) * 8000.0); 4891 4892 if( maxduration 4893 + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) 4894 { 4895 maxduration = 4896 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 4897 } 4898 4899 /* priority 2 : cut times */ 4900 if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) ) 4901 { 4902 if( calcduration > maxduration ) 4903 { 4904 calcduration = maxduration; 4905 } 4906 4907 if( calcduration == 0 ) 4908 { 4909 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 4910 } 4911 4912 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 4913 / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0)); 4914 4915 /* audio and video bitrates */ 4916 if( ( pRates->OutputAudioBitrate 4917 == M4VIDEOEDITING_kUndefinedBitrate) 4918 && (pRates->OutputVideoBitrate 4919 == M4VIDEOEDITING_kUndefinedBitrate) ) 4920 { 4921 /* set audio = 1/3 and video = 2/3 */ 4922 if( fixed_audio == M4OSA_FALSE ) 4923 { 4924 if( pC->novideo ) 4925 pRates->OutputAudioBitrate = 4926 M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0); 4927 else 4928 pRates->OutputAudioBitrate = 4929 M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3, 4930 0); 4931 4932 if( pRates->OutputAudioBitrate < minaudiobitrate ) 4933 pRates->OutputAudioBitrate = minaudiobitrate; 4934 4935 if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) 4936 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4937 } 4938 4939 if( fixed_video == M4OSA_FALSE ) 4940 { 4941 pRates->OutputVideoBitrate = 4942 M4MCS_intGetNearestBitrate(maxcombinedbitrate 4943 - pRates->OutputAudioBitrate, 0); 4944 4945 if( pRates->OutputVideoBitrate < minvideobitrate ) 4946 pRates->OutputVideoBitrate = minvideobitrate; 4947 4948 if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4949 pRates->OutputVideoBitrate = 4950 M4VIDEOEDITING_k8_MBPS; /*+ New Encoder 4951 bitrates */ 4952 } 4953 } 4954 else 4955 { 4956 /* priority 3 : audio bitrate */ 4957 if( pRates->OutputAudioBitrate 4958 != M4VIDEOEDITING_kUndefinedBitrate ) 4959 { 4960 while( ( fixed_audio == M4OSA_FALSE) 4961 && (pRates->OutputAudioBitrate >= minaudiobitrate) 4962 && (pRates->OutputAudioBitrate 4963 + minvideobitrate > maxcombinedbitrate) ) 4964 { 4965 pRates->OutputAudioBitrate = 4966 M4MCS_intGetNearestBitrate( 4967 pRates->OutputAudioBitrate, -1); 4968 } 4969 4970 if( ( fixed_audio == M4OSA_FALSE) 4971 && (pRates->OutputAudioBitrate < minaudiobitrate) ) 4972 { 4973 pRates->OutputAudioBitrate = minaudiobitrate; 4974 } 4975 4976 calcbitrate = M4MCS_intGetNearestBitrate( 4977 maxcombinedbitrate 4978 - pRates->OutputAudioBitrate, 0); 4979 4980 if( calcbitrate < minvideobitrate ) 4981 calcbitrate = minvideobitrate; 4982 4983 if( calcbitrate > M4VIDEOEDITING_k8_MBPS ) 4984 calcbitrate = M4VIDEOEDITING_k8_MBPS; 4985 4986 if( ( fixed_video == M4OSA_FALSE) 4987 && (( pRates->OutputVideoBitrate 4988 == M4VIDEOEDITING_kUndefinedBitrate) 4989 || (pRates->OutputVideoBitrate > calcbitrate)) ) 4990 { 4991 pRates->OutputVideoBitrate = calcbitrate; 4992 } 4993 } 4994 else 4995 { 4996 /* priority 4 : video bitrate */ 4997 if( pRates->OutputVideoBitrate 4998 != M4VIDEOEDITING_kUndefinedBitrate ) 4999 { 5000 while( ( fixed_video == M4OSA_FALSE) 5001 && (pRates->OutputVideoBitrate >= minvideobitrate) 5002 && (pRates->OutputVideoBitrate 5003 + minaudiobitrate > maxcombinedbitrate) ) 5004 { 5005 pRates->OutputVideoBitrate = 5006 M4MCS_intGetNearestBitrate( 5007 pRates->OutputVideoBitrate, -1); 5008 } 5009 5010 if( ( fixed_video == M4OSA_FALSE) 5011 && (pRates->OutputVideoBitrate < minvideobitrate) ) 5012 { 5013 pRates->OutputVideoBitrate = minvideobitrate; 5014 } 5015 5016 calcbitrate = 5017 M4MCS_intGetNearestBitrate(maxcombinedbitrate 5018 - pRates->OutputVideoBitrate, 0); 5019 5020 if( calcbitrate < minaudiobitrate ) 5021 calcbitrate = minaudiobitrate; 5022 5023 if( calcbitrate > M4VIDEOEDITING_k96_KBPS ) 5024 calcbitrate = M4VIDEOEDITING_k96_KBPS; 5025 5026 if( ( fixed_audio == M4OSA_FALSE) 5027 && (( pRates->OutputAudioBitrate 5028 == M4VIDEOEDITING_kUndefinedBitrate) 5029 || (pRates->OutputAudioBitrate > calcbitrate)) ) 5030 { 5031 pRates->OutputAudioBitrate = calcbitrate; 5032 } 5033 } 5034 } 5035 } 5036 } 5037 else 5038 { 5039 /* priority 3 : audio bitrate */ 5040 if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 5041 { 5042 /* priority 4 : video bitrate */ 5043 if( pRates->OutputVideoBitrate 5044 != M4VIDEOEDITING_kUndefinedBitrate ) 5045 { 5046 /* compute max duration */ 5047 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5048 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5049 / (pRates->OutputVideoBitrate 5050 + pRates->OutputAudioBitrate) * 8000.0); 5051 5052 if( maxduration + pRates->BeginCutTime 5053 > pC->InputFileProperties.uiClipDuration ) 5054 { 5055 maxduration = pC->InputFileProperties.uiClipDuration 5056 - pRates->BeginCutTime; 5057 } 5058 5059 if( calcduration > maxduration ) 5060 { 5061 calcduration = maxduration; 5062 } 5063 5064 if( calcduration == 0 ) 5065 { 5066 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5067 } 5068 } 5069 else 5070 { 5071 /* start with min video bitrate */ 5072 pRates->OutputVideoBitrate = minvideobitrate; 5073 5074 /* compute max duration */ 5075 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5076 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5077 / (pRates->OutputVideoBitrate 5078 + pRates->OutputAudioBitrate) * 8000.0); 5079 5080 if( maxduration + pRates->BeginCutTime 5081 > pC->InputFileProperties.uiClipDuration ) 5082 { 5083 maxduration = pC->InputFileProperties.uiClipDuration 5084 - pRates->BeginCutTime; 5085 } 5086 5087 if( calcduration > maxduration ) 5088 { 5089 calcduration = maxduration; 5090 } 5091 5092 if( calcduration == 0 ) 5093 { 5094 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5095 } 5096 5097 /* search max possible video bitrate */ 5098 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5099 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5100 / (calcduration / 8000.0)); 5101 5102 while( ( fixed_video == M4OSA_FALSE) 5103 && (pRates->OutputVideoBitrate 5104 < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */ 5105 { 5106 calcbitrate = M4MCS_intGetNearestBitrate( 5107 pRates->OutputVideoBitrate, +1); 5108 5109 if( calcbitrate 5110 + pRates->OutputAudioBitrate <= maxcombinedbitrate ) 5111 pRates->OutputVideoBitrate = calcbitrate; 5112 else 5113 break; 5114 } 5115 } 5116 } 5117 else 5118 { 5119 /* priority 4 : video bitrate */ 5120 if( pRates->OutputVideoBitrate 5121 != M4VIDEOEDITING_kUndefinedBitrate ) 5122 { 5123 /* start with min audio bitrate */ 5124 pRates->OutputAudioBitrate = minaudiobitrate; 5125 5126 /* compute max duration */ 5127 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5128 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5129 / (pRates->OutputVideoBitrate 5130 + pRates->OutputAudioBitrate) * 8000.0); 5131 5132 if( maxduration + pRates->BeginCutTime 5133 > pC->InputFileProperties.uiClipDuration ) 5134 { 5135 maxduration = pC->InputFileProperties.uiClipDuration 5136 - pRates->BeginCutTime; 5137 } 5138 5139 if( calcduration > maxduration ) 5140 { 5141 calcduration = maxduration; 5142 } 5143 5144 if( calcduration == 0 ) 5145 { 5146 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5147 } 5148 5149 /* search max possible audio bitrate */ 5150 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5151 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5152 / (calcduration / 8000.0)); 5153 5154 while( ( fixed_audio == M4OSA_FALSE) 5155 && (pRates->OutputAudioBitrate 5156 < M4VIDEOEDITING_k96_KBPS) ) 5157 { 5158 calcbitrate = M4MCS_intGetNearestBitrate( 5159 pRates->OutputAudioBitrate, +1); 5160 5161 if( calcbitrate 5162 + pRates->OutputVideoBitrate <= maxcombinedbitrate ) 5163 pRates->OutputAudioBitrate = calcbitrate; 5164 else 5165 break; 5166 } 5167 } 5168 else 5169 { 5170 /* compute max duration */ 5171 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5172 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5173 / (minvideobitrate + minaudiobitrate) * 8000.0); 5174 5175 if( maxduration + pRates->BeginCutTime 5176 > pC->InputFileProperties.uiClipDuration ) 5177 { 5178 maxduration = pC->InputFileProperties.uiClipDuration 5179 - pRates->BeginCutTime; 5180 } 5181 5182 if( calcduration > maxduration ) 5183 { 5184 calcduration = maxduration; 5185 } 5186 5187 if( calcduration == 0 ) 5188 { 5189 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5190 } 5191 5192 /* set audio = 1/3 and video = 2/3 */ 5193 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5194 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5195 / (calcduration / 8000.0)); 5196 5197 if( fixed_audio == M4OSA_FALSE ) 5198 { 5199 if( pC->novideo ) 5200 pRates->OutputAudioBitrate = 5201 M4MCS_intGetNearestBitrate(maxcombinedbitrate, 5202 0); 5203 else 5204 pRates->OutputAudioBitrate = 5205 M4MCS_intGetNearestBitrate(maxcombinedbitrate 5206 / 3, 0); 5207 5208 if( pRates->OutputAudioBitrate < minaudiobitrate ) 5209 pRates->OutputAudioBitrate = minaudiobitrate; 5210 5211 if( pRates->OutputAudioBitrate 5212 > M4VIDEOEDITING_k96_KBPS ) 5213 pRates->OutputAudioBitrate = 5214 M4VIDEOEDITING_k96_KBPS; 5215 } 5216 5217 if( fixed_video == M4OSA_FALSE ) 5218 { 5219 pRates->OutputVideoBitrate = 5220 M4MCS_intGetNearestBitrate(maxcombinedbitrate 5221 - pRates->OutputAudioBitrate, 0); 5222 5223 if( pRates->OutputVideoBitrate < minvideobitrate ) 5224 pRates->OutputVideoBitrate = minvideobitrate; 5225 5226 if( pRates->OutputVideoBitrate 5227 > M4VIDEOEDITING_k8_MBPS ) 5228 pRates->OutputVideoBitrate = 5229 M4VIDEOEDITING_k8_MBPS; /*+ New Encoder 5230 bitrates */ 5231 } 5232 } 5233 } 5234 } 5235 } 5236 5237 /* recompute max duration with final bitrates */ 5238 if( pRates->OutputFileSize > 0 ) 5239 { 5240 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5241 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5242 / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) 5243 * 8000.0); 5244 } 5245 else 5246 { 5247 maxduration = pC->InputFileProperties.uiClipDuration; 5248 } 5249 5250 if( maxduration 5251 + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) 5252 { 5253 maxduration = 5254 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 5255 } 5256 5257 if( pRates->EndCutTime == 0 ) 5258 { 5259 pRates->EndCutTime = pRates->BeginCutTime + maxduration; 5260 } 5261 else 5262 { 5263 calcduration = pRates->EndCutTime - pRates->BeginCutTime; 5264 5265 if( calcduration > maxduration ) 5266 { 5267 pRates->EndCutTime = pRates->BeginCutTime + maxduration; 5268 } 5269 } 5270 5271 /* Should never happen : constraints are too strong */ 5272 if( pRates->EndCutTime == pRates->BeginCutTime ) 5273 { 5274 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5275 } 5276 5277 /* estimated resulting file size */ 5278 pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO 5279 * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) 5280 * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0)); 5281 5282 return M4NO_ERROR; 5283 } 5284 5285 /** 5286 ****************************************************************************** 5287 * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext) 5288 * @brief Check parameters to start 5289 * @note 5290 * @param pContext (IN) MCS context 5291 * @return M4NO_ERROR: No error 5292 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 5293 * @return M4ERR_STATE: MCS is not in an appropriate state for 5294 * this function to be called 5295 * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: 5296 * Audio bitrate too high (we limit to 96 kbps) 5297 * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: 5298 * Audio bitrate is too low (16 kbps min for aac, 5299 * 12.2 for amr, 8 for mp3) 5300 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: 5301 * Begin cut and End cut are equals 5302 * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: 5303 * Begin cut time is larger than the input 5304 * clip duration 5305 * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: 5306 * End cut time is smaller than begin cut time 5307 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: 5308 * Not enough space to store whole output 5309 * file at given bitrates 5310 * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: 5311 * Video bitrate too high (we limit to 800 kbps) 5312 * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: 5313 * Video bitrate too low 5314 ****************************************************************************** 5315 */ 5316 M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext ) 5317 { 5318 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 5319 M4MCS_EncodingParams VerifyRates; 5320 M4OSA_ERR err; 5321 5322 /** 5323 * Check input parameters */ 5324 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 5325 "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL"); 5326 5327 #ifdef M4MCS_SUPPORT_STILL_PICTURE 5328 5329 if( pC->m_bIsStillPicture ) 5330 { 5331 /** 5332 * Call the corresponding still picture MCS function*/ 5333 return M4MCS_stillPicCheckParamsAndStart(pC); 5334 } 5335 5336 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 5337 5338 /** 5339 * Check state automaton */ 5340 5341 if( M4MCS_kState_SET != pC->State ) 5342 { 5343 M4OSA_TRACE1_1( 5344 "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE", 5345 pC->State); 5346 return M4ERR_STATE; 5347 } 5348 5349 /* Audio bitrate should not stay undefined at this point */ 5350 if( ( pC->noaudio == M4OSA_FALSE) 5351 && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) 5352 && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) 5353 { 5354 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate"); 5355 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 5356 } 5357 5358 /* Video bitrate should not stay undefined at this point */ 5359 if( ( pC->novideo == M4OSA_FALSE) 5360 && (pC->EncodingVideoFormat != M4ENCODER_kNULL) 5361 && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) 5362 { 5363 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate"); 5364 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; 5365 } 5366 5367 /* Set end cut time if necessary (not an error) */ 5368 if( pC->uiEndCutTime == 0 ) 5369 { 5370 pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; 5371 } 5372 5373 /* Force a re-set to check validity of parameters */ 5374 VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate; 5375 VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate; 5376 VerifyRates.BeginCutTime = pC->uiBeginCutTime; 5377 VerifyRates.EndCutTime = pC->uiEndCutTime; 5378 VerifyRates.OutputFileSize = pC->uiMaxFileSize; 5379 VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale; 5380 5381 err = M4MCS_setEncodingParams(pContext, &VerifyRates); 5382 5383 /** 5384 * Check parameters consistency */ 5385 if( err != M4NO_ERROR ) 5386 { 5387 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found"); 5388 return err; 5389 } 5390 5391 /** 5392 * All is OK : update state automaton */ 5393 pC->uiEncVideoBitrate = pC->uiVideoBitrate; 5394 pC->AudioEncParams.Bitrate = pC->uiAudioBitrate; 5395 5396 #ifdef M4MCS_WITH_FAST_OPEN 5397 /** 5398 * Remake the open if it was done in fast mode */ 5399 5400 if( M4OSA_TRUE == pC->bFileOpenedInFastMode ) 5401 { 5402 /* Close the file opened in fast mode */ 5403 M4MCS_intCleanUp_ReadersDecoders(pC); 5404 5405 pC->State = M4MCS_kState_CREATED; 5406 5407 /* Reopen it in normal mode */ 5408 err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType, 5409 pC->pOutputFile, pC->pTemporaryFile); 5410 5411 if( err != M4NO_ERROR ) 5412 { 5413 M4OSA_TRACE1_1( 5414 "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err); 5415 return err; 5416 } 5417 } 5418 5419 #endif /* M4MCS_WITH_FAST_OPEN */ 5420 5421 pC->State = M4MCS_kState_READY; 5422 5423 return M4NO_ERROR; 5424 } 5425 5426 /** 5427 ****************************************************************************** 5428 * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC) 5429 ****************************************************************************** 5430 */ 5431 static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC ) 5432 { 5433 M4OSA_ERR err; 5434 M4ENCODER_Header *encHeader; 5435 5436 /** 5437 * Prepare the video decoder */ 5438 err = M4MCS_intPrepareVideoDecoder(pC); 5439 5440 if( M4NO_ERROR != err ) 5441 { 5442 M4OSA_TRACE1_1( 5443 "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x", 5444 err); 5445 return err; 5446 } 5447 5448 if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) 5449 && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) 5450 { 5451 pC->bH264Trim = M4OSA_TRUE; 5452 } 5453 5454 /** 5455 * Prepare the video encoder */ 5456 err = M4MCS_intPrepareVideoEncoder(pC); 5457 5458 if( M4NO_ERROR != err ) 5459 { 5460 M4OSA_TRACE1_1( 5461 "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x", 5462 err); 5463 return err; 5464 } 5465 5466 if( ( pC->uiBeginCutTime != 0) 5467 && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) 5468 && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) 5469 { 5470 5471 err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, 5472 M4ENCODER_kOptionID_H264ProcessNALUContext, 5473 (M4OSA_DataOption)pC->m_pInstance); 5474 5475 if( err != M4NO_ERROR ) 5476 { 5477 M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", 5478 err); 5479 return err; 5480 } 5481 5482 err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, 5483 M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr, 5484 (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU); 5485 5486 if( err != M4NO_ERROR ) 5487 { 5488 M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", 5489 err); 5490 return err; 5491 } 5492 5493 err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt, 5494 M4ENCODER_kOptionID_EncoderHeader, 5495 (M4OSA_DataOption) &encHeader); 5496 5497 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) 5498 { 5499 M4OSA_TRACE1_1( 5500 "M4MCS_close: failed to get the encoder header (err 0x%x)", 5501 err); 5502 /**< no return here, we still have stuff to deallocate after close, even if it fails.*/ 5503 } 5504 else 5505 { 5506 // Handle DSI first bits 5507 #define SPS_START_POS 6 5508 5509 pC->m_pInstance->m_encoderSPSSize = 5510 ( encHeader->pBuf[SPS_START_POS] << 8) 5511 + encHeader->pBuf[SPS_START_POS + 1]; 5512 pC->m_pInstance->m_pEncoderSPS = 5513 (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2; 5514 5515 pC->m_pInstance->m_encoderPPSSize = 5516 ( encHeader->pBuf[SPS_START_POS + 3 5517 + pC->m_pInstance->m_encoderSPSSize] << 8) 5518 + encHeader->pBuf[SPS_START_POS + 4 5519 + pC->m_pInstance->m_encoderSPSSize]; 5520 pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5 5521 + pC->m_pInstance->m_encoderSPSSize; 5522 5523 /* Check the DSI integrity */ 5524 if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize 5525 + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) ) 5526 { 5527 M4OSA_TRACE1_3( 5528 "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d", 5529 encHeader->Size, pC->m_pInstance->m_encoderSPSSize, 5530 pC->m_pInstance->m_encoderPPSSize); 5531 return M4ERR_PARAMETER; 5532 } 5533 } 5534 } 5535 5536 /** 5537 * Prepare audio processing */ 5538 err = M4MCS_intPrepareAudioProcessing(pC); 5539 5540 if( M4NO_ERROR != err ) 5541 { 5542 M4OSA_TRACE1_1( 5543 "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x", 5544 err); 5545 return err; 5546 } 5547 5548 /** 5549 * Prepare the writer */ 5550 err = M4MCS_intPrepareWriter(pC); 5551 5552 if( M4NO_ERROR != err ) 5553 { 5554 M4OSA_TRACE1_1( 5555 "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err); 5556 return err; 5557 } 5558 5559 /** 5560 * Jump the audio stream to the begin cut time (all AUs are RAP) 5561 * Must be done after the 3gpp writer init, because it may write the first 5562 * audio AU in some cases */ 5563 err = M4MCS_intPrepareAudioBeginCut(pC); 5564 5565 if( M4NO_ERROR != err ) 5566 { 5567 M4OSA_TRACE1_1( 5568 "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x", 5569 err); 5570 return err; 5571 } 5572 5573 /** 5574 * Update state automaton */ 5575 if( 0 == pC->uiBeginCutTime ) 5576 { 5577 pC->dViDecStartingCts = 0.0; 5578 /** 5579 * No begin cut, do the encoding */ 5580 pC->State = M4MCS_kState_PROCESSING; 5581 } 5582 else 5583 { 5584 /** 5585 * Remember that we must start the decode/encode process at the begin cut time */ 5586 pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime; 5587 5588 /** 5589 * Jumping */ 5590 pC->State = M4MCS_kState_BEGINVIDEOJUMP; 5591 } 5592 5593 /** 5594 * Return with no error */ 5595 M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR"); 5596 return M4NO_ERROR; 5597 } 5598 5599 /** 5600 ****************************************************************************** 5601 * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC); 5602 * @brief Prepare the video decoder. 5603 * @param pC (IN) MCS private context 5604 * @return M4NO_ERROR No error 5605 * @return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED 5606 * @return Any error returned by an underlaying module 5607 ****************************************************************************** 5608 */ 5609 static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC ) 5610 { 5611 M4OSA_ERR err; 5612 M4OSA_Void *decoderUserData; 5613 M4DECODER_OutputFilter FilterOption; 5614 5615 if( pC->novideo ) 5616 return M4NO_ERROR; 5617 5618 /** 5619 * Create the decoder, if it has not been created yet (to get video properties for example) */ 5620 if( M4OSA_NULL == pC->pViDecCtxt ) 5621 { 5622 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 5623 5624 decoderUserData = pC->m_pCurrentVideoDecoderUserData; 5625 5626 #else 5627 5628 decoderUserData = M4OSA_NULL; 5629 5630 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */ 5631 5632 err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt, 5633 &pC->pReaderVideoStream->m_basicProperties, pC->m_pReader, 5634 pC->m_pReaderDataIt, &pC->ReaderVideoAU, decoderUserData); 5635 5636 if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err ) 5637 { 5638 /** 5639 * Our decoder is not compatible with H263 profile other than 0. 5640 * So it returns this internal error code. 5641 * We translate it to our own error code */ 5642 M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\ 5643 returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED"); 5644 return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED; 5645 } 5646 else if( M4NO_ERROR != err ) 5647 { 5648 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ 5649 m_pVideoDecoder->m_pFctCreate returns 0x%x", err); 5650 return err; 5651 } 5652 5653 if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType ) 5654 { 5655 FilterOption.m_pFilterFunction = 5656 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420; 5657 FilterOption.m_pFilterUserData = M4OSA_NULL; 5658 err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt, 5659 M4DECODER_kOptionID_OutputFilter, 5660 (M4OSA_DataOption) &FilterOption); 5661 5662 if( M4NO_ERROR != err ) 5663 { 5664 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ 5665 m_pVideoDecoder->m_pFctSetOption returns 0x%x", err); 5666 return err; 5667 } 5668 } 5669 } 5670 5671 /** 5672 * Return with no error */ 5673 M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR"); 5674 return M4NO_ERROR; 5675 } 5676 5677 /** 5678 ****************************************************************************** 5679 * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC); 5680 * @brief Prepare the video encoder. 5681 * @param pC (IN) MCS private context 5682 * @return M4NO_ERROR No error 5683 * @return Any error returned by an underlaying module 5684 ****************************************************************************** 5685 */ 5686 static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC ) 5687 { 5688 M4OSA_ERR err; 5689 M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */ 5690 M4ENCODER_Params EncParams1; 5691 M4OSA_Double dFrameRate; /**< tmp variable */ 5692 5693 if( pC->novideo ) 5694 return M4NO_ERROR; 5695 5696 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 5697 { 5698 /* Approximative cts increment */ 5699 pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate; 5700 5701 if( pC->uiBeginCutTime == 0 ) 5702 { 5703 M4OSA_TRACE3_0( 5704 "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing."); 5705 return M4NO_ERROR; 5706 } 5707 else 5708 { 5709 M4OSA_TRACE3_0( 5710 "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults."); 5711 5712 /* Set useful parameters to encode the first I-frame */ 5713 EncParams.InputFormat = M4ENCODER_kIYUV420; 5714 EncParams.videoProfile = pC->encodingVideoProfile; 5715 EncParams.videoLevel= pC->encodingVideoLevel; 5716 5717 switch( pC->InputFileProperties.VideoStreamType ) 5718 { 5719 case M4VIDEOEDITING_kH263: 5720 EncParams.Format = M4ENCODER_kH263; 5721 break; 5722 5723 case M4VIDEOEDITING_kMPEG4: 5724 EncParams.Format = M4ENCODER_kMPEG4; 5725 break; 5726 5727 case M4VIDEOEDITING_kH264: 5728 EncParams.Format = M4ENCODER_kH264; 5729 break; 5730 5731 default: 5732 M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\ 5733 (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED", 5734 pC->InputFileProperties.VideoStreamType); 5735 return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED; 5736 } 5737 5738 EncParams.FrameWidth = pC->EncodingWidth; 5739 EncParams.FrameHeight = pC->EncodingHeight; 5740 EncParams.Bitrate = pC->uiEncVideoBitrate; 5741 EncParams.bInternalRegulation = 5742 M4OSA_FALSE; /* do not constrain the I-frame */ 5743 EncParams.FrameRate = pC->EncodingVideoFramerate; 5744 5745 /* Other encoding settings (quite all dummy...) */ 5746 EncParams.uiHorizontalSearchRange = 0; /* use default */ 5747 EncParams.uiVerticalSearchRange = 0; /* use default */ 5748 EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */ 5749 EncParams.uiIVopPeriod = 0; /* use default */ 5750 EncParams.uiMotionEstimationTools = 5751 0; /* M4V_MOTION_EST_TOOLS_ALL */ 5752 EncParams.bAcPrediction = M4OSA_TRUE; /* use AC prediction */ 5753 EncParams.uiStartingQuantizerValue = 5; /* initial QP = 5 */ 5754 EncParams.bDataPartitioning = 5755 M4OSA_FALSE; /* no data partitioning */ 5756 5757 /* Rate factor */ 5758 EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale; 5759 EncParams.uiRateFactor = 1; 5760 } 5761 } 5762 else 5763 { 5764 M4OSA_TRACE3_0( 5765 "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config."); 5766 5767 /** 5768 * Set encoder shell parameters according to MCS settings */ 5769 EncParams.Format = pC->EncodingVideoFormat; 5770 EncParams.InputFormat = M4ENCODER_kIYUV420; 5771 EncParams.videoProfile = pC->encodingVideoProfile; 5772 EncParams.videoLevel= pC->encodingVideoLevel; 5773 5774 /** 5775 * Video frame size */ 5776 EncParams.FrameWidth = pC->EncodingWidth; 5777 EncParams.FrameHeight = pC->EncodingHeight; 5778 5779 /** 5780 * Video bitrate has been previously computed */ 5781 EncParams.Bitrate = pC->uiEncVideoBitrate; 5782 5783 /** 5784 * MCS use the "true" core internal bitrate regulation */ 5785 EncParams.bInternalRegulation = M4OSA_TRUE; 5786 5787 /** 5788 * Other encoder settings */ 5789 5790 EncParams.uiHorizontalSearchRange = 0; /* use default */ 5791 EncParams.uiVerticalSearchRange = 0; /* use default */ 5792 EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */ 5793 EncParams.uiIVopPeriod = 0; /* use default */ 5794 EncParams.uiMotionEstimationTools = 5795 0; /* M4V_MOTION_EST_TOOLS_ALL */ 5796 EncParams.bAcPrediction = M4OSA_TRUE; /* use AC prediction */ 5797 EncParams.uiStartingQuantizerValue = 10; /* initial QP = 10 */ 5798 EncParams.bDataPartitioning = 5799 M4OSA_FALSE; /* no data partitioning */ 5800 5801 5802 /** 5803 * Video encoder frame rate and rate factor */ 5804 EncParams.FrameRate = pC->EncodingVideoFramerate; 5805 EncParams.uiTimeScale = pC->outputVideoTimescale; 5806 5807 switch( pC->EncodingVideoFramerate ) 5808 { 5809 case M4ENCODER_k5_FPS: 5810 dFrameRate = 5.0; 5811 break; 5812 5813 case M4ENCODER_k7_5_FPS: 5814 dFrameRate = 7.5; 5815 break; 5816 5817 case M4ENCODER_k10_FPS: 5818 dFrameRate = 10.0; 5819 break; 5820 5821 case M4ENCODER_k12_5_FPS: 5822 dFrameRate = 12.5; 5823 break; 5824 5825 case M4ENCODER_k15_FPS: 5826 dFrameRate = 15.0; 5827 break; 5828 5829 case M4ENCODER_k20_FPS: /**< MPEG-4 only */ 5830 dFrameRate = 20.0; 5831 break; 5832 5833 case M4ENCODER_k25_FPS: /**< MPEG-4 only */ 5834 dFrameRate = 25.0; 5835 break; 5836 5837 case M4ENCODER_k30_FPS: 5838 dFrameRate = 30.0; 5839 break; 5840 5841 default: 5842 M4OSA_TRACE1_1( 5843 "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\ 5844 (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", 5845 pC->EncodingVideoFramerate); 5846 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; 5847 } 5848 5849 /** 5850 * Compute the number of milliseconds between two frames */ 5851 if( M4ENCODER_kH263 == EncParams.Format ) 5852 { 5853 pC->dCtsIncrement = 1001.0 / dFrameRate; 5854 } 5855 else /**< MPEG4 or H.264 */ 5856 { 5857 pC->dCtsIncrement = 1000.0 / dFrameRate; 5858 } 5859 } 5860 5861 /** 5862 * Limit the video bitrate according to encoder profile 5863 * and level */ 5864 err = M4MCS_intLimitBitratePerCodecProfileLevel(&EncParams); 5865 if (M4NO_ERROR != err) { 5866 M4OSA_TRACE1_1( 5867 "M4MCS_intPrepareVideoEncoder: limit bitrate returned err \ 5868 0x%x", err); 5869 return err; 5870 } 5871 5872 /** 5873 * Create video encoder */ 5874 err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt, 5875 pC->pWriterDataFcts, \ 5876 M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \ 5877 pC->pCurrentVideoEncoderUserData); 5878 5879 /**< We put the MCS context in place of the VPP context */ 5880 if( M4NO_ERROR != err ) 5881 { 5882 M4OSA_TRACE1_1( 5883 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x", 5884 err); 5885 return err; 5886 } 5887 5888 pC->encoderState = M4MCS_kEncoderClosed; 5889 5890 if( M4OSA_TRUE == pC->bH264Trim ) 5891 //if((M4ENCODER_kNULL == pC->EncodingVideoFormat) 5892 // && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType)) 5893 { 5894 EncParams1.InputFormat = EncParams.InputFormat; 5895 //EncParams1.InputFrameWidth = EncParams.InputFrameWidth; 5896 //EncParams1.InputFrameHeight = EncParams.InputFrameHeight; 5897 EncParams1.FrameWidth = EncParams.FrameWidth; 5898 EncParams1.FrameHeight = EncParams.FrameHeight; 5899 EncParams1.videoProfile= EncParams.videoProfile; 5900 EncParams1.videoLevel= EncParams.videoLevel; 5901 EncParams1.Bitrate = EncParams.Bitrate; 5902 EncParams1.FrameRate = EncParams.FrameRate; 5903 EncParams1.Format = M4ENCODER_kH264; //EncParams.Format; 5904 M4OSA_TRACE1_2("mcs encoder open profile :%d, level %d", 5905 EncParams1.videoProfile, EncParams1.videoLevel); 5906 err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, 5907 &pC->WriterVideoAU, &EncParams1); 5908 } 5909 else 5910 { 5911 M4OSA_TRACE1_2("mcs encoder open Adv profile :%d, level %d", 5912 EncParams.videoProfile, EncParams.videoLevel); 5913 err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, 5914 &pC->WriterVideoAU, &EncParams); 5915 } 5916 5917 if( M4NO_ERROR != err ) 5918 { 5919 M4OSA_TRACE1_1( 5920 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x", 5921 err); 5922 return err; 5923 } 5924 5925 pC->encoderState = M4MCS_kEncoderStopped; 5926 5927 if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart ) 5928 { 5929 err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt); 5930 5931 if( M4NO_ERROR != err ) 5932 { 5933 M4OSA_TRACE1_1( 5934 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x", 5935 err); 5936 return err; 5937 } 5938 } 5939 5940 pC->encoderState = M4MCS_kEncoderRunning; 5941 5942 /******************************/ 5943 /* Video resize management */ 5944 /******************************/ 5945 /** 5946 * Compare video input size and video output size to check if resize is needed */ 5947 if( ( (M4OSA_UInt32)EncParams.FrameWidth 5948 != pC->pReaderVideoStream->m_videoWidth) 5949 || ((M4OSA_UInt32)EncParams.FrameHeight 5950 != pC->pReaderVideoStream->m_videoHeight) ) 5951 { 5952 /** 5953 * Allocate the intermediate video plane that will receive the decoded image before 5954 resizing */ 5955 pC->pPreResizeFrame = 5956 (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3 * sizeof(M4VIFI_ImagePlane), 5957 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame"); 5958 5959 if( M4OSA_NULL == pC->pPreResizeFrame ) 5960 { 5961 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\ 5962 unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC"); 5963 return M4ERR_ALLOC; 5964 } 5965 5966 pC->pPreResizeFrame[0].pac_data = M4OSA_NULL; 5967 pC->pPreResizeFrame[1].pac_data = M4OSA_NULL; 5968 pC->pPreResizeFrame[2].pac_data = M4OSA_NULL; 5969 5970 /** 5971 * Allocate the Y plane */ 5972 pC->pPreResizeFrame[0].u_topleft = 0; 5973 pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream-> 5974 m_videoWidth; /**< input width */ 5975 pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream-> 5976 m_videoHeight; /**< input height */ 5977 pC->pPreResizeFrame[0].u_stride = pC-> 5978 pPreResizeFrame[0].u_width; /**< simple case: stride equals width */ 5979 5980 pC->pPreResizeFrame[0].pac_data = 5981 (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[0].u_stride \ 5982 *pC->pPreResizeFrame[0].u_height, M4MCS, 5983 (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); 5984 5985 if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data ) 5986 { 5987 M4OSA_TRACE1_0( 5988 "M4MCS_intPrepareVideoEncoder():\ 5989 unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC"); 5990 return M4ERR_ALLOC; 5991 } 5992 5993 /** 5994 * Allocate the U plane */ 5995 pC->pPreResizeFrame[1].u_topleft = 0; 5996 pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width 5997 >> 1; /**< U width is half the Y width */ 5998 pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height 5999 >> 1; /**< U height is half the Y height */ 6000 pC->pPreResizeFrame[1].u_stride = pC-> 6001 pPreResizeFrame[1].u_width; /**< simple case: stride equals width */ 6002 6003 pC->pPreResizeFrame[1].pac_data = 6004 (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[1].u_stride \ 6005 *pC->pPreResizeFrame[1].u_height, M4MCS, 6006 (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 6007 6008 if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data ) 6009 { 6010 M4OSA_TRACE1_0( 6011 "M4MCS_intPrepareVideoEncoder():\ 6012 unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC"); 6013 return M4ERR_ALLOC; 6014 } 6015 6016 /** 6017 * Allocate the V plane */ 6018 pC->pPreResizeFrame[2].u_topleft = 0; 6019 pC->pPreResizeFrame[2].u_width = pC-> 6020 pPreResizeFrame[1].u_width; /**< V width equals U width */ 6021 pC->pPreResizeFrame[2].u_height = pC-> 6022 pPreResizeFrame[1].u_height; /**< V height equals U height */ 6023 pC->pPreResizeFrame[2].u_stride = pC-> 6024 pPreResizeFrame[2].u_width; /**< simple case: stride equals width */ 6025 6026 pC->pPreResizeFrame[2].pac_data = 6027 (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[2].u_stride \ 6028 *pC->pPreResizeFrame[2].u_height, M4MCS, 6029 (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 6030 6031 if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data ) 6032 { 6033 M4OSA_TRACE1_0( 6034 "M4MCS_intPrepareVideoEncoder():\ 6035 unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC"); 6036 return M4ERR_ALLOC; 6037 } 6038 } 6039 6040 /** 6041 * Return with no error */ 6042 M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR"); 6043 return M4NO_ERROR; 6044 } 6045 6046 /** 6047 ****************************************************************************** 6048 * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC); 6049 * @brief Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder. 6050 * @param pC (IN) MCS private context 6051 * @return M4NO_ERROR No error 6052 * @return Any error returned by an underlaying module 6053 ****************************************************************************** 6054 */ 6055 static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC ) 6056 { 6057 M4OSA_ERR err; 6058 6059 SSRC_ReturnStatus_en 6060 ReturnStatus; /* Function return status */ 6061 LVM_INT16 NrSamplesMin = 6062 0; /* Minimal number of samples on the input or on the output */ 6063 LVM_INT32 ScratchSize; /* The size of the scratch memory */ 6064 LVM_INT16 6065 *pInputInScratch; /* Pointer to input in the scratch buffer */ 6066 LVM_INT16 6067 *pOutputInScratch; /* Pointer to the output in the scratch buffer */ 6068 SSRC_Params_t ssrcParams; /* Memory for init parameters */ 6069 6070 #ifdef MCS_DUMP_PCM_TO_FILE 6071 6072 file_au_reader = fopen("mcs_ReaderOutput.raw", "wb"); 6073 file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb"); 6074 file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb"); 6075 6076 #endif 6077 6078 if( pC->noaudio ) 6079 return M4NO_ERROR; 6080 6081 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 6082 { 6083 M4OSA_TRACE3_0( 6084 "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing."); 6085 return M4NO_ERROR; 6086 } 6087 6088 /* ________________________________ */ 6089 /*| |*/ 6090 /*| Create and "start" the decoder |*/ 6091 /*|________________________________|*/ 6092 6093 if( M4OSA_NULL == pC->m_pAudioDecoder ) 6094 { 6095 M4OSA_TRACE1_0( 6096 "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder."); 6097 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 6098 } 6099 6100 if( M4OSA_NULL == pC->pAudioDecCtxt ) 6101 { 6102 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt, 6103 pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData); 6104 6105 if( M4NO_ERROR != err ) 6106 { 6107 M4OSA_TRACE1_1( 6108 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 6109 err); 6110 return err; 6111 } 6112 } 6113 6114 if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) { 6115 /* AMR DECODER CONFIGURATION */ 6116 6117 /* nothing specific to do */ 6118 } 6119 else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) { 6120 /* EVRC DECODER CONFIGURATION */ 6121 6122 /* nothing specific to do */ 6123 } 6124 else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) { 6125 /* MP3 DECODER CONFIGURATION */ 6126 6127 /* nothing specific to do */ 6128 } 6129 else 6130 { 6131 /* AAC DECODER CONFIGURATION */ 6132 M4_AacDecoderConfig AacDecParam; 6133 6134 AacDecParam.m_AACDecoderProfile = AAC_kAAC; 6135 AacDecParam.m_DownSamplingMode = AAC_kDS_OFF; 6136 6137 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 6138 { 6139 AacDecParam.m_OutputMode = AAC_kMono; 6140 } 6141 else 6142 { 6143 /* For this version, we encode only in AAC */ 6144 if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) 6145 { 6146 AacDecParam.m_OutputMode = AAC_kMono; 6147 } 6148 else 6149 { 6150 AacDecParam.m_OutputMode = AAC_kStereo; 6151 } 6152 } 6153 6154 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 6155 M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); 6156 } 6157 6158 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 6159 M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); 6160 6161 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 6162 M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); 6163 6164 if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) 6165 { 6166 /* Not implemented in all decoders */ 6167 err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); 6168 6169 if( M4NO_ERROR != err ) 6170 { 6171 M4OSA_TRACE1_1( 6172 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x", 6173 err); 6174 return err; 6175 } 6176 } 6177 6178 /** 6179 * Allocate output buffer for the audio decoder */ 6180 pC->InputFileProperties.uiDecodedPcmSize = 6181 pC->pReaderAudioStream->m_byteFrameLength 6182 * pC->pReaderAudioStream->m_byteSampleSize 6183 * pC->pReaderAudioStream->m_nbChannels; 6184 6185 if( pC->InputFileProperties.uiDecodedPcmSize > 0 ) 6186 { 6187 pC->AudioDecBufferOut.m_bufferSize = 6188 pC->InputFileProperties.uiDecodedPcmSize; 6189 pC->AudioDecBufferOut.m_dataAddress = 6190 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->AudioDecBufferOut.m_bufferSize \ 6191 *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize"); 6192 } 6193 6194 if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress ) 6195 { 6196 M4OSA_TRACE1_0( 6197 "M4MCS_intPrepareVideoDecoder():\ 6198 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC"); 6199 return M4ERR_ALLOC; 6200 } 6201 6202 /* _________________________ */ 6203 /*| |*/ 6204 /*| Set the SSRC parameters |*/ 6205 /*|_________________________|*/ 6206 6207 switch( pC->pReaderAudioStream->m_samplingFrequency ) 6208 { 6209 case 8000: 6210 ssrcParams.SSRC_Fs_In = LVM_FS_8000; 6211 break; 6212 6213 case 11025: 6214 ssrcParams.SSRC_Fs_In = LVM_FS_11025; 6215 break; 6216 6217 case 12000: 6218 ssrcParams.SSRC_Fs_In = LVM_FS_12000; 6219 break; 6220 6221 case 16000: 6222 ssrcParams.SSRC_Fs_In = LVM_FS_16000; 6223 break; 6224 6225 case 22050: 6226 ssrcParams.SSRC_Fs_In = LVM_FS_22050; 6227 break; 6228 6229 case 24000: 6230 ssrcParams.SSRC_Fs_In = LVM_FS_24000; 6231 break; 6232 6233 case 32000: 6234 ssrcParams.SSRC_Fs_In = LVM_FS_32000; 6235 break; 6236 6237 case 44100: 6238 ssrcParams.SSRC_Fs_In = LVM_FS_44100; 6239 break; 6240 6241 case 48000: 6242 ssrcParams.SSRC_Fs_In = LVM_FS_48000; 6243 break; 6244 6245 default: 6246 M4OSA_TRACE1_1( 6247 "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\ 6248 returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", 6249 pC->pReaderAudioStream->m_samplingFrequency); 6250 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; 6251 } 6252 6253 if( 1 == pC->pReaderAudioStream->m_nbChannels ) 6254 { 6255 ssrcParams.SSRC_NrOfChannels = LVM_MONO; 6256 } 6257 else 6258 { 6259 ssrcParams.SSRC_NrOfChannels = LVM_STEREO; 6260 } 6261 6262 /*FlB 26.02.2009: add mp3 as output format*/ 6263 if( pC->AudioEncParams.Format == M4ENCODER_kAAC 6264 || pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 6265 { 6266 switch( pC->AudioEncParams.Frequency ) 6267 { 6268 case M4ENCODER_k8000Hz: 6269 ssrcParams.SSRC_Fs_Out = LVM_FS_8000; 6270 break; 6271 6272 case M4ENCODER_k11025Hz: 6273 ssrcParams.SSRC_Fs_Out = LVM_FS_11025; 6274 break; 6275 6276 case M4ENCODER_k12000Hz: 6277 ssrcParams.SSRC_Fs_Out = LVM_FS_12000; 6278 break; 6279 6280 case M4ENCODER_k16000Hz: 6281 ssrcParams.SSRC_Fs_Out = LVM_FS_16000; 6282 break; 6283 6284 case M4ENCODER_k22050Hz: 6285 ssrcParams.SSRC_Fs_Out = LVM_FS_22050; 6286 break; 6287 6288 case M4ENCODER_k24000Hz: 6289 ssrcParams.SSRC_Fs_Out = LVM_FS_24000; 6290 break; 6291 6292 case M4ENCODER_k32000Hz: 6293 ssrcParams.SSRC_Fs_Out = LVM_FS_32000; 6294 break; 6295 6296 case M4ENCODER_k44100Hz: 6297 ssrcParams.SSRC_Fs_Out = LVM_FS_44100; 6298 break; 6299 6300 case M4ENCODER_k48000Hz: 6301 ssrcParams.SSRC_Fs_Out = LVM_FS_48000; 6302 break; 6303 6304 default: 6305 M4OSA_TRACE1_1( 6306 "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \ 6307 (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", 6308 pC->AudioEncParams.Frequency); 6309 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; 6310 break; 6311 } 6312 } 6313 else 6314 { 6315 ssrcParams.SSRC_Fs_Out = LVM_FS_8000; 6316 } 6317 6318 6319 6320 ReturnStatus = 0; 6321 6322 switch( ssrcParams.SSRC_Fs_In ) 6323 { 6324 case LVM_FS_8000: 6325 ssrcParams.NrSamplesIn = 320; 6326 break; 6327 6328 case LVM_FS_11025: 6329 ssrcParams.NrSamplesIn = 441; 6330 break; 6331 6332 case LVM_FS_12000: 6333 ssrcParams.NrSamplesIn = 480; 6334 break; 6335 6336 case LVM_FS_16000: 6337 ssrcParams.NrSamplesIn = 640; 6338 break; 6339 6340 case LVM_FS_22050: 6341 ssrcParams.NrSamplesIn = 882; 6342 break; 6343 6344 case LVM_FS_24000: 6345 ssrcParams.NrSamplesIn = 960; 6346 break; 6347 6348 case LVM_FS_32000: 6349 ssrcParams.NrSamplesIn = 1280; 6350 break; 6351 6352 case LVM_FS_44100: 6353 ssrcParams.NrSamplesIn = 1764; 6354 break; 6355 6356 case LVM_FS_48000: 6357 ssrcParams.NrSamplesIn = 1920; 6358 break; 6359 6360 default: 6361 ReturnStatus = -1; 6362 break; 6363 } 6364 6365 switch( ssrcParams.SSRC_Fs_Out ) 6366 { 6367 case LVM_FS_8000: 6368 ssrcParams.NrSamplesOut = 320; 6369 break; 6370 6371 case LVM_FS_11025: 6372 ssrcParams.NrSamplesOut = 441; 6373 break; 6374 6375 case LVM_FS_12000: 6376 ssrcParams.NrSamplesOut = 480; 6377 break; 6378 6379 case LVM_FS_16000: 6380 ssrcParams.NrSamplesOut = 640; 6381 break; 6382 6383 case LVM_FS_22050: 6384 ssrcParams.NrSamplesOut = 882; 6385 break; 6386 6387 case LVM_FS_24000: 6388 ssrcParams.NrSamplesOut = 960; 6389 break; 6390 6391 case LVM_FS_32000: 6392 ssrcParams.NrSamplesOut = 1280; 6393 break; 6394 6395 case LVM_FS_44100: 6396 ssrcParams.NrSamplesOut = 1764; 6397 break; 6398 6399 case LVM_FS_48000: 6400 ssrcParams.NrSamplesOut = 1920; 6401 break; 6402 6403 default: 6404 ReturnStatus = -1; 6405 break; 6406 } 6407 6408 6409 6410 if( ReturnStatus != SSRC_OK ) 6411 { 6412 M4OSA_TRACE1_1( 6413 "M4MCS_intPrepareAudioProcessing:\ 6414 Error code %d returned by the SSRC_GetNrSamples function", 6415 ReturnStatus); 6416 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 6417 } 6418 6419 NrSamplesMin = 6420 (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut) 6421 ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn); 6422 6423 while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE ) 6424 { /* Don't take blocks smaller that the minimal block size */ 6425 ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1); 6426 ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1); 6427 NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1); 6428 } 6429 6430 6431 pC->iSsrcNbSamplIn = (LVM_INT16)( 6432 ssrcParams. 6433 NrSamplesIn); /* multiplication by NrOfChannels is done below */ 6434 pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut); 6435 6436 /** 6437 * Allocate buffer for the input of the SSRC */ 6438 pC->pSsrcBufferIn = 6439 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplIn * sizeof(short) \ 6440 *pC->pReaderAudioStream->m_nbChannels, M4MCS, 6441 (M4OSA_Char *)"pSsrcBufferIn"); 6442 6443 if( M4OSA_NULL == pC->pSsrcBufferIn ) 6444 { 6445 M4OSA_TRACE1_0( 6446 "M4MCS_intPrepareVideoDecoder():\ 6447 unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC"); 6448 return M4ERR_ALLOC; 6449 } 6450 pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn; 6451 6452 /** 6453 * Allocate buffer for the output of the SSRC */ 6454 pC->pSsrcBufferOut = 6455 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplOut * sizeof(short) \ 6456 *pC->pReaderAudioStream->m_nbChannels, M4MCS, 6457 (M4OSA_Char *)"pSsrcBufferOut"); 6458 6459 if( M4OSA_NULL == pC->pSsrcBufferOut ) 6460 { 6461 M4OSA_TRACE1_0( 6462 "M4MCS_intPrepareVideoDecoder():\ 6463 unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC"); 6464 return M4ERR_ALLOC; 6465 } 6466 6467 6468 pC->pLVAudioResampler = LVAudioResamplerCreate( 6469 16, /*gInputParams.lvBTChannelCount*/ 6470 (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/, 6471 (M4OSA_Int32)(pC->AudioEncParams.Frequency)/*ssrcParams.SSRC_Fs_Out*/, 1); 6472 6473 if( M4OSA_NULL == pC->pLVAudioResampler) 6474 { 6475 return M4ERR_ALLOC; 6476 } 6477 6478 LVAudiosetSampleRate(pC->pLVAudioResampler, 6479 /*gInputParams.lvInSampleRate*/ 6480 /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/ 6481 pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/); 6482 6483 LVAudiosetVolume(pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */), 6484 (M4OSA_Int16)(0x1000/*0x7fff*/)); 6485 6486 6487 /* ________________________ */ 6488 /*| |*/ 6489 /*| Init the audio encoder |*/ 6490 /*|________________________|*/ 6491 6492 /* Initialise the audio encoder */ 6493 6494 err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt, 6495 pC->pCurrentAudioEncoderUserData); 6496 6497 if( M4NO_ERROR != err ) 6498 { 6499 M4OSA_TRACE1_1( 6500 "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x", 6501 err); 6502 return err; 6503 } 6504 6505 /* Open the audio encoder */ 6506 err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt, 6507 &pC->AudioEncParams, &pC->pAudioEncDSI, 6508 M4OSA_NULL /* no grabbing */); 6509 6510 if( M4NO_ERROR != err ) 6511 { 6512 M4OSA_TRACE1_1( 6513 "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x", 6514 err); 6515 return err; 6516 } 6517 6518 /* Allocate the input buffer for the audio encoder */ 6519 switch( pC->AudioEncParams.Format ) 6520 { 6521 case M4ENCODER_kAMRNB: 6522 pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES; 6523 break; 6524 6525 case M4ENCODER_kAAC: 6526 pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES; 6527 break; 6528 6529 /*FlB 26.02.2009: add mp3 as output format*/ 6530 case M4ENCODER_kMP3: 6531 pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES; 6532 break; 6533 6534 default: 6535 break; 6536 } 6537 6538 if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) 6539 pC->audioEncoderGranularity *= sizeof(short); 6540 else 6541 pC->audioEncoderGranularity *= sizeof(short) * 2; 6542 6543 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 6544 pC->pAudioEncoderBuffer = 6545 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->audioEncoderGranularity, M4MCS, 6546 (M4OSA_Char *)"pC->pAudioEncoderBuffer"); 6547 6548 /** 6549 * Return with no error */ 6550 M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR"); 6551 return M4NO_ERROR; 6552 } 6553 6554 /** 6555 ****************************************************************************** 6556 * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC); 6557 * @brief Prepare the writer. 6558 * @param pC (IN) MCS private context 6559 * @return M4NO_ERROR No error 6560 * @return Any error returned by an underlaying module 6561 ****************************************************************************** 6562 */ 6563 static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC ) 6564 { 6565 M4OSA_ERR err; 6566 M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */ 6567 M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */ 6568 M4SYS_StreamIDValue optionValue; /**< For the setoption calls */ 6569 M4OSA_UInt32 TargetedFileSize; 6570 M4OSA_Bool bMULPPSSPS = M4OSA_FALSE; 6571 6572 /** 6573 * Init the writer */ 6574 err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile, 6575 pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr); 6576 6577 if( M4NO_ERROR != err ) 6578 { 6579 M4OSA_TRACE1_1( 6580 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x", 6581 err); 6582 return err; 6583 } 6584 6585 /** 6586 * Link to the writer context in the writer interface */ 6587 pC->pWriterDataFcts->pWriterContext = pC->pWriterContext; 6588 6589 /** 6590 * Set the product description string in the written file */ 6591 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6592 M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS "); 6593 6594 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6595 != err) ) /* this option may not be implemented by some writers */ 6596 { 6597 M4OSA_TRACE1_1( 6598 "M4MCS_intPrepareWriter:\ 6599 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x", 6600 err); 6601 return err; 6602 } 6603 6604 /** 6605 * Set the product version in the written file */ 6606 uiVersion = 6607 M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 6608 + M4VIDEOEDITING_VERSION_REVISION; 6609 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6610 M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); 6611 6612 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6613 != err) ) /* this option may not be implemented by some writers */ 6614 { 6615 M4OSA_TRACE1_1( 6616 "M4MCS_intPrepareWriter: \ 6617 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x", 6618 err); 6619 return err; 6620 } 6621 6622 /** 6623 * If there is a video input, allocate and fill the video stream structures for the writer */ 6624 if( pC->novideo == M4OSA_FALSE ) 6625 { 6626 /** 6627 * Fill Video properties structure for the AddStream method */ 6628 pC->WriterVideoStreamInfo.height = pC->EncodingHeight; 6629 pC->WriterVideoStreamInfo.width = pC->EncodingWidth; 6630 pC->WriterVideoStreamInfo.fps = 6631 0; /**< Not used by the shell/core writer */ 6632 pC->WriterVideoStreamInfo.Header.pBuf = 6633 M4OSA_NULL; /**< Will be updated later */ 6634 pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */ 6635 6636 /** 6637 * Fill Video stream description structure for the AddStream method */ 6638 switch( pC->EncodingVideoFormat ) 6639 { 6640 case M4ENCODER_kMPEG4: 6641 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; 6642 break; 6643 6644 case M4ENCODER_kH263: 6645 pC->WriterVideoStream.streamType = M4SYS_kH263; 6646 break; 6647 6648 case M4ENCODER_kH264: 6649 pC->WriterVideoStream.streamType = M4SYS_kH264; 6650 break; 6651 6652 case M4ENCODER_kNULL: 6653 switch( pC->InputFileProperties.VideoStreamType ) 6654 { 6655 case M4VIDEOEDITING_kMPEG4: 6656 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; 6657 break; 6658 6659 case M4VIDEOEDITING_kH263: 6660 pC->WriterVideoStream.streamType = M4SYS_kH263; 6661 break; 6662 6663 case M4VIDEOEDITING_kH264: 6664 pC->WriterVideoStream.streamType = M4SYS_kH264; 6665 break; 6666 6667 default: 6668 M4OSA_TRACE1_1( 6669 "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \ 6670 unknown format (0x%x),\ 6671 returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", 6672 pC->EncodingVideoFormat); 6673 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; 6674 } 6675 break; 6676 6677 default: /**< It should never happen, already tested */ 6678 M4OSA_TRACE1_1( 6679 "M4MCS_intPrepareWriter: unknown format (0x%x),\ 6680 returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", 6681 pC->EncodingVideoFormat); 6682 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; 6683 } 6684 6685 /** 6686 * Video bitrate value will be the real value */ 6687 pC->WriterVideoStream.averageBitrate = 6688 (M4OSA_Int32)pC->uiEncVideoBitrate; 6689 pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate; 6690 6691 /** 6692 * most other parameters are "dummy" */ 6693 pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 6694 pC->WriterVideoStream.timeScale = 6695 0; /**< Not used by the shell/core writer */ 6696 pC->WriterVideoStream.profileLevel = 6697 0; /**< Not used by the shell/core writer */ 6698 pC->WriterVideoStream.duration = 6699 0; /**< Not used by the shell/core writer */ 6700 pC->WriterVideoStream.decoderSpecificInfoSize = 6701 sizeof(M4WRITER_StreamVideoInfos); 6702 pC->WriterVideoStream.decoderSpecificInfo = 6703 (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo); 6704 6705 /** 6706 * Update Encoder Header properties for Video stream if needed */ 6707 if( M4ENCODER_kH263 == pC->EncodingVideoFormat ) 6708 { 6709 /** 6710 * Creates the H263 DSI */ 6711 pC->WriterVideoStreamInfo.Header.Size = 6712 7; /**< H263 output DSI is always 7 bytes */ 6713 pDSI = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(7, M4MCS, (M4OSA_Char 6714 *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)"); 6715 6716 if( M4OSA_NULL == pDSI ) 6717 { 6718 M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\ 6719 returning M4ERR_ALLOC"); 6720 return M4ERR_ALLOC; 6721 } 6722 6723 /** 6724 * Vendor is NXP Software: N, X, P, S. */ 6725 pDSI[0] = 'N'; 6726 pDSI[1] = 'X'; 6727 pDSI[2] = 'P'; 6728 pDSI[3] = 'S'; 6729 6730 /** 6731 * Decoder version is 0 */ 6732 pDSI[4] = 0; 6733 6734 /** 6735 * Level is the sixth byte of the DSI. */ 6736 switch( pC->EncodingWidth ) 6737 { 6738 case M4ENCODER_SQCIF_Width: 6739 case M4ENCODER_QCIF_Width: 6740 if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS) 6741 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6742 { 6743 pDSI[5] = 10; 6744 } 6745 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6746 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6747 { 6748 pDSI[5] = 45; 6749 } 6750 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6751 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6752 { 6753 pDSI[5] = 20; 6754 } 6755 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) 6756 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6757 { 6758 pDSI[5] = 30; 6759 } 6760 else if( ( pC->uiEncVideoBitrate 6761 <= M4ENCODER_k800_KBPS/*2048*/) 6762 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6763 { 6764 pDSI[5] = 40; 6765 } 6766 break; 6767 6768 case M4ENCODER_CIF_Width: 6769 if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6770 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6771 { 6772 pDSI[5] = 20; 6773 } 6774 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) 6775 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6776 { 6777 pDSI[5] = 30; 6778 } 6779 else if( ( pC->uiEncVideoBitrate 6780 <= M4ENCODER_k800_KBPS/*2048*/) 6781 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6782 { 6783 pDSI[5] = 40; 6784 } 6785 break; 6786 6787 default: 6788 break; 6789 } 6790 6791 /** 6792 * Profile is the seventh byte of the DSI. */ 6793 pDSI[6] = 0; 6794 6795 pC->WriterVideoStreamInfo.Header.pBuf = pDSI; 6796 } 6797 else if( M4ENCODER_kNULL == pC->EncodingVideoFormat ) 6798 { 6799 /* If we copy the stream from the input, we copy its DSI */ 6800 6801 pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream-> 6802 m_basicProperties.m_decoderSpecificInfoSize; 6803 pC->WriterVideoStreamInfo.Header.pBuf = 6804 (M4OSA_MemAddr8)pC->pReaderVideoStream-> 6805 m_basicProperties.m_pDecoderSpecificInfo; 6806 6807 } 6808 /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */ 6809 6810 /*+CRLV6775 - H.264 Trimming */ 6811 if( pC->bH264Trim == M4OSA_TRUE ) 6812 { 6813 bMULPPSSPS = M4OSA_TRUE; 6814 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6815 (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS, 6816 (M4OSA_DataOption) &bMULPPSSPS); 6817 6818 if( ( M4NO_ERROR != err) 6819 && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6820 != err) ) /* this option may not be implemented by some writers */ 6821 { 6822 M4OSA_TRACE1_1( 6823 "M4MCS_intPrepareWriter:\ 6824 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x", 6825 err); 6826 return err; 6827 } 6828 } 6829 /*-CRLV6775 - H.264 Trimming */ 6830 /** 6831 * Add the video stream */ 6832 err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, 6833 &pC->WriterVideoStream); 6834 6835 if( M4NO_ERROR != err ) 6836 { 6837 M4OSA_TRACE1_1( 6838 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", 6839 err); 6840 return err; 6841 } 6842 6843 /** 6844 * Update AU properties for video stream */ 6845 pC->WriterVideoAU.stream = &(pC->WriterVideoStream); 6846 pC->WriterVideoAU.dataAddress = M4OSA_NULL; 6847 pC->WriterVideoAU.size = 0; 6848 pC->WriterVideoAU.CTS = 0; /** Reset time */ 6849 pC->WriterVideoAU.DTS = 0; 6850 pC->WriterVideoAU.attribute = AU_RAP; 6851 pC->WriterVideoAU.nbFrag = 0; /** No fragment */ 6852 pC->WriterVideoAU.frag = M4OSA_NULL; 6853 6854 /** 6855 * Set the writer max video AU size */ 6856 optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 6857 optionValue.value = pC->uiVideoMaxAuSize; 6858 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6859 (M4OSA_UInt32)M4WRITER_kMaxAUSize, 6860 (M4OSA_DataOption) &optionValue); 6861 6862 if( M4NO_ERROR != err ) 6863 { 6864 M4OSA_TRACE1_1( 6865 "M4MCS_intPrepareWriter: \ 6866 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 6867 err); 6868 return err; 6869 } 6870 6871 /** 6872 * Set the writer max video chunk size */ 6873 optionValue.value = pC->uiVideoMaxChunckSize; 6874 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6875 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 6876 (M4OSA_DataOption) &optionValue); 6877 6878 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6879 != err) ) /* this option may not be implemented by some writers */ 6880 { 6881 M4OSA_TRACE1_1( 6882 "M4MCS_intPrepareWriter:\ 6883 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 6884 err); 6885 return err; 6886 } 6887 } 6888 6889 /** 6890 * If there is an audio input, allocate and fill the audio stream structures for the writer */ 6891 if( pC->noaudio == M4OSA_FALSE ) 6892 { 6893 M4WRITER_StreamAudioInfos streamAudioInfo; 6894 6895 streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ 6896 streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ 6897 streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ 6898 6899 pC->WriterAudioStream.averageBitrate = 6900 0; /**< It is not used by the shell, the DSI is taken into account instead */ 6901 pC->WriterAudioStream.maxBitrate = 6902 0; /**< Not used by the shell/core writer */ 6903 6904 /** 6905 * Fill Audio stream description structure for the AddStream method */ 6906 switch( pC->AudioEncParams.Format ) 6907 { 6908 case M4ENCODER_kAMRNB: 6909 pC->WriterAudioStream.streamType = M4SYS_kAMR; 6910 break; 6911 6912 case M4ENCODER_kAAC: 6913 pC->WriterAudioStream.streamType = M4SYS_kAAC; 6914 pC->WriterAudioStream.averageBitrate = 6915 pC->AudioEncParams.Bitrate; 6916 pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate; 6917 break; 6918 6919 /*FlB 26.02.2009: add mp3 as output format*/ 6920 case M4ENCODER_kMP3: 6921 pC->WriterAudioStream.streamType = M4SYS_kMP3; 6922 break; 6923 6924 case M4ENCODER_kAudioNULL: 6925 switch( pC->InputFileProperties.AudioStreamType ) 6926 { 6927 case M4VIDEOEDITING_kAMR_NB: 6928 pC->WriterAudioStream.streamType = M4SYS_kAMR; 6929 break; 6930 /*FlB 26.02.2009: add mp3 as output format*/ 6931 case M4VIDEOEDITING_kMP3: 6932 pC->WriterAudioStream.streamType = M4SYS_kMP3; 6933 break; 6934 6935 case M4VIDEOEDITING_kAAC: 6936 case M4VIDEOEDITING_kAACplus: 6937 case M4VIDEOEDITING_keAACplus: 6938 pC->WriterAudioStream.streamType = M4SYS_kAAC; 6939 pC->WriterAudioStream.averageBitrate = 6940 pC->AudioEncParams.Bitrate; 6941 pC->WriterAudioStream.maxBitrate = 6942 pC->AudioEncParams.Bitrate; 6943 break; 6944 6945 case M4VIDEOEDITING_kEVRC: 6946 pC->WriterAudioStream.streamType = M4SYS_kEVRC; 6947 break; 6948 6949 case M4VIDEOEDITING_kNoneAudio: 6950 case M4VIDEOEDITING_kPCM: 6951 case M4VIDEOEDITING_kNullAudio: 6952 case M4VIDEOEDITING_kUnsupportedAudio: 6953 break; 6954 } 6955 break; 6956 6957 default: /**< It should never happen, already tested */ 6958 M4OSA_TRACE1_1( 6959 "M4MCS_intPrepareWriter: \ 6960 unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 6961 pC->AudioEncParams.Format); 6962 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 6963 } 6964 6965 /** 6966 * MCS produces only AMR-NB output */ 6967 pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; 6968 pC->WriterAudioStream.duration = 6969 0; /**< Not used by the shell/core writer */ 6970 pC->WriterAudioStream.profileLevel = 6971 0; /**< Not used by the shell/core writer */ 6972 pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency; 6973 6974 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 6975 { 6976 /* If we copy the stream from the input, we copy its DSI */ 6977 streamAudioInfo.Header.Size = pC->pReaderAudioStream-> 6978 m_basicProperties.m_decoderSpecificInfoSize; 6979 streamAudioInfo.Header.pBuf = 6980 (M4OSA_MemAddr8)pC->pReaderAudioStream-> 6981 m_basicProperties.m_pDecoderSpecificInfo; 6982 } 6983 else 6984 { 6985 if( pC->pAudioEncDSI.pInfo != M4OSA_NULL ) 6986 { 6987 /* Use the DSI given by the encoder open() */ 6988 streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize; 6989 streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo; 6990 } 6991 else 6992 { 6993 /* Writer will put a default Philips DSI */ 6994 streamAudioInfo.Header.Size = 0; 6995 streamAudioInfo.Header.pBuf = M4OSA_NULL; 6996 } 6997 } 6998 6999 /** 7000 * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos 7001 in the DSI pointer... */ 7002 pC->WriterAudioStream.decoderSpecificInfo = 7003 (M4OSA_MemAddr32) &streamAudioInfo; 7004 7005 /** 7006 * Add the audio stream to the writer */ 7007 err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, 7008 &pC->WriterAudioStream); 7009 7010 if( M4NO_ERROR != err ) 7011 { 7012 M4OSA_TRACE1_1( 7013 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x", 7014 err); 7015 return err; 7016 } 7017 7018 /** 7019 * Link the AU and the stream */ 7020 pC->WriterAudioAU.stream = &(pC->WriterAudioStream); 7021 pC->WriterAudioAU.dataAddress = M4OSA_NULL; 7022 pC->WriterAudioAU.size = 0; 7023 pC->WriterAudioAU.CTS = 0; /** Reset time */ 7024 pC->WriterAudioAU.DTS = 0; 7025 pC->WriterAudioAU.attribute = 0; 7026 pC->WriterAudioAU.nbFrag = 0; /** No fragment */ 7027 pC->WriterAudioAU.frag = M4OSA_NULL; 7028 7029 /** 7030 * Set the writer audio max AU size */ 7031 /* As max bitrate is now 320kbps instead of 128kbps, max AU 7032 * size has to be increased adapt the max AU size according to the stream type and the 7033 * channels numbers*/ 7034 /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite) 7035 */ 7036 //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE; 7037 switch( pC->WriterAudioStream.streamType ) 7038 { 7039 case M4SYS_kAMR: 7040 pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES 7041 * (( pC->InputFileProperties.uiNbChannels 7042 * sizeof(short)) + 3); 7043 break; 7044 7045 case M4SYS_kMP3: 7046 pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES 7047 * (( pC->InputFileProperties.uiNbChannels 7048 * sizeof(short)) + 3); 7049 break; 7050 7051 case M4SYS_kAAC: 7052 pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES 7053 * (( pC->InputFileProperties.uiNbChannels 7054 * sizeof(short)) + 3); 7055 break; 7056 /*case M4SYS_kEVRC: 7057 pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES* 7058 ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3); 7059 break;*/ 7060 default: /**< It should never happen, already tested */ 7061 M4OSA_TRACE1_1( 7062 "M4MCS_intPrepareWriter: unknown format (0x%x),\ 7063 returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 7064 pC->WriterAudioStream.streamType); 7065 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 7066 } 7067 7068 optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; 7069 optionValue.value = pC->uiAudioMaxAuSize; 7070 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7071 (M4OSA_UInt32)M4WRITER_kMaxAUSize, 7072 (M4OSA_DataOption) &optionValue); 7073 7074 if( M4NO_ERROR != err ) 7075 { 7076 M4OSA_TRACE1_1( 7077 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ 7078 M4WRITER_kMaxAUSize) returns 0x%x", 7079 err); 7080 return err; 7081 } 7082 7083 optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE; 7084 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7085 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 7086 (M4OSA_DataOption) &optionValue); 7087 7088 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 7089 != err) ) /* this option may not be implemented by some writers */ 7090 { 7091 M4OSA_TRACE1_1( 7092 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ 7093 M4WRITER_kMaxChunckSize) returns 0x%x", 7094 err); 7095 return err; 7096 } 7097 } 7098 7099 /* 7100 * Set the limitation size of the writer */ 7101 TargetedFileSize = pC->uiMaxFileSize; 7102 /* add 1 kB margin */ 7103 if( TargetedFileSize > 8192 ) 7104 TargetedFileSize -= 1024; 7105 7106 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7107 (M4OSA_UInt32)M4WRITER_kMaxFileSize, 7108 (M4OSA_DataOption) &TargetedFileSize); 7109 7110 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 7111 != err) ) /* this option may not be implemented by some writers */ 7112 { 7113 M4OSA_TRACE1_1( 7114 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\ 7115 (M4WRITER_kMaxFileSize) returns 0x%x!", 7116 err); 7117 return err; 7118 } 7119 7120 /** 7121 * Close the stream registering in order to be ready to write data */ 7122 err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext); 7123 7124 if( M4NO_ERROR != err ) 7125 { 7126 M4OSA_TRACE1_1( 7127 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x", 7128 err); 7129 return err; 7130 } 7131 7132 /** 7133 * Return with no error */ 7134 M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR"); 7135 return M4NO_ERROR; 7136 } 7137 7138 /** 7139 ****************************************************************************** 7140 * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC); 7141 * @brief DO the audio begin cut. 7142 * @param pC (IN) MCS private context 7143 * @return M4NO_ERROR No error 7144 * @return Any error returned by an underlaying module 7145 ****************************************************************************** 7146 */ 7147 static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC ) 7148 { 7149 M4OSA_ERR err; 7150 M4OSA_Int32 iCts; 7151 M4OSA_UInt32 uiFrameSize; 7152 7153 if( pC->noaudio ) 7154 return M4NO_ERROR; 7155 7156 /** 7157 * Check if an audio begin cut is needed */ 7158 if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) ) 7159 { 7160 /** 7161 * Return with no error */ 7162 M4OSA_TRACE3_0( 7163 "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)"); 7164 return M4NO_ERROR; 7165 } 7166 7167 /** 7168 * Jump at the begin cut time */ 7169 iCts = pC->uiBeginCutTime; 7170 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 7171 (M4_StreamHandler *)pC->pReaderAudioStream, &iCts); 7172 7173 if( M4NO_ERROR != err ) 7174 { 7175 M4OSA_TRACE1_1( 7176 "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!", 7177 err); 7178 return err; 7179 } 7180 7181 /** 7182 * Remember audio begin cut offset */ 7183 pC->iAudioCtsOffset = iCts; 7184 7185 /** 7186 * AMR-NB & EVRC: there may be many frames per AU. 7187 * In that case we need to slice the first AU to keep the 20 ms cut precision */ 7188 if( ( M4DA_StreamTypeAudioAmrNarrowBand 7189 == pC->pReaderAudioStream->m_basicProperties.m_streamType) 7190 || (M4DA_StreamTypeAudioEvrc 7191 == pC->pReaderAudioStream->m_basicProperties.m_streamType) ) 7192 { 7193 /** 7194 * If the next frame CTS is lower than the begin cut time, 7195 * we must read the AU and parse its frames to reach the 7196 * nearest to the begin cut */ 7197 if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime ) 7198 { 7199 /** 7200 * Read the first audio AU after the jump */ 7201 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7202 (M4_StreamHandler *)pC->pReaderAudioStream, 7203 &pC->ReaderAudioAU); 7204 7205 if( M4WAR_NO_MORE_AU == err ) 7206 { 7207 M4OSA_TRACE1_0( 7208 "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\ 7209 returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR"); 7210 return 7211 M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ 7212 } 7213 else if( M4NO_ERROR != err ) 7214 { 7215 M4OSA_TRACE1_1( 7216 "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\ 7217 returns 0x%x", 7218 err); 7219 return err; 7220 } 7221 7222 /** 7223 * While the next AU has a lower CTS than the begin cut time, we advance to 7224 the next frame */ 7225 while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime ) 7226 { 7227 /** 7228 * Get the size of the frame */ 7229 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) 7230 { 7231 case M4DA_StreamTypeAudioAmrNarrowBand: 7232 uiFrameSize = M4MCS_intGetFrameSize_AMRNB( 7233 pC->ReaderAudioAU.m_dataAddress); 7234 break; 7235 7236 case M4DA_StreamTypeAudioEvrc: 7237 uiFrameSize = M4MCS_intGetFrameSize_EVRC( 7238 pC->ReaderAudioAU.m_dataAddress); 7239 break; 7240 7241 default: 7242 uiFrameSize = 0; 7243 break; 7244 } 7245 7246 if( 0 == uiFrameSize ) 7247 { 7248 /** 7249 * Corrupted frame! We get out of this mess! 7250 * We don't want to crash here... */ 7251 M4OSA_TRACE1_0( 7252 "M4MCS_intPrepareAudioBeginCut(): \ 7253 M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR"); 7254 return 7255 M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ 7256 } 7257 7258 /** 7259 * Go to the next frame */ 7260 pC->ReaderAudioAU.m_dataAddress += uiFrameSize; 7261 pC->ReaderAudioAU.m_size -= uiFrameSize; 7262 7263 /** 7264 * Get the CTS of the next frame */ 7265 iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */ 7266 pC->ReaderAudioAU.m_CTS = iCts; 7267 pC->ReaderAudioAU.m_DTS = iCts; 7268 } 7269 7270 /** 7271 * Update the audio begin cut offset */ 7272 pC->iAudioCtsOffset = iCts; 7273 } 7274 } 7275 7276 /** 7277 * Return with no error */ 7278 M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR"); 7279 return M4NO_ERROR; 7280 } 7281 7282 /** 7283 ****************************************************************************** 7284 * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress) 7285 ****************************************************************************** 7286 */ 7287 static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC, 7288 M4OSA_UInt8 *pProgress ) 7289 { 7290 M4OSA_ERR err; 7291 M4OSA_UInt32 uiAudioStepCount = 0; 7292 7293 /* ---------- VIDEO TRANSCODING ---------- */ 7294 7295 if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED 7296 == pC->VideoState) ) /**< If the video encoding is going on */ 7297 { 7298 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 7299 { 7300 err = M4MCS_intVideoNullEncoding(pC); 7301 } 7302 else 7303 { 7304 err = M4MCS_intVideoTranscoding(pC); 7305 } 7306 7307 /** 7308 * No more space, quit properly */ 7309 if( M4WAR_WRITER_STOP_REQ == err ) 7310 { 7311 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts 7312 - pC->uiBeginCutTime) * 100) 7313 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7314 7315 pC->State = M4MCS_kState_FINISHED; 7316 7317 /* bad file produced on very short 3gp file */ 7318 if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 ) 7319 { 7320 /* Nothing has been encoded -> bad produced file -> error returned */ 7321 M4OSA_TRACE2_0( 7322 "M4MCS_intStepEncoding(): video transcoding returns\ 7323 M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); 7324 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; 7325 } 7326 else 7327 { 7328 #ifndef M4MCS_AUDIOONLY 7329 /* clean AIR context needed to keep media aspect ratio*/ 7330 7331 if( M4OSA_NULL != pC->m_air_context ) 7332 { 7333 err = M4AIR_cleanUp(pC->m_air_context); 7334 7335 if( err != M4NO_ERROR ) 7336 { 7337 M4OSA_TRACE1_1( 7338 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7339 err); 7340 return err; 7341 } 7342 pC->m_air_context = M4OSA_NULL; 7343 } 7344 7345 #endif /*M4MCS_AUDIOONLY*/ 7346 7347 M4OSA_TRACE2_0( 7348 "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE"); 7349 return M4MCS_ERR_NOMORE_SPACE; 7350 } 7351 } 7352 7353 /**< The input plane is null because the input image will be obtained by the 7354 VPP filter from the context */ 7355 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) ) 7356 { 7357 M4OSA_TRACE1_1( 7358 "M4MCS_intStepEncoding(): video transcoding returns 0x%x!", 7359 err); 7360 return err; 7361 } 7362 } 7363 7364 /* ---------- AUDIO TRANSCODING ---------- */ 7365 7366 if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED 7367 == pC->AudioState) ) /**< If there is an audio stream */ 7368 { 7369 while( 7370 /**< If the video encoding is running, encode audio until we reach video time */ 7371 ( ( pC->novideo == M4OSA_FALSE) 7372 && (M4MCS_kStreamState_STARTED == pC->VideoState) 7373 && (pC->ReaderAudioAU.m_CTS 7374 + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) || 7375 /**< If the video encoding is not running, perform 1 step of audio encoding */ 7376 (( M4MCS_kStreamState_STARTED == pC->AudioState) 7377 && (uiAudioStepCount < 1)) ) 7378 { 7379 uiAudioStepCount++; 7380 7381 /**< check if an adio effect has to be applied*/ 7382 err = M4MCS_intCheckAudioEffects(pC); 7383 7384 if( M4NO_ERROR != err ) 7385 { 7386 M4OSA_TRACE1_1( 7387 "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x", 7388 err); 7389 return err; 7390 } 7391 7392 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 7393 { 7394 err = M4MCS_intAudioNullEncoding(pC); 7395 } 7396 else /**< Audio transcoding */ 7397 { 7398 err = M4MCS_intAudioTranscoding(pC); 7399 } 7400 7401 /** 7402 * No more space, quit properly */ 7403 if( M4WAR_WRITER_STOP_REQ == err ) 7404 { 7405 *pProgress = 7406 (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7407 - pC->uiBeginCutTime) * 100) 7408 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7409 7410 pC->State = M4MCS_kState_FINISHED; 7411 7412 /* bad file produced on very short 3gp file */ 7413 if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 ) 7414 { 7415 /* Nothing has been encoded -> bad produced file -> error returned */ 7416 M4OSA_TRACE2_0( 7417 "M4MCS_intStepEncoding():\ 7418 audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); 7419 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; 7420 } 7421 else 7422 { 7423 #ifndef M4MCS_AUDIOONLY 7424 /* clean AIR context needed to keep media aspect ratio*/ 7425 7426 if( M4OSA_NULL != pC->m_air_context ) 7427 { 7428 err = M4AIR_cleanUp(pC->m_air_context); 7429 7430 if( err != M4NO_ERROR ) 7431 { 7432 M4OSA_TRACE1_1( 7433 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7434 err); 7435 return err; 7436 } 7437 pC->m_air_context = M4OSA_NULL; 7438 } 7439 7440 #endif /*M4MCS_AUDIOONLY*/ 7441 7442 M4OSA_TRACE2_0( 7443 "M4MCS_intStepEncoding(): \ 7444 audio transcoding returns M4MCS_ERR_NOMORE_SPACE"); 7445 return M4MCS_ERR_NOMORE_SPACE; 7446 } 7447 } 7448 7449 if( M4WAR_NO_MORE_AU == err ) 7450 { 7451 pC->AudioState = M4MCS_kStreamState_FINISHED; 7452 M4OSA_TRACE3_0( 7453 "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU"); 7454 break; 7455 } 7456 else if( M4NO_ERROR != err ) 7457 { 7458 M4OSA_TRACE1_1( 7459 "M4MCS_intStepEncoding(): audio transcoding returns 0x%x", 7460 err); 7461 return err; 7462 } 7463 7464 /** 7465 * Check for end cut */ 7466 /* We absolutely want to have less or same audio duration as video -> 7467 (2*pC->m_audioAUDuration) */ 7468 if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7469 + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime ) 7470 { 7471 pC->AudioState = M4MCS_kStreamState_FINISHED; 7472 break; 7473 } 7474 } 7475 } 7476 7477 /* ---------- PROGRESS MANAGEMENT ---------- */ 7478 7479 /** 7480 * Compute progress */ 7481 if( pC->novideo ) 7482 { 7483 if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime ) 7484 { 7485 *pProgress = 0; 7486 } 7487 else 7488 { 7489 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7490 - pC->uiBeginCutTime) * 100) 7491 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7492 } 7493 //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS); 7494 7495 } 7496 else 7497 { 7498 if( pC->dViDecCurrentCts < pC->uiBeginCutTime ) 7499 { 7500 *pProgress = 0; 7501 } 7502 else 7503 { 7504 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts 7505 - pC->uiBeginCutTime) * 100) 7506 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7507 } 7508 //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts); 7509 } 7510 7511 /** 7512 * Sanity check */ 7513 if( *pProgress > 99 ) 7514 { 7515 *pProgress = 99; 7516 } 7517 7518 /** 7519 * Increment CTS for next step */ 7520 if( pC->novideo == M4OSA_FALSE ) 7521 { 7522 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 7523 { 7524 pC->dViDecCurrentCts += 1; 7525 } 7526 else 7527 { 7528 pC->dViDecCurrentCts += pC->dCtsIncrement; 7529 } 7530 } 7531 7532 /** 7533 * The transcoding is finished when no stream is being encoded anymore */ 7534 if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState)) 7535 && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) ) 7536 { 7537 /* the AIR part can only be used when video codecs are compiled*/ 7538 #ifndef M4MCS_AUDIOONLY 7539 /* clean AIR context needed to keep media aspect ratio*/ 7540 7541 if( M4OSA_NULL != pC->m_air_context ) 7542 { 7543 err = M4AIR_cleanUp(pC->m_air_context); 7544 7545 if( err != M4NO_ERROR ) 7546 { 7547 M4OSA_TRACE1_1( 7548 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7549 err); 7550 return err; 7551 } 7552 pC->m_air_context = M4OSA_NULL; 7553 } 7554 7555 #endif /*M4MCS_AUDIOONLY*/ 7556 /**/ 7557 7558 *pProgress = 100; 7559 pC->State = M4MCS_kState_FINISHED; 7560 M4OSA_TRACE2_0( 7561 "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE"); 7562 return M4MCS_WAR_TRANSCODING_DONE; 7563 } 7564 7565 /** 7566 * Return with no error */ 7567 M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR"); 7568 return M4NO_ERROR; 7569 } 7570 7571 /** 7572 ****************************************************************************** 7573 * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC) 7574 ****************************************************************************** 7575 */ 7576 static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC ) 7577 { 7578 M4OSA_ERR err; 7579 M4OSA_Int32 iCts; 7580 7581 if( pC->novideo ) 7582 { 7583 pC->State = M4MCS_kState_BEGINVIDEODECODE; 7584 return M4NO_ERROR; 7585 } 7586 7587 /** 7588 * Jump to the previous RAP in the clip (first get the time, then jump) */ 7589 iCts = (M4OSA_Int32)pC->dViDecStartingCts; 7590 err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext, 7591 (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); 7592 7593 if( M4WAR_READER_INFORMATION_NOT_PRESENT == err ) 7594 { 7595 /* No RAP table, jump backward and predecode */ 7596 iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT; 7597 7598 if( iCts < 0 ) 7599 iCts = 0; 7600 } 7601 else if( M4NO_ERROR != err ) 7602 { 7603 M4OSA_TRACE1_1( 7604 "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!", 7605 err); 7606 return err; 7607 } 7608 7609 /* + CRLV6775 -H.264 Trimming */ 7610 7611 if( M4OSA_TRUE == pC->bH264Trim ) 7612 { 7613 7614 // Save jump time for safety, this fix should be generic 7615 7616 M4OSA_Int32 iCtsOri = iCts; 7617 7618 7619 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 7620 (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); 7621 7622 if( M4NO_ERROR != err ) 7623 { 7624 M4OSA_TRACE1_1( 7625 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", 7626 err); 7627 return err; 7628 } 7629 7630 if( pC->ReaderVideoAU1.m_structSize == 0 ) 7631 { 7632 /** 7633 * Initializes an access Unit */ 7634 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7635 (M4_StreamHandler *)pC->pReaderVideoStream, 7636 &pC->ReaderVideoAU1); 7637 7638 if( M4NO_ERROR != err ) 7639 { 7640 M4OSA_TRACE1_1( 7641 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 7642 err); 7643 return err; 7644 } 7645 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7646 (M4_StreamHandler *)pC->pReaderVideoStream, 7647 &pC->ReaderVideoAU1); 7648 7649 if( M4WAR_NO_MORE_AU == err ) 7650 { 7651 M4OSA_TRACE2_0( 7652 "M4MCS_intVideoNullEncoding(): \ 7653 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 7654 /* The audio transcoding is finished */ 7655 pC->VideoState = M4MCS_kStreamState_FINISHED; 7656 return err; 7657 } 7658 else if( M4NO_ERROR != err ) 7659 { 7660 M4OSA_TRACE1_1( 7661 "M4MCS_intVideoNullEncoding():\ 7662 m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", 7663 err); 7664 return err; 7665 } 7666 7667 pC->ReaderVideoAU1.m_structSize = 0; 7668 } 7669 7670 err = H264MCS_ProcessSPS_PPS(pC->m_pInstance, 7671 (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size); 7672 7673 if( M4NO_ERROR != err ) 7674 { 7675 M4OSA_TRACE1_1( 7676 "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!", 7677 err); 7678 return err; 7679 } 7680 7681 7682 // Restore jump time for safety, this fix should be generic 7683 7684 iCts = iCtsOri; 7685 7686 7687 } 7688 /* - CRLV6775 -H.264 Trimming */ 7689 7690 /** 7691 * Decode one step */ 7692 pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr); 7693 7694 /** 7695 * Be sure we don't decode too far */ 7696 if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) 7697 { 7698 pC->dViDecCurrentCts = pC->dViDecStartingCts; 7699 } 7700 7701 /** 7702 * Decode at least once with the bJump flag to true */ 7703 M4OSA_TRACE3_1( 7704 "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f", 7705 pC->dViDecCurrentCts); 7706 pC->isRenderDup = M4OSA_FALSE; 7707 err = 7708 pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts, 7709 M4OSA_TRUE, 0); 7710 7711 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) 7712 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) 7713 { 7714 M4OSA_TRACE1_1( 7715 "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err); 7716 return err; 7717 } 7718 7719 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 7720 { 7721 M4OSA_TRACE2_0("Decoding output the same frame as before 1"); 7722 pC->isRenderDup = M4OSA_TRUE; 7723 } 7724 7725 /** 7726 * Increment decoding cts for the next step */ 7727 pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; 7728 7729 /** 7730 * Update state automaton */ 7731 if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) 7732 { 7733 /** 7734 * Be sure we don't decode too far */ 7735 pC->dViDecCurrentCts = pC->dViDecStartingCts; 7736 pC->State = M4MCS_kState_PROCESSING; 7737 } 7738 else 7739 { 7740 pC->State = M4MCS_kState_BEGINVIDEODECODE; 7741 } 7742 7743 /** 7744 * Return with no error */ 7745 M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR"); 7746 return M4NO_ERROR; 7747 } 7748 7749 /** 7750 ****************************************************************************** 7751 * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC) 7752 ****************************************************************************** 7753 */ 7754 static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC ) 7755 { 7756 M4OSA_ERR err; 7757 M4_MediaTime dDecTarget; 7758 7759 if( pC->novideo ) 7760 { 7761 pC->State = M4MCS_kState_PROCESSING; 7762 return M4NO_ERROR; 7763 } 7764 7765 /** 7766 * Decode */ 7767 dDecTarget = pC->dViDecCurrentCts; 7768 M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f", 7769 pC->dViDecCurrentCts); 7770 pC->isRenderDup = M4OSA_FALSE; 7771 err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget, 7772 M4OSA_FALSE, 0); 7773 7774 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) 7775 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) 7776 { 7777 M4OSA_TRACE1_1( 7778 "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err); 7779 return err; 7780 } 7781 7782 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 7783 { 7784 M4OSA_TRACE2_0("Decoding output the same frame as before 2"); 7785 pC->isRenderDup = M4OSA_TRUE; 7786 } 7787 7788 /** 7789 * Increment decoding cts for the next step */ 7790 pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; 7791 7792 /** 7793 * Update state automaton, if needed */ 7794 if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts) 7795 || (M4WAR_NO_MORE_AU == err) ) 7796 { 7797 /** 7798 * Be sure we don't decode too far */ 7799 pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts; 7800 pC->State = M4MCS_kState_PROCESSING; 7801 } 7802 7803 /** 7804 * Return with no error */ 7805 M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR"); 7806 return M4NO_ERROR; 7807 } 7808 7809 /*****************************/ 7810 /* define AMR silence frames */ 7811 /*****************************/ 7812 7813 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13 7814 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160 7815 7816 #ifdef M4VSS3GPP_SILENCE_FRAMES 7817 7818 const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[ 7819 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] = 7820 { 7821 0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00 7822 }; 7823 #else 7824 7825 extern 7826 const 7827 M4OSA_UInt8 7828 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE]; 7829 7830 #endif 7831 7832 /*****************************/ 7833 /* define AAC silence frames */ 7834 /*****************************/ 7835 7836 #define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE 4 7837 7838 #ifdef M4VSS3GPP_SILENCE_FRAMES 7839 7840 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[ 7841 M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] = 7842 { 7843 0x00, 0xC8, 0x20, 0x07 7844 }; 7845 #else 7846 7847 extern const M4OSA_UInt8 7848 M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE]; 7849 7850 #endif 7851 7852 #define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE 6 7853 7854 #ifdef M4VSS3GPP_SILENCE_FRAMES 7855 7856 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[ 7857 M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] = 7858 { 7859 0x21, 0x10, 0x03, 0x20, 0x54, 0x1C 7860 }; 7861 #else 7862 7863 extern const 7864 M4OSA_UInt8 7865 M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE]; 7866 7867 #endif 7868 7869 /** 7870 ****************************************************************************** 7871 * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC) 7872 * @return M4NO_ERROR: No error 7873 ****************************************************************************** 7874 */ 7875 7876 static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC ) 7877 { 7878 M4OSA_ERR err; 7879 7880 if( pC->noaudio ) 7881 return M4NO_ERROR; 7882 7883 /* Check if all audio frame has been written (happens at begin cut) */ 7884 if( pC->ReaderAudioAU.m_size == 0 ) 7885 { 7886 /** 7887 * Initializes a new AU if needed */ 7888 if( pC->ReaderAudioAU1.m_structSize == 0 ) 7889 { 7890 /** 7891 * Initializes an access Unit */ 7892 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7893 (M4_StreamHandler *)pC->pReaderAudioStream, 7894 &pC->ReaderAudioAU1); 7895 7896 if( M4NO_ERROR != err ) 7897 { 7898 M4OSA_TRACE1_1( 7899 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 7900 err); 7901 return err; 7902 } 7903 7904 pC->m_pDataAddress1 = 7905 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU1.m_maxsize, 7906 M4MCS, (M4OSA_Char *)"Temporary AU1 buffer"); 7907 7908 if( pC->m_pDataAddress1 == M4OSA_NULL ) 7909 { 7910 M4OSA_TRACE1_0( 7911 "M4MCS_intAudioNullEncoding(): allocation error"); 7912 return M4ERR_ALLOC; 7913 } 7914 7915 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7916 (M4_StreamHandler *)pC->pReaderAudioStream, 7917 &pC->ReaderAudioAU1); 7918 7919 if( M4WAR_NO_MORE_AU == err ) 7920 { 7921 M4OSA_TRACE2_0( 7922 "M4MCS_intAudioNullEncoding():\ 7923 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 7924 /* The audio transcoding is finished */ 7925 pC->AudioState = M4MCS_kStreamState_FINISHED; 7926 return err; 7927 } 7928 else if( M4NO_ERROR != err ) 7929 { 7930 M4OSA_TRACE1_1( 7931 "M4MCS_intAudioNullEncoding(): \ 7932 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", 7933 err); 7934 return err; 7935 } 7936 /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying , 7937 constant memory reader case*/ 7938 if( pC->ReaderAudioAU1.m_maxsize 7939 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) 7940 { 7941 /* Constant memory reader case, we need to reallocate the temporary buffers */ 7942 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 7943 *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize); 7944 /* pC->m_pDataAddress1 and 7945 pC->m_pDataAddress2 must be reallocated at the same time */ 7946 /* because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take 7947 maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > 7948 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true */ 7949 /* and the size of the second buffer is never changed. */ 7950 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 7951 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); 7952 /* pC->m_pDataAddress1 and 7953 pC->m_pDataAddress2 must be reallocated at the same time */ 7954 /* Update stream properties */ 7955 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 7956 pC->ReaderAudioAU1.m_maxsize; 7957 } 7958 /**/ 7959 memcpy((void *)pC->m_pDataAddress1, 7960 (void *)pC->ReaderAudioAU1.m_dataAddress, 7961 pC->ReaderAudioAU1.m_size); 7962 } 7963 7964 if( pC->ReaderAudioAU2.m_structSize == 0 ) 7965 { 7966 /** 7967 * Initializes an access Unit */ 7968 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7969 (M4_StreamHandler *)pC->pReaderAudioStream, 7970 &pC->ReaderAudioAU2); 7971 7972 if( M4NO_ERROR != err ) 7973 { 7974 M4OSA_TRACE1_1( 7975 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 7976 err); 7977 return err; 7978 } 7979 pC->m_pDataAddress2 = 7980 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU2.m_maxsize, 7981 M4MCS, (M4OSA_Char *)"Temporary AU buffer"); 7982 7983 if( pC->m_pDataAddress2 == M4OSA_NULL ) 7984 { 7985 M4OSA_TRACE1_0( 7986 "M4MCS_intAudioNullEncoding(): allocation error"); 7987 return M4ERR_ALLOC; 7988 } 7989 } 7990 /** 7991 * Read the next audio AU in the input file */ 7992 if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS ) 7993 { 7994 memcpy((void *) &pC->ReaderAudioAU, 7995 (void *) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit)); 7996 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7997 (M4_StreamHandler *)pC->pReaderAudioStream, 7998 &pC->ReaderAudioAU1); 7999 8000 if( pC->ReaderAudioAU1.m_maxsize 8001 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) 8002 { 8003 /* Constant memory reader case, we need to reallocate the temporary buffers */ 8004 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8005 *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize); 8006 /* pC->m_pDataAddress1 8007 * and pC->m_pDataAddress2 must be reallocated at the same time * 8008 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take 8009 * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > 8010 * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true * 8011 * and the size of the second buffer is never changed. 8012 */ 8013 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8014 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); 8015 /* pC->m_pDataAddress1 and 8016 * pC->m_pDataAddress2 must be reallocated at the same time 8017 * Update stream properties 8018 */ 8019 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 8020 pC->ReaderAudioAU1.m_maxsize; 8021 } 8022 /**/ 8023 memcpy((void *)pC->m_pDataAddress1, 8024 (void *)pC->ReaderAudioAU1.m_dataAddress, 8025 pC->ReaderAudioAU1.m_size); 8026 pC->m_audioAUDuration = 8027 pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS; 8028 pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2; 8029 } 8030 else 8031 { 8032 memcpy((void *) &pC->ReaderAudioAU, 8033 (void *) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit)); 8034 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8035 (M4_StreamHandler *)pC->pReaderAudioStream, 8036 &pC->ReaderAudioAU2); 8037 /* Crash in MCS while Audio AU copying , 8038 * constant memory reader case 8039 */ 8040 if( pC->ReaderAudioAU2.m_maxsize 8041 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) 8042 { 8043 /* Constant memory reader case, we need to reallocate the temporary buffers */ 8044 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8045 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize); 8046 /* pC->m_pDataAddress1 and 8047 * pC->m_pDataAddress2 must be reallocated at the same time 8048 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum 8049 * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream-> 8050 * m_basicProperties.m_maxAUSize)" is never true 8051 * and the size of the second buffer is never changed. 8052 */ 8053 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8054 *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize); 8055 /* [ END ] 20091008 JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and 8056 pC->m_pDataAddress2 must be reallocated at the same time */ 8057 /* Update stream properties */ 8058 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 8059 pC->ReaderAudioAU2.m_maxsize; 8060 } 8061 /**/ 8062 memcpy((void *)pC->m_pDataAddress2, 8063 (void *)pC->ReaderAudioAU2.m_dataAddress, 8064 pC->ReaderAudioAU2.m_size); 8065 pC->m_audioAUDuration = 8066 pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS; 8067 pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1; 8068 } 8069 8070 if( M4WAR_NO_MORE_AU == err ) 8071 { 8072 M4OSA_TRACE2_0( 8073 "M4MCS_intAudioNullEncoding(): \ 8074 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 8075 /* The audio transcoding is finished */ 8076 pC->AudioState = M4MCS_kStreamState_FINISHED; 8077 return err; 8078 } 8079 else if( M4NO_ERROR != err ) 8080 { 8081 M4OSA_TRACE1_1( 8082 "M4MCS_intAudioNullEncoding(): \ 8083 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", 8084 err); 8085 return err; 8086 } 8087 } 8088 8089 /** 8090 * Prepare the writer AU */ 8091 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 8092 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8093 8094 if( M4NO_ERROR != err ) 8095 { 8096 M4OSA_TRACE1_1( 8097 "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", 8098 err); 8099 return err; 8100 } 8101 8102 if( pC->uiAudioAUCount 8103 == 0 ) /* If it is the first AU, we set it to silence 8104 (else, errors 0x3841, 0x3847 in our AAC decoder) */ 8105 { 8106 if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC 8107 || pC->InputFileProperties.AudioStreamType 8108 == M4VIDEOEDITING_kAACplus 8109 || pC->InputFileProperties.AudioStreamType 8110 == M4VIDEOEDITING_keAACplus ) 8111 { 8112 if( pC->InputFileProperties.uiNbChannels == 1 ) 8113 { 8114 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; 8115 memcpy((void *)pC->WriterAudioAU.dataAddress, 8116 (void *)M4VSS3GPP_AAC_AU_SILENCE_MONO, 8117 pC->WriterAudioAU.size); 8118 } 8119 else if( pC->InputFileProperties.uiNbChannels == 2 ) 8120 { 8121 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; 8122 memcpy((void *)pC->WriterAudioAU.dataAddress, 8123 (void *)M4VSS3GPP_AAC_AU_SILENCE_STEREO, 8124 pC->WriterAudioAU.size); 8125 } 8126 else 8127 { 8128 /* Must never happen ...*/ 8129 M4OSA_TRACE1_0( 8130 "M4MCS_intAudioNullEncoding: Bad number of channels in audio input"); 8131 return M4MCS_ERR_INVALID_INPUT_FILE; 8132 } 8133 } 8134 else if( pC->InputFileProperties.AudioStreamType 8135 == M4VIDEOEDITING_kAMR_NB ) 8136 { 8137 pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; 8138 memcpy((void *)pC->WriterAudioAU.dataAddress, 8139 (void *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048, 8140 pC->WriterAudioAU.size); 8141 /* Some remaining AMR AU needs to be copied */ 8142 if( pC->ReaderAudioAU.m_size != 0 ) 8143 { 8144 /* Update Writer AU */ 8145 pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size; 8146 memcpy((void *)(pC->WriterAudioAU.dataAddress 8147 + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE), 8148 (void *)pC->ReaderAudioAU.m_dataAddress, 8149 pC->ReaderAudioAU.m_size); 8150 } 8151 } 8152 else 8153 { 8154 /*MP3 case: copy the AU*/ 8155 M4OSA_TRACE3_1( 8156 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", 8157 pC->ReaderAudioAU.m_size); 8158 memcpy((void *)pC->WriterAudioAU.dataAddress, 8159 (void *)pC->ReaderAudioAU.m_dataAddress, 8160 pC->ReaderAudioAU.m_size); 8161 pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; 8162 } 8163 } 8164 else 8165 { 8166 /** 8167 * Copy audio data from reader AU to writer AU */ 8168 M4OSA_TRACE3_1( 8169 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", 8170 pC->ReaderAudioAU.m_size); 8171 memcpy((void *)pC->WriterAudioAU.dataAddress, 8172 (void *)pC->ReaderAudioAU.m_dataAddress, 8173 pC->ReaderAudioAU.m_size); 8174 pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; 8175 } 8176 8177 /** 8178 * Convert CTS unit from milliseconds to timescale */ 8179 pC->WriterAudioAU.CTS = 8180 (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset) 8181 * (pC->WriterAudioStream.timeScale / 1000.0))); 8182 8183 if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB 8184 && pC->uiAudioAUCount == 0 ) 8185 { 8186 pC->iAudioCtsOffset -= 8187 20; /* Duration of a silence AMR AU, to handle the duration of the added 8188 silence frame */ 8189 } 8190 pC->WriterAudioAU.nbFrag = 0; 8191 M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms", 8192 pC->WriterAudioAU.CTS); 8193 8194 /** 8195 * Write it to the output file */ 8196 pC->uiAudioAUCount++; 8197 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8198 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8199 8200 if( M4NO_ERROR != err ) 8201 { 8202 M4OSA_TRACE1_1( 8203 "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8204 err); 8205 return err; 8206 } 8207 8208 /* All the audio has been written */ 8209 pC->ReaderAudioAU.m_size = 0; 8210 8211 /** 8212 * Return with no error */ 8213 M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR"); 8214 return M4NO_ERROR; 8215 } 8216 8217 /** 8218 ****************************************************************************** 8219 * @brief Init Audio Transcoding 8220 * @return M4NO_ERROR: No error 8221 ****************************************************************************** 8222 */ 8223 static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) 8224 { 8225 M4OSA_ERR err; /**< General error */ 8226 8227 M4OSA_UInt32 8228 uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */ 8229 M4OSA_UInt32 8230 uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */ 8231 8232 int ssrcErr; /**< Error while ssrc processing */ 8233 M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */ 8234 M4OSA_UInt32 8235 uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */ 8236 M4OSA_MemAddr8 8237 pSsrcInput; /**< Pointer to the good buffer location for ssrc input */ 8238 M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */ 8239 M4OSA_UInt32 8240 uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */ 8241 8242 M4OSA_UInt8 8243 needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */ 8244 M4OSA_UInt32 8245 uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo 8246 <-> mono conversion is applied */ 8247 M4OSA_MemAddr8 pChannelConvertorInput = 8248 M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */ 8249 M4OSA_UInt32 uiChannelConvertorNbSamples = 8250 0; /**< Nb of pcm samples to convert in channel convertor */ 8251 M4OSA_MemAddr8 pChannelConvertorOutput = 8252 M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */ 8253 8254 M4OSA_Time 8255 frameTimeDelta; /**< Duration of the encoded (then written) data */ 8256 M4OSA_UInt32 8257 uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */ 8258 M4OSA_UInt32 8259 uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */ 8260 M4OSA_MemAddr8 8261 pEncoderInput; /**< Pointer to the good buffer location for encoder input */ 8262 M4ENCODER_AudioBuffer pEncInBuffer; /**< Encoder input buffer for api */ 8263 M4ENCODER_AudioBuffer pEncOutBuffer; /**< Encoder output buffer for api */ 8264 8265 M4OSA_Int16 *tempBuffOut = M4OSA_NULL; 8266 /*FlB 2009.03.04: apply audio effects if an effect is active*/ 8267 M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber); 8268 8269 uint32_t errCode = M4NO_ERROR; 8270 8271 if( pC->noaudio ) 8272 return M4NO_ERROR; 8273 8274 /* _________________ */ 8275 /*| |*/ 8276 /*| READ AND DECODE |*/ 8277 /*|_________________|*/ 8278 8279 /* Check if we have to empty the decoder out buffer first */ 8280 if( M4OSA_NULL != pC->pPosInDecBufferOut ) 8281 { 8282 goto m4mcs_intaudiotranscoding_feed_resampler; 8283 } 8284 8285 err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, 8286 M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE); 8287 8288 8289 if( M4NO_ERROR != err ) 8290 { 8291 M4OSA_TRACE1_1( 8292 "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x", 8293 err); 8294 return err; 8295 } 8296 8297 #ifdef MCS_DUMP_PCM_TO_FILE 8298 8299 fwrite(pC->AudioDecBufferOut.m_dataAddress, 8300 pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder); 8301 8302 #endif 8303 8304 pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, 8305 M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode); 8306 8307 if ( M4WAR_NO_MORE_AU == errCode ) { 8308 pC->AudioState = M4MCS_kStreamState_FINISHED; 8309 M4OSA_TRACE2_0( 8310 "M4MCS_intAudioTranscoding():\ 8311 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 8312 return errCode; 8313 } 8314 8315 /* Set the current position in the decoder out buffer */ 8316 pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress; 8317 8318 /* ________________ */ 8319 /*| |*/ 8320 /*| FEED RESAMPLER |*/ 8321 /*|________________|*/ 8322 8323 m4mcs_intaudiotranscoding_feed_resampler: 8324 8325 /* Check if we have to empty the ssrc out buffer first */ 8326 if( M4OSA_NULL != pC->pPosInSsrcBufferOut ) 8327 { 8328 goto m4mcs_intaudiotranscoding_prepare_input_buffer; 8329 } 8330 8331 /* Compute number of bytes remaining in the decoder buffer */ 8332 uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short) 8333 * pC->pReaderAudioStream->m_nbChannels; 8334 uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress 8335 + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut; 8336 8337 /* Check if we can feed directly the Ssrc with the decoder out buffer */ 8338 if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn) 8339 && (uiBytesDec >= uiSsrcInSize) ) 8340 { 8341 pSsrcInput = pC->pPosInDecBufferOut; 8342 8343 /* update data consumed into decoder buffer after resampling */ 8344 if( uiBytesDec == uiSsrcInSize ) 8345 pC->pPosInDecBufferOut = M4OSA_NULL; 8346 else 8347 pC->pPosInDecBufferOut += uiSsrcInSize; 8348 8349 goto m4mcs_intaudiotranscoding_do_resampling; 8350 } 8351 8352 /** 8353 * Compute remaining space in Ssrc buffer in */ 8354 uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn; 8355 8356 /** 8357 * Nb of bytes copied is the minimum between nb of bytes remaining in 8358 * decoder out buffer and space remaining in ssrc in buffer */ 8359 uiDecoder2Ssrc_NbBytes = 8360 (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec; 8361 8362 /** 8363 * Copy from the decoder out buffer into the Ssrc in buffer */ 8364 memcpy((void *)pC->pPosInSsrcBufferIn, (void *)pC->pPosInDecBufferOut, 8365 uiDecoder2Ssrc_NbBytes); 8366 8367 /** 8368 * Update the position in the decoder out buffer */ 8369 pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes; 8370 8371 /** 8372 * Update the position in the Ssrc in buffer */ 8373 pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes; 8374 8375 /** 8376 * Check if the decoder buffer out is empty */ 8377 if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress) 8378 == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize ) 8379 { 8380 pC->pPosInDecBufferOut = M4OSA_NULL; 8381 } 8382 8383 /* Check if the Ssrc in buffer is ready (= full) */ 8384 if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn) 8385 < (M4OSA_Int32)uiSsrcInSize ) 8386 { 8387 goto m4mcs_intaudiotranscoding_end; 8388 } 8389 8390 pSsrcInput = pC->pSsrcBufferIn; 8391 8392 /* update data consumed into ssrc buffer in after resampling (empty) */ 8393 pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn; 8394 8395 /* ___________________ */ 8396 /*| |*/ 8397 /*| DO THE RESAMPLING |*/ 8398 /*|___________________|*/ 8399 8400 m4mcs_intaudiotranscoding_do_resampling: 8401 8402 /** 8403 * No need for memcopy, we can feed Ssrc directly with the data in the audio 8404 decoder out buffer*/ 8405 8406 ssrcErr = 0; 8407 8408 if( pC->pReaderAudioStream->m_nbChannels == 1 ) 8409 { 8410 tempBuffOut = 8411 (short *)M4OSA_32bitAlignedMalloc((pC->iSsrcNbSamplOut * sizeof(short) * 2 8412 * ((*pC).InputFileProperties).uiNbChannels), 8413 M4VSS3GPP,(M4OSA_Char *) "tempBuffOut"); 8414 memset((void *)tempBuffOut, 0,(pC->iSsrcNbSamplOut * sizeof(short) * 2 8415 * ((*pC).InputFileProperties).uiNbChannels)); 8416 8417 LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput, 8418 pC->iSsrcNbSamplOut, pC->pLVAudioResampler); 8419 } 8420 else 8421 { 8422 memset((void *)pC->pSsrcBufferOut, 0, (pC->iSsrcNbSamplOut * sizeof(short) 8423 * ((*pC).InputFileProperties).uiNbChannels)); 8424 8425 LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut, 8426 (short *)pSsrcInput, pC->iSsrcNbSamplOut, pC->pLVAudioResampler); 8427 } 8428 8429 if( pC->pReaderAudioStream->m_nbChannels == 1 ) 8430 { 8431 From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut, 8432 (short)pC->iSsrcNbSamplOut); 8433 free(tempBuffOut); 8434 } 8435 8436 8437 if( 0 != ssrcErr ) 8438 { 8439 M4OSA_TRACE1_1( 8440 "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \ 8441 returning M4MCS_ERR_AUDIO_CONVERSION_FAILED", 8442 ssrcErr); 8443 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 8444 } 8445 8446 pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut; 8447 8448 /* ______________________ */ 8449 /*| |*/ 8450 /*| PREPARE INPUT BUFFER |*/ 8451 /*|______________________|*/ 8452 8453 m4mcs_intaudiotranscoding_prepare_input_buffer: 8454 8455 /* Set the flag for channel conversion requirement */ 8456 if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 8457 && (pC->pReaderAudioStream->m_nbChannels == 2) ) 8458 { 8459 needChannelConversion = 1; 8460 uiChannelConvertorCoeff = 4; 8461 } 8462 else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo) 8463 && (pC->pReaderAudioStream->m_nbChannels == 1) ) 8464 { 8465 needChannelConversion = 2; 8466 uiChannelConvertorCoeff = 1; 8467 } 8468 else 8469 { 8470 needChannelConversion = 0; 8471 uiChannelConvertorCoeff = 2; 8472 } 8473 8474 /* Compute number of bytes remaining in the Ssrc buffer */ 8475 uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short) 8476 * pC->pReaderAudioStream->m_nbChannels; 8477 uiBytesSsrc = 8478 ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut; 8479 8480 /* Check if the ssrc buffer is full */ 8481 if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut ) 8482 { 8483 uiSsrc2Encoder_NbBytes = 8484 pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2; 8485 8486 /* Check if we can feed directly the encoder with the ssrc out buffer */ 8487 if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL) 8488 && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) ) 8489 { 8490 /* update position in ssrc out buffer after encoding */ 8491 if( uiBytesSsrc == uiSsrc2Encoder_NbBytes ) 8492 pC->pPosInSsrcBufferOut = M4OSA_NULL; 8493 else 8494 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; 8495 8496 /* mark the encoder buffer ready (= full) */ 8497 pC->pPosInAudioEncoderBuffer = 8498 pC->pAudioEncoderBuffer + pC->audioEncoderGranularity; 8499 8500 if( needChannelConversion > 0 ) 8501 { 8502 /* channel convertor writes directly into encoder buffer */ 8503 pEncoderInput = pC->pAudioEncoderBuffer; 8504 8505 pChannelConvertorInput = pC->pSsrcBufferOut; 8506 pChannelConvertorOutput = pC->pAudioEncoderBuffer; 8507 uiChannelConvertorNbSamples = 8508 uiSsrc2Encoder_NbBytes / sizeof(short); 8509 8510 goto m4mcs_intaudiotranscoding_channel_convertor; 8511 } 8512 else 8513 { 8514 /* encode directly from ssrc out buffer */ 8515 pEncoderInput = pC->pSsrcBufferOut; 8516 8517 goto m4mcs_intaudiotranscoding_encode_and_write; 8518 } 8519 } 8520 } 8521 8522 /** 8523 * Compute remaining space in encoder buffer in */ 8524 if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL ) 8525 { 8526 pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer; 8527 } 8528 8529 uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity) 8530 - pC->pPosInAudioEncoderBuffer; 8531 pEncoderInput = pC->pAudioEncoderBuffer; 8532 8533 /** 8534 * Nb of bytes copied is the minimum between nb of bytes remaining in 8535 * decoder out buffer and space remaining in ssrc in buffer */ 8536 uiSsrc2Encoder_NbBytes = 8537 (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc) 8538 ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc; 8539 8540 if( needChannelConversion > 0 ) 8541 { 8542 /* channel convertor writes directly into encoder buffer */ 8543 pChannelConvertorInput = pC->pPosInSsrcBufferOut; 8544 pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer; 8545 uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short); 8546 } 8547 else 8548 { 8549 /* copy from the ssrc out buffer into the encoder in buffer */ 8550 memcpy((void *)pC->pPosInAudioEncoderBuffer, (void *)pC->pPosInSsrcBufferOut, 8551 uiSsrc2Encoder_NbBytes); 8552 } 8553 8554 /* Update position in ssrc out buffer after encoding */ 8555 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; 8556 8557 /* Update the position in the encoder in buffer */ 8558 pC->pPosInAudioEncoderBuffer += 8559 uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff; 8560 8561 /* Check if the ssrc buffer out is empty */ 8562 if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut) 8563 == (M4OSA_Int32)uiSsrcOutSize ) 8564 { 8565 pC->pPosInSsrcBufferOut = M4OSA_NULL; 8566 } 8567 8568 /* go to next statement */ 8569 if( needChannelConversion > 0 ) 8570 goto m4mcs_intaudiotranscoding_channel_convertor; 8571 else 8572 goto m4mcs_intaudiotranscoding_encode_and_write; 8573 8574 /* _________________ */ 8575 /*| |*/ 8576 /*| STEREO <-> MONO |*/ 8577 /*|_________________|*/ 8578 8579 m4mcs_intaudiotranscoding_channel_convertor: 8580 8581 /* convert the input pcm stream to mono or to stereo */ 8582 switch( needChannelConversion ) 8583 { 8584 case 1: /* stereo to mono */ 8585 From2iToMono_16((short *)pChannelConvertorInput, 8586 (short *)pChannelConvertorOutput, 8587 (short)(uiChannelConvertorNbSamples / 2)); 8588 break; 8589 8590 case 2: /* mono to stereo */ 8591 MonoTo2I_16((short *)pChannelConvertorInput, 8592 (short *)pChannelConvertorOutput, 8593 (short)uiChannelConvertorNbSamples); 8594 break; 8595 } 8596 8597 /* __________________ */ 8598 /*| |*/ 8599 /*| ENCODE AND WRITE |*/ 8600 /*|__________________|*/ 8601 8602 m4mcs_intaudiotranscoding_encode_and_write: 8603 8604 /* Check if the encoder in buffer is ready (= full) */ 8605 if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer) 8606 < (M4OSA_Int32)pC->audioEncoderGranularity ) 8607 { 8608 goto m4mcs_intaudiotranscoding_end; 8609 } 8610 8611 /* [Mono] or [Stereo interleaved] : all is in one buffer */ 8612 pEncInBuffer.pTableBuffer[0] = pEncoderInput; 8613 pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity; 8614 pEncInBuffer.pTableBuffer[1] = M4OSA_NULL; 8615 pEncInBuffer.pTableBufferSize[1] = 0; 8616 8617 /* Time in ms from data size, because it is PCM16 samples */ 8618 frameTimeDelta = 8619 ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2) 8620 / sizeof(short) / pC->pReaderAudioStream->m_nbChannels; 8621 8622 /** 8623 * Prepare the writer AU */ 8624 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 8625 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8626 8627 if( M4NO_ERROR != err ) 8628 { 8629 M4OSA_TRACE1_1( 8630 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", 8631 err); 8632 return err; 8633 } 8634 8635 /*FlB 2009.03.04: apply audio effects if an effect is active*/ 8636 if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects ) 8637 { 8638 if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL ) 8639 { 8640 M4MCS_ExternalProgress pProgress; 8641 M4OSA_UInt32 tempProgress = 0; 8642 pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS; 8643 8644 pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000) 8645 / pC->WriterAudioStream.timeScale; 8646 tempProgress = ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 8647 - pC->pEffects[*pActiveEffectNumber].uiStartTime 8648 - pC->uiBeginCutTime) * 1000; 8649 pProgress.uiProgress = 8650 (M4OSA_UInt32)(tempProgress / (M4OSA_UInt32)pC->pEffects[ 8651 *pActiveEffectNumber].uiDuration); 8652 8653 err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct( 8654 pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt, 8655 (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0], 8656 pEncInBuffer.pTableBufferSize[0], &pProgress); 8657 8658 if( err != M4NO_ERROR ) 8659 { 8660 M4OSA_TRACE1_1( 8661 "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x", 8662 err); 8663 return err; 8664 } 8665 } 8666 } 8667 8668 /** 8669 * Prepare output buffer */ 8670 pEncOutBuffer.pTableBuffer[0] = 8671 (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress; 8672 pEncOutBuffer.pTableBufferSize[0] = 0; 8673 8674 #ifdef MCS_DUMP_PCM_TO_FILE 8675 8676 fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1, 8677 file_pcm_encoder); 8678 8679 #endif 8680 8681 if( M4OSA_FALSE == pC->b_isRawWriter ) 8682 { 8683 /* This allow to write PCM data to file and to encode AMR data, 8684 when output file is not RAW */ 8685 if( pC->pOutputPCMfile != M4OSA_NULL ) 8686 { 8687 pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile, 8688 pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]); 8689 } 8690 8691 /** 8692 * Encode the PCM audio */ 8693 err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt, 8694 &pEncInBuffer, &pEncOutBuffer); 8695 8696 if( M4NO_ERROR != err ) 8697 { 8698 M4OSA_TRACE1_1( 8699 "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x", 8700 err); 8701 return err; 8702 } 8703 8704 /* update data consumed into encoder buffer in after encoding (empty) */ 8705 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 8706 8707 /** 8708 * Set AU cts and size */ 8709 pC->WriterAudioAU.size = 8710 pEncOutBuffer. 8711 pTableBufferSize[0]; /**< Get the size of encoded data */ 8712 pC->WriterAudioAU.CTS += frameTimeDelta; 8713 8714 /** 8715 * Update duration of the encoded AU */ 8716 pC->m_audioAUDuration = 8717 ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale; 8718 8719 /** 8720 * Write the encoded AU to the output file */ 8721 pC->uiAudioAUCount++; 8722 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8723 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8724 8725 if( M4NO_ERROR != err ) 8726 { 8727 M4OSA_TRACE1_1( 8728 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8729 err); 8730 return err; 8731 } 8732 } 8733 else 8734 { 8735 /* update data consumed into encoder buffer in after encoding (empty) */ 8736 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 8737 8738 pC->WriterAudioAU.dataAddress = 8739 (M4OSA_MemAddr32) 8740 pEncoderInput; /* will be converted back to u8* in file write */ 8741 pC->WriterAudioAU.size = pC->audioEncoderGranularity; 8742 pC->uiAudioAUCount++; 8743 8744 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8745 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8746 8747 if( M4NO_ERROR != err ) 8748 { 8749 M4OSA_TRACE1_1( 8750 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8751 err); 8752 return err; 8753 } 8754 } 8755 8756 /* _______________ */ 8757 /*| |*/ 8758 /*| ONE PASS DONE |*/ 8759 /*|_______________|*/ 8760 8761 m4mcs_intaudiotranscoding_end: 8762 8763 /** 8764 * Return with no error */ 8765 M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR"); 8766 return M4NO_ERROR; 8767 } 8768 8769 /** 8770 ****************************************************************************** 8771 * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize) 8772 * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU 8773 * because max AU size can be reevaluated during reading 8774 * @return M4NO_ERROR: No error 8775 ****************************************************************************** 8776 */ 8777 static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr, 8778 M4OSA_UInt32 newSize ) 8779 { 8780 if( *addr != M4OSA_NULL ) 8781 { 8782 free(*addr); 8783 *addr = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(newSize, M4MCS, 8784 (M4OSA_Char *)"Reallocation of temporary AU buffer"); 8785 8786 if( *addr == M4OSA_NULL ) 8787 { 8788 return M4ERR_ALLOC; 8789 } 8790 } 8791 8792 return M4NO_ERROR; 8793 } 8794 8795 /** 8796 ****************************************************************************** 8797 * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC) 8798 * @author Alexis Vapillon (NXP Software Vision) 8799 * @return M4NO_ERROR: No error 8800 ****************************************************************************** 8801 */ 8802 static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC ) 8803 { 8804 M4OSA_ERR err = M4NO_ERROR; 8805 /* Duration of the AU (find the next AU duration 8806 * to obtain a more precise video end cut) 8807 */ 8808 M4OSA_UInt32 videoAUDuration = 0; 8809 8810 M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL; 8811 M4OSA_Int32 lastdecodedCTS = 0; 8812 M4_AccessUnit lReaderVideoAU; /**< Read video access unit */ 8813 8814 if( pC->novideo ) 8815 return M4NO_ERROR; 8816 8817 /* H.264 Trimming */ 8818 if( ( ( pC->bH264Trim == M4OSA_TRUE) 8819 && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames) 8820 && (pC->uiBeginCutTime > 0)) 8821 || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) ) 8822 { 8823 err = M4MCS_intVideoTranscoding(pC); 8824 return err; 8825 } 8826 8827 8828 if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0)) 8829 { 8830 // StageFright encoder does prefetch, the one frame we requested will not be written until 8831 // the encoder is closed, so do it now rather than in MCS_close 8832 if( ( M4NO_ERROR != err) 8833 || (M4MCS_kEncoderRunning != pC->encoderState) ) 8834 { 8835 M4OSA_TRACE1_2( 8836 "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding " 8837 "returns 0x%X w/ encState=%d", err, pC->encoderState); 8838 8839 return err; 8840 } 8841 8842 /* Stop and close the encoder now to flush the frame (prefetch) */ 8843 if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL ) 8844 { 8845 err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt); 8846 8847 if( M4NO_ERROR != err ) 8848 { 8849 M4OSA_TRACE1_1( 8850 "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X", 8851 err); 8852 return err; 8853 } 8854 } 8855 pC->encoderState = M4MCS_kEncoderStopped; 8856 err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt); 8857 8858 if( M4NO_ERROR != err ) 8859 { 8860 M4OSA_TRACE1_1( 8861 "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X", 8862 err); 8863 return err; 8864 } 8865 pC->encoderState = M4MCS_kEncoderClosed; 8866 } 8867 8868 8869 if ((pC->EncodingVideoFormat = M4ENCODER_kNULL) 8870 && (pC->bLastDecodedFrameCTS == M4OSA_FALSE) 8871 && (pC->uiBeginCutTime > 0)) { 8872 8873 pC->bLastDecodedFrameCTS = M4OSA_TRUE; 8874 err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt, 8875 M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS); 8876 8877 if (M4NO_ERROR != err) { 8878 M4OSA_TRACE1_1( 8879 "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!", 8880 err); 8881 return err; 8882 } 8883 /* Do not need video decoder any more, need to destroy it. Otherwise it 8884 * will call reader function which will cause frame lost during triming, 8885 * since the 3gp reader is shared between MCS and decoder.*/ 8886 if (M4OSA_NULL != pC->pViDecCtxt) { 8887 err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); 8888 pC->pViDecCtxt = M4OSA_NULL; 8889 8890 if (M4NO_ERROR != err) { 8891 M4OSA_TRACE1_1( 8892 "M4MCS_intVideoNullEncoding: decoder pFctDestroy returns 0x%x", 8893 err); 8894 return err; 8895 } 8896 } 8897 8898 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 8899 (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS); 8900 8901 if (M4NO_ERROR != err) { 8902 M4OSA_TRACE1_1( 8903 "M4MCS_intVideoNullEncoding: m_pFctJump(V) returns 0x%x!", 8904 err); 8905 return err; 8906 } 8907 8908 8909 /* Initializes an access Unit */ 8910 8911 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 8912 (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); 8913 8914 if (M4NO_ERROR != err) { 8915 M4OSA_TRACE1_1( 8916 "M4MCS_intVideoNullEncoding:m_pReader->m_pFctFillAuStruct(video)\ 8917 returns 0x%x", err); 8918 return err; 8919 } 8920 8921 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8922 (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); 8923 8924 if (M4WAR_NO_MORE_AU == err) { 8925 M4OSA_TRACE2_0( 8926 "M4MCS_intVideoNullEncoding():\ 8927 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 8928 /* The audio transcoding is finished */ 8929 pC->VideoState = M4MCS_kStreamState_FINISHED; 8930 return err; 8931 } 8932 else if (M4NO_ERROR != err) { 8933 M4OSA_TRACE1_1( 8934 "M4MCS_intVideoNullEncoding():\ 8935 m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", 8936 err); 8937 return err; 8938 } 8939 8940 M4OSA_TRACE1_1( 8941 "### [TS_CHECK] M4MCS_intVideoNullEncoding video AU CTS: %d ", 8942 lReaderVideoAU.m_CTS); 8943 8944 8945 } 8946 8947 8948 pC->bLastDecodedFrameCTS = M4OSA_TRUE; 8949 8950 8951 /* Find the next AU duration to obtain a more precise video end cut*/ 8952 /** 8953 * Initializes a new AU if needed */ 8954 8955 if (pC->ReaderVideoAU1.m_structSize == 0) { 8956 /** 8957 * Initializes an access Unit */ 8958 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 8959 (M4_StreamHandler *)pC->pReaderVideoStream, 8960 &pC->ReaderVideoAU1); 8961 8962 if (M4NO_ERROR != err) { 8963 M4OSA_TRACE1_1( 8964 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 8965 err); 8966 return err; 8967 } 8968 8969 pC->m_pDataVideoAddress1 = 8970 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU1.m_maxsize, M4MCS, 8971 (M4OSA_Char *)"Temporary video AU1 buffer"); 8972 8973 if (pC->m_pDataVideoAddress1 == M4OSA_NULL) { 8974 M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); 8975 return M4ERR_ALLOC; 8976 } 8977 8978 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8979 (M4_StreamHandler *)pC->pReaderVideoStream, 8980 &pC->ReaderVideoAU1); 8981 8982 if( M4WAR_NO_MORE_AU == err ) 8983 { 8984 M4OSA_TRACE2_0( 8985 "M4MCS_intVideoNullEncoding():\ 8986 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 8987 /* The audio transcoding is finished */ 8988 pC->VideoState = M4MCS_kStreamState_FINISHED; 8989 return err; 8990 } 8991 else if( M4NO_ERROR != err ) 8992 { 8993 M4OSA_TRACE1_1( 8994 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\ 8995 returns 0x%x", err); 8996 return err; 8997 } 8998 8999 if( pC->ReaderVideoAU1.m_maxsize 9000 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9001 { 9002 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9003 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9004 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); 9005 /* pC->m_pDataVideoAddress1 9006 and pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9007 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9008 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9009 m_basicProperties.m_maxAUSize)" is never true */ 9010 /* and the size of the second buffer is never changed. */ 9011 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9012 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); 9013 /* pC->m_pDataVideoAddress1 and 9014 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9015 /* Update stream properties */ 9016 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9017 pC->ReaderVideoAU1.m_maxsize; 9018 } 9019 memcpy((void *)pC->m_pDataVideoAddress1, 9020 (void *)pC->ReaderVideoAU1.m_dataAddress, 9021 pC->ReaderVideoAU1.m_size); 9022 } 9023 9024 if( pC->ReaderVideoAU2.m_structSize == 0 ) 9025 { 9026 /** 9027 * Initializes an access Unit */ 9028 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 9029 (M4_StreamHandler *)pC->pReaderVideoStream, 9030 &pC->ReaderVideoAU2); 9031 9032 if( M4NO_ERROR != err ) 9033 { 9034 M4OSA_TRACE1_1( 9035 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 9036 err); 9037 return err; 9038 } 9039 pC->m_pDataVideoAddress2 = 9040 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU2.m_maxsize, M4MCS, 9041 (M4OSA_Char *)"Temporary video AU buffer"); 9042 9043 if( pC->m_pDataVideoAddress2 == M4OSA_NULL ) 9044 { 9045 M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); 9046 return M4ERR_ALLOC; 9047 } 9048 } 9049 /** 9050 * Read the next video AU in the input file */ 9051 if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS ) 9052 { 9053 memcpy((void *) &pC->ReaderVideoAU, 9054 (void *) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit)); 9055 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9056 (M4_StreamHandler *)pC->pReaderVideoStream, 9057 &pC->ReaderVideoAU1); 9058 9059 if( pC->ReaderVideoAU1.m_maxsize 9060 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9061 { 9062 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9063 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9064 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); 9065 /* pC->m_pDataVideoAddress1 and 9066 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9067 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9068 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9069 m_basicProperties.m_maxAUSize)" is never true */ 9070 /* and the size of the second buffer is never changed. */ 9071 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9072 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); 9073 /* pC->m_pDataVideoAddress1 and 9074 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9075 /* Update stream properties */ 9076 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9077 pC->ReaderVideoAU1.m_maxsize; 9078 } 9079 memcpy((void *)pC->m_pDataVideoAddress1, 9080 (void *)pC->ReaderVideoAU1.m_dataAddress, 9081 pC->ReaderVideoAU1.m_size); 9082 videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS; 9083 pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2; 9084 } 9085 else 9086 { 9087 memcpy((void *) &pC->ReaderVideoAU, 9088 (void *) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit)); 9089 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9090 (M4_StreamHandler *)pC->pReaderVideoStream, 9091 &pC->ReaderVideoAU2); 9092 9093 if( pC->ReaderVideoAU2.m_maxsize 9094 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9095 { 9096 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9097 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9098 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize); 9099 /* pC->m_pDataVideoAddress1 and 9100 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9101 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9102 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9103 m_basicProperties.m_maxAUSize)" is never true */ 9104 /* and the size of the second buffer is never changed. */ 9105 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9106 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize); 9107 /* pC->m_pDataVideoAddress1 and 9108 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9109 /* Update stream properties */ 9110 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9111 pC->ReaderVideoAU2.m_maxsize; 9112 } 9113 memcpy((void *)pC->m_pDataVideoAddress2, 9114 (void *)pC->ReaderVideoAU2.m_dataAddress, 9115 pC->ReaderVideoAU2.m_size); 9116 videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS; 9117 pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1; 9118 } 9119 9120 if( M4WAR_NO_MORE_AU == err ) 9121 { 9122 M4OSA_TRACE2_0( 9123 "M4MCS_intVideoNullEncoding():\ 9124 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 9125 /* The video transcoding is finished */ 9126 pC->VideoState = M4MCS_kStreamState_FINISHED; 9127 return err; 9128 } 9129 else if( M4NO_ERROR != err ) 9130 { 9131 M4OSA_TRACE1_1( 9132 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x", 9133 err); 9134 return err; 9135 } 9136 else 9137 { 9138 /** 9139 * Prepare the writer AU */ 9140 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 9141 M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); 9142 9143 if( M4NO_ERROR != err ) 9144 { 9145 M4OSA_TRACE1_1( 9146 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x", 9147 err); 9148 return err; 9149 } 9150 /** 9151 * Copy video data from reader AU to writer AU */ 9152 M4OSA_TRACE3_1( 9153 "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d", 9154 pC->ReaderVideoAU.m_size); 9155 /* + CRLV6775 -H.264 Trimming */ 9156 if( M4OSA_TRUE == pC->bH264Trim ) 9157 { 9158 if( pC->H264MCSTempBufferSize 9159 < (pC->ReaderVideoAU.m_size + 2048) ) 9160 { 9161 pC->H264MCSTempBufferSize = 9162 (pC->ReaderVideoAU.m_size + 2048); 9163 9164 if( pC->H264MCSTempBuffer != M4OSA_NULL ) 9165 { 9166 free(pC->H264MCSTempBuffer); 9167 } 9168 pC->H264MCSTempBuffer = 9169 (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->H264MCSTempBufferSize, 9170 M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer"); 9171 9172 if( pC->H264MCSTempBuffer == M4OSA_NULL ) 9173 { 9174 M4OSA_TRACE1_0( 9175 "M4MCS_intVideoNullEncoding(): allocation error"); 9176 return M4ERR_ALLOC; 9177 } 9178 } 9179 9180 pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize; 9181 9182 err = H264MCS_ProcessNALU(pC->m_pInstance, 9183 (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress, 9184 pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer, 9185 (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize); 9186 9187 if( pC->m_pInstance->is_done == 1 ) 9188 { 9189 M4MCS_convetFromByteStreamtoNALStream( 9190 (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress , 9191 pC->ReaderVideoAU.m_size); 9192 9193 memcpy((void *)pC->WriterVideoAU.dataAddress, 9194 (void *)(pC->ReaderVideoAU.m_dataAddress + 4), 9195 pC->ReaderVideoAU.m_size - 4); 9196 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4; 9197 WritebufferAdd = 9198 (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; 9199 } 9200 else 9201 { 9202 memcpy((void *)pC->WriterVideoAU.dataAddress, 9203 (void *)(pC->H264MCSTempBuffer + 4), 9204 pC->H264MCSTempBufferDataSize - 4); 9205 pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4; 9206 WritebufferAdd = 9207 (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; 9208 } 9209 } 9210 /* H.264 Trimming */ 9211 else 9212 { 9213 memcpy((void *)pC->WriterVideoAU.dataAddress, 9214 (void *)pC->ReaderVideoAU.m_dataAddress, 9215 pC->ReaderVideoAU.m_size); 9216 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size; 9217 } 9218 /** 9219 * Convert CTS unit from milliseconds to timescale */ 9220 pC->WriterVideoAU.CTS = 9221 (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts) 9222 * (pC->WriterVideoStream.timeScale / 1000.0))); 9223 pC->WriterVideoAU.nbFrag = 0; 9224 pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute; 9225 9226 M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms", 9227 pC->WriterVideoAU.CTS); 9228 9229 /** 9230 * Write it to the output file */ 9231 pC->uiVideoAUCount++; 9232 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 9233 M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); 9234 9235 if( M4NO_ERROR != err ) 9236 { 9237 M4OSA_TRACE1_1( 9238 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x", 9239 err); 9240 return err; 9241 } 9242 /* + CRLV6775 -H.264 Trimming */ 9243 if( M4OSA_TRUE == pC->bH264Trim ) 9244 { 9245 if( pC->m_pInstance->is_done == 1 ) 9246 { 9247 memcpy((void *)(WritebufferAdd - 4), 9248 (void *)(pC->ReaderVideoAU.m_dataAddress), 4); 9249 } 9250 else 9251 { 9252 memcpy((void *)(WritebufferAdd - 4), 9253 (void *)(pC->H264MCSTempBuffer), 4); 9254 } 9255 } /* H.264 Trimming */ 9256 } 9257 /** 9258 * Check for end cut. */ 9259 /* Bug fix 11/12/2008: We absolutely want to have less or same video duration -> 9260 (2*videoAUDuration) to have a more precise end cut*/ 9261 if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime ) 9262 { 9263 pC->VideoState = M4MCS_kStreamState_FINISHED; 9264 } 9265 9266 /** 9267 * Return with no error */ 9268 M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR"); 9269 return M4NO_ERROR; 9270 } 9271 9272 /** 9273 ****************************************************************************** 9274 * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC) 9275 * @author Alexis Vapillon (NXP Software Vision) 9276 * @return M4NO_ERROR: No error 9277 ****************************************************************************** 9278 */ 9279 static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC ) 9280 { 9281 M4OSA_ERR err = M4NO_ERROR; 9282 M4_MediaTime mtTranscodedTime = 0.0; 9283 M4ENCODER_FrameMode FrameMode; 9284 M4OSA_Int32 derive = 0; 9285 9286 /** 9287 * Get video CTS to decode */ 9288 mtTranscodedTime = pC->dViDecCurrentCts; 9289 FrameMode = M4ENCODER_kNormalFrame; 9290 9291 /** 9292 * Decode video */ 9293 M4OSA_TRACE3_1( 9294 "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)", 9295 mtTranscodedTime); 9296 pC->isRenderDup = M4OSA_FALSE; 9297 err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime, 9298 M4OSA_FALSE, 0); 9299 9300 if( M4WAR_NO_MORE_AU == err ) 9301 { 9302 FrameMode = 9303 M4ENCODER_kLastFrame; /**< We will give this value to the encoder to 9304 ask for the end of the encoding */ 9305 pC->VideoState = M4MCS_kStreamState_FINISHED; 9306 } 9307 else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 9308 { 9309 M4OSA_TRACE2_0("Decoding output the same frame as before 3"); 9310 pC->isRenderDup = M4OSA_TRUE; 9311 } 9312 else if( M4NO_ERROR != err ) 9313 { 9314 M4OSA_TRACE1_1( 9315 "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!", 9316 err); 9317 return err; 9318 } 9319 9320 /** 9321 * Check for end cut. 9322 * We must check here if the end cut is reached, because in that case we must 9323 * call the last encode step (-> bLastFrame set to true) */ 9324 if( ( pC->dViDecCurrentCts + pC->dCtsIncrement ) >= (pC->uiEndCutTime 9325 + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) ) 9326 { 9327 FrameMode = 9328 M4ENCODER_kLastFrame; /**< We will give this value to the encoder to 9329 ask for the end of the encoding */ 9330 pC->VideoState = M4MCS_kStreamState_FINISHED; 9331 derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5) 9332 - (pC->uiEndCutTime 9333 + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime))); 9334 } 9335 9336 /* Update starting CTS to have a more precise value ( 9337 the begin cut is not a real CTS)*/ 9338 if( pC->uiVideoAUCount == 0 ) 9339 { 9340 pC->dViDecStartingCts = mtTranscodedTime; 9341 pC->dViDecCurrentCts = pC->dViDecStartingCts; 9342 } 9343 9344 /** 9345 * Encode video */ 9346 M4OSA_TRACE3_1( 9347 "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\ 9348 = %.2f",pC->ReaderVideoAU.m_CTS); 9349 pC->uiVideoAUCount++; 9350 /* update the given duration (the begin cut is not a real CTS)*/ 9351 err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL, 9352 (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)), 9353 FrameMode); 9354 9355 return err; 9356 } 9357 9358 /** 9359 ****************************************************************************** 9360 * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext) 9361 * @author Dounya Manai (NXP Software Vision) 9362 * @brief Retrieve the properties of the audio and video streams from the input file. 9363 * @param pContext (IN) MCS context 9364 * @return M4NO_ERROR: No error 9365 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) 9366 ****************************************************************************** 9367 */ 9368 static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC ) 9369 { 9370 M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo; 9371 M4READER_3GP_H263Properties H263prop; 9372 M4OSA_ERR err; 9373 M4OSA_UInt32 videoBitrate; 9374 M4DECODER_VideoSize videoSize; 9375 M4_AACType iAacType = 0; 9376 9377 /** 9378 * Check input parameters */ 9379 M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER, 9380 "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL"); 9381 9382 /** 9383 * Reset common characteristics */ 9384 pC->InputFileProperties.bAnalysed = M4OSA_FALSE; 9385 pC->InputFileProperties.FileType = 0; 9386 pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR; 9387 pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR; 9388 pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION; 9389 pC->InputFileProperties.uiClipDuration = 0; 9390 9391 memset((void *) &pC->InputFileProperties.ftyp, 9392 0, sizeof(M4VIDEOEDITING_FtypBox)); 9393 9394 /** 9395 * Reset video characteristics */ 9396 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; 9397 pC->InputFileProperties.uiClipVideoDuration = 0; 9398 pC->InputFileProperties.uiVideoBitrate = 0; 9399 pC->InputFileProperties.uiVideoMaxAuSize = 0; 9400 pC->InputFileProperties.uiVideoWidth = 0; 9401 pC->InputFileProperties.uiVideoHeight = 0; 9402 pC->InputFileProperties.uiVideoTimeScale = 0; 9403 pC->InputFileProperties.fAverageFrameRate = 0.0; 9404 pC->InputFileProperties.uiVideoLevel = 9405 M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; 9406 pC->InputFileProperties.uiVideoProfile = 9407 M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; 9408 pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE; 9409 pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE; 9410 pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE; 9411 9412 /** 9413 * Reset audio characteristics */ 9414 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; 9415 pC->InputFileProperties.uiClipAudioDuration = 0; 9416 pC->InputFileProperties.uiAudioBitrate = 0; 9417 pC->InputFileProperties.uiAudioMaxAuSize = 0; 9418 pC->InputFileProperties.uiNbChannels = 0; 9419 pC->InputFileProperties.uiSamplingFrequency = 0; 9420 pC->InputFileProperties.uiExtendedSamplingFrequency = 0; 9421 pC->InputFileProperties.uiDecodedPcmSize = 0; 9422 9423 /* Reset compatibility chart (not used in MCS) */ 9424 pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE; 9425 pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE; 9426 pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE; 9427 pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; 9428 9429 /** 9430 * Video stream properties */ 9431 if( M4OSA_NULL != pC->pReaderVideoStream ) 9432 { 9433 switch( pC->pReaderVideoStream->m_basicProperties.m_streamType ) 9434 { 9435 case M4DA_StreamTypeVideoMpeg4: 9436 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4; 9437 break; 9438 9439 case M4DA_StreamTypeVideoH263: 9440 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263; 9441 break; 9442 9443 case M4DA_StreamTypeVideoMpeg4Avc: 9444 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264; 9445 break; 9446 9447 case M4DA_StreamTypeUnknown: 9448 default: 9449 pC->InputFileProperties.VideoStreamType = 9450 M4VIDEOEDITING_kUnsupportedVideo; 9451 break; 9452 } 9453 9454 /* if bitrate not available retrieve an estimation of the overall bitrate */ 9455 pC->InputFileProperties.uiVideoBitrate = 9456 pC->pReaderVideoStream->m_basicProperties.m_averageBitRate; 9457 9458 if( 0 == pC->InputFileProperties.uiVideoBitrate ) 9459 { 9460 pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 9461 M4READER_kOptionID_Bitrate, &videoBitrate); 9462 9463 if( M4OSA_NULL != pC->pReaderAudioStream ) 9464 { 9465 /* we get the overall bitrate, substract the audio bitrate if any */ 9466 videoBitrate -= 9467 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; 9468 } 9469 pC->InputFileProperties.uiVideoBitrate = videoBitrate; 9470 } 9471 9472 /** 9473 * Retrieve the Profile & Level */ 9474 if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType) 9475 && (M4VIDEOEDITING_kH264 9476 != pC->InputFileProperties.VideoStreamType) ) 9477 { 9478 /* Use the DSI parsing function from the external video shell decoder. 9479 See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the 9480 same issue. */ 9481 9482 err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream-> 9483 m_basicProperties.m_pDecoderSpecificInfo, 9484 pC->pReaderVideoStream-> 9485 m_basicProperties.m_decoderSpecificInfoSize, 9486 &DecConfInfo, &videoSize); 9487 9488 if( M4NO_ERROR != err ) 9489 { 9490 M4OSA_TRACE1_1( 9491 "M4MCS_intGetInputClipProperties():\ 9492 M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", 9493 err); 9494 return err; 9495 } 9496 9497 pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth; 9498 pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight; 9499 pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale; 9500 pC->InputFileProperties.bMPEG4dataPartition = 9501 DecConfInfo.bDataPartition; 9502 pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC; 9503 pC->InputFileProperties.bMPEG4resynchMarker = 9504 DecConfInfo.uiUseOfResynchMarker; 9505 9506 err = getMPEG4ProfileAndLevel(DecConfInfo.uiProfile, 9507 &(pC->InputFileProperties.uiVideoProfile), 9508 &(pC->InputFileProperties.uiVideoLevel)); 9509 if ( M4NO_ERROR != err ) { 9510 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ 9511 getMPEG4ProfileAndLevel returns 0x%08X", err); 9512 return err; 9513 } 9514 } 9515 else if( M4VIDEOEDITING_kH263 == 9516 pC->InputFileProperties.VideoStreamType ) { 9517 9518 err = getH263ProfileAndLevel(pC->pReaderVideoStream-> 9519 m_basicProperties.m_pDecoderSpecificInfo, 9520 pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize, 9521 &(pC->InputFileProperties.uiVideoProfile), 9522 &(pC->InputFileProperties.uiVideoLevel)); 9523 if ( M4NO_ERROR != err ) { 9524 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ 9525 getH263ProfileAndLevel returns 0x%08X", err); 9526 return err; 9527 } 9528 /* For h263 set default timescale : 30000:1001 */ 9529 pC->InputFileProperties.uiVideoTimeScale = 30000; 9530 } 9531 else if ( M4VIDEOEDITING_kH264 == 9532 pC->InputFileProperties.VideoStreamType ) { 9533 9534 pC->InputFileProperties.uiVideoTimeScale = 30000; 9535 err = getAVCProfileAndLevel(pC->pReaderVideoStream-> 9536 m_basicProperties.m_pDecoderSpecificInfo, 9537 pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize, 9538 &(pC->InputFileProperties.uiVideoProfile), 9539 &(pC->InputFileProperties.uiVideoLevel)); 9540 if ( M4NO_ERROR != err ) { 9541 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\ 9542 getAVCProfileAndLevel returns 0x%08X", err); 9543 return err; 9544 } 9545 } 9546 9547 /* Here because width x height is correct only after dsi parsing 9548 (done in create decoder) */ 9549 pC->InputFileProperties.uiVideoHeight = 9550 pC->pReaderVideoStream->m_videoHeight; 9551 pC->InputFileProperties.uiVideoWidth = 9552 pC->pReaderVideoStream->m_videoWidth; 9553 pC->InputFileProperties.uiClipVideoDuration = 9554 (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration; 9555 pC->InputFileProperties.fAverageFrameRate = 9556 pC->pReaderVideoStream->m_averageFrameRate; 9557 pC->InputFileProperties.uiVideoMaxAuSize = 9558 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize; 9559 pC->InputFileProperties.videoRotationDegrees = 9560 pC->pReaderVideoStream->videoRotationDegrees; 9561 } 9562 else 9563 { 9564 if( M4OSA_TRUE == pC->bUnsupportedVideoFound ) 9565 { 9566 pC->InputFileProperties.VideoStreamType = 9567 M4VIDEOEDITING_kUnsupportedVideo; 9568 } 9569 else 9570 { 9571 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; 9572 } 9573 } 9574 9575 /** 9576 * Audio stream properties */ 9577 if( M4OSA_NULL != pC->pReaderAudioStream ) 9578 { 9579 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) 9580 { 9581 case M4DA_StreamTypeAudioAmrNarrowBand: 9582 pC->InputFileProperties.AudioStreamType = 9583 M4VIDEOEDITING_kAMR_NB; 9584 break; 9585 9586 case M4DA_StreamTypeAudioAac: 9587 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC; 9588 break; 9589 9590 case M4DA_StreamTypeAudioMp3: 9591 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3; 9592 break; 9593 9594 case M4DA_StreamTypeAudioEvrc: 9595 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC; 9596 break; 9597 9598 case M4DA_StreamTypeUnknown: 9599 default: 9600 pC->InputFileProperties.AudioStreamType = 9601 M4VIDEOEDITING_kUnsupportedAudio; 9602 break; 9603 } 9604 9605 if( ( M4OSA_NULL != pC->m_pAudioDecoder) 9606 && (M4OSA_NULL == pC->pAudioDecCtxt) ) 9607 { 9608 M4OSA_TRACE3_1( 9609 "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x", 9610 pC->m_pCurrentAudioDecoderUserData); 9611 9612 if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) { 9613 err = M4MCS_intCheckAndGetCodecProperties(pC); 9614 } 9615 else 9616 { 9617 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 9618 &pC->pAudioDecCtxt, pC->pReaderAudioStream, 9619 pC->m_pCurrentAudioDecoderUserData); 9620 9621 if( M4NO_ERROR == err ) 9622 { 9623 /* AAC properties*/ 9624 //get from Reader; temporary, till Audio decoder shell API available to 9625 //get the AAC properties 9626 pC->AacProperties.aNumChan = 9627 pC->pReaderAudioStream->m_nbChannels; 9628 pC->AacProperties.aSampFreq = 9629 pC->pReaderAudioStream->m_samplingFrequency; 9630 9631 err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec( 9632 pC->pAudioDecCtxt, M4AD_kOptionID_StreamType, 9633 (M4OSA_DataOption) &iAacType); 9634 9635 if( M4NO_ERROR != err ) 9636 { 9637 M4OSA_TRACE1_1( 9638 "M4MCS_intGetInputClipProperties:\ 9639 m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", 9640 err); 9641 iAacType = M4_kAAC; //set to default 9642 err = M4NO_ERROR; 9643 } 9644 else 9645 { 9646 M4OSA_TRACE3_1( 9647 "M4MCS_intGetInputClipProperties:\ 9648 m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d", 9649 iAacType); 9650 } 9651 9652 switch( iAacType ) 9653 { 9654 case M4_kAAC: 9655 pC->AacProperties.aSBRPresent = 0; 9656 pC->AacProperties.aPSPresent = 0; 9657 break; 9658 9659 case M4_kAACplus: 9660 pC->AacProperties.aSBRPresent = 1; 9661 pC->AacProperties.aPSPresent = 0; 9662 pC->AacProperties.aExtensionSampFreq = 9663 pC->pReaderAudioStream-> 9664 m_samplingFrequency; //TODO 9665 break; 9666 9667 case M4_keAACplus: 9668 pC->AacProperties.aSBRPresent = 1; 9669 pC->AacProperties.aPSPresent = 1; 9670 pC->AacProperties.aExtensionSampFreq = 9671 pC->pReaderAudioStream-> 9672 m_samplingFrequency; //TODO 9673 break; 9674 case M4_kUnknown: 9675 break; 9676 default: 9677 break; 9678 } 9679 M4OSA_TRACE3_2( 9680 "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d", 9681 pC->AacProperties.aNumChan, 9682 pC->AacProperties.aSampFreq); 9683 } 9684 } 9685 9686 if( M4NO_ERROR != err ) 9687 { 9688 M4OSA_TRACE1_1( 9689 "M4MCS_intGetInputClipProperties:\ 9690 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 9691 err); 9692 return err; 9693 } 9694 } 9695 9696 //EVRC 9697 if( pC->pReaderAudioStream->m_basicProperties.m_streamType 9698 == M4DA_StreamTypeAudioEvrc ) 9699 { 9700 /* decoder not implemented yet, provide some default values for the null encoding */ 9701 pC->pReaderAudioStream->m_nbChannels = 1; 9702 pC->pReaderAudioStream->m_samplingFrequency = 8000; 9703 } 9704 9705 /** 9706 * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according 9707 the GetProperties function */ 9708 if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate ) 9709 { 9710 if( M4VIDEOEDITING_kAMR_NB 9711 == pC->InputFileProperties.AudioStreamType ) 9712 { 9713 /** 9714 * Better returning a guessed 12.2 kbps value than a sure-to-be-false 9715 0 kbps value! */ 9716 pC->InputFileProperties.uiAudioBitrate = 9717 M4VIDEOEDITING_k12_2_KBPS; 9718 } 9719 else if( M4VIDEOEDITING_kEVRC 9720 == pC->InputFileProperties.AudioStreamType ) 9721 { 9722 /** 9723 * Better returning a guessed 8.5 kbps value than a sure-to-be-false 9724 0 kbps value! */ 9725 pC->InputFileProperties.uiAudioBitrate = 9726 M4VIDEOEDITING_k9_2_KBPS; 9727 } 9728 else 9729 { 9730 M4OSA_UInt32 FileBitrate; 9731 9732 /* Can happen also for aac, in this case we calculate an approximative */ 9733 /* value from global bitrate and video bitrate */ 9734 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 9735 M4READER_kOptionID_Bitrate, 9736 (M4OSA_DataOption) &FileBitrate); 9737 9738 if( M4NO_ERROR != err ) 9739 { 9740 M4OSA_TRACE1_1( 9741 "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x", 9742 err); 9743 return err; 9744 } 9745 pC->InputFileProperties.uiAudioBitrate = 9746 FileBitrate 9747 - pC-> 9748 InputFileProperties. 9749 uiVideoBitrate /* normally setted to 0, if no video */; 9750 } 9751 } 9752 else 9753 { 9754 pC->InputFileProperties.uiAudioBitrate = 9755 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; 9756 } 9757 9758 pC->InputFileProperties.uiNbChannels = 9759 pC->pReaderAudioStream->m_nbChannels; 9760 pC->InputFileProperties.uiSamplingFrequency = 9761 pC->pReaderAudioStream->m_samplingFrequency; 9762 pC->InputFileProperties.uiClipAudioDuration = 9763 (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration; 9764 pC->InputFileProperties.uiAudioMaxAuSize = 9765 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize; 9766 9767 /* Bug: with aac, value is 0 until decoder start() is called */ 9768 pC->InputFileProperties.uiDecodedPcmSize = 9769 pC->pReaderAudioStream->m_byteFrameLength 9770 * pC->pReaderAudioStream->m_byteSampleSize 9771 * pC->pReaderAudioStream->m_nbChannels; 9772 9773 /* New aac properties */ 9774 if( M4DA_StreamTypeAudioAac 9775 == pC->pReaderAudioStream->m_basicProperties.m_streamType ) 9776 { 9777 pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan; 9778 pC->InputFileProperties.uiSamplingFrequency = 9779 pC->AacProperties.aSampFreq; 9780 9781 if( pC->AacProperties.aSBRPresent ) 9782 { 9783 pC->InputFileProperties.AudioStreamType = 9784 M4VIDEOEDITING_kAACplus; 9785 pC->InputFileProperties.uiExtendedSamplingFrequency = 9786 pC->AacProperties.aExtensionSampFreq; 9787 } 9788 9789 if( pC->AacProperties.aPSPresent ) 9790 { 9791 pC->InputFileProperties.AudioStreamType = 9792 M4VIDEOEDITING_keAACplus; 9793 } 9794 } 9795 } 9796 else 9797 { 9798 if( M4OSA_TRUE == pC->bUnsupportedAudioFound ) 9799 { 9800 pC->InputFileProperties.AudioStreamType = 9801 M4VIDEOEDITING_kUnsupportedAudio; 9802 } 9803 else 9804 { 9805 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; 9806 } 9807 } 9808 9809 /* Get 'ftyp' atom */ 9810 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 9811 M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp); 9812 9813 /* Analysis is successful */ 9814 if( pC->InputFileProperties.uiClipVideoDuration 9815 > pC->InputFileProperties.uiClipAudioDuration ) 9816 pC->InputFileProperties.uiClipDuration = 9817 pC->InputFileProperties.uiClipVideoDuration; 9818 else 9819 pC->InputFileProperties.uiClipDuration = 9820 pC->InputFileProperties.uiClipAudioDuration; 9821 9822 pC->InputFileProperties.FileType = pC->InputFileType; 9823 pC->InputFileProperties.bAnalysed = M4OSA_TRUE; 9824 9825 return M4NO_ERROR; 9826 } 9827 9828 /** 9829 ****************************************************************************** 9830 * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame) 9831 * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer 9832 * @note 9833 * @param pCpAudioFrame (IN) AMRNB frame 9834 * @return M4NO_ERROR: No error 9835 ****************************************************************************** 9836 */ 9837 static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame ) 9838 { 9839 M4OSA_UInt32 frameSize = 0; 9840 M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3; 9841 9842 switch( frameType ) 9843 { 9844 case 0: 9845 frameSize = 95; 9846 break; /* 4750 bps */ 9847 9848 case 1: 9849 frameSize = 103; 9850 break; /* 5150 bps */ 9851 9852 case 2: 9853 frameSize = 118; 9854 break; /* 5900 bps */ 9855 9856 case 3: 9857 frameSize = 134; 9858 break; /* 6700 bps */ 9859 9860 case 4: 9861 frameSize = 148; 9862 break; /* 7400 bps */ 9863 9864 case 5: 9865 frameSize = 159; 9866 break; /* 7950 bps */ 9867 9868 case 6: 9869 frameSize = 204; 9870 break; /* 10200 bps */ 9871 9872 case 7: 9873 frameSize = 244; 9874 break; /* 12000 bps */ 9875 9876 case 8: 9877 frameSize = 39; 9878 break; /* SID (Silence) */ 9879 9880 case 15: 9881 frameSize = 0; 9882 break; /* No data */ 9883 9884 default: 9885 M4OSA_TRACE3_0( 9886 "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0."); 9887 return 0; 9888 } 9889 9890 return (1 + (( frameSize + 7) / 8)); 9891 } 9892 9893 /** 9894 ****************************************************************************** 9895 * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame) 9896 * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer 9897 * @note 9898 * 0 1 2 3 9899 * +-+-+-+-+ 9900 * |fr type| RFC 3558 9901 * +-+-+-+-+ 9902 * 9903 * Frame Type: 4 bits 9904 * The frame type indicates the type of the corresponding codec data 9905 * frame in the RTP packet. 9906 * 9907 * For EVRC and SMV codecs, the frame type values and size of the 9908 * associated codec data frame are described in the table below: 9909 * 9910 * Value Rate Total codec data frame size (in octets) 9911 * --------------------------------------------------------- 9912 * 0 Blank 0 (0 bit) 9913 * 1 1/8 2 (16 bits) 9914 * 2 1/4 5 (40 bits; not valid for EVRC) 9915 * 3 1/2 10 (80 bits) 9916 * 4 1 22 (171 bits; 5 padded at end with zeros) 9917 * 5 Erasure 0 (SHOULD NOT be transmitted by sender) 9918 * 9919 * @param pCpAudioFrame (IN) EVRC frame 9920 * @return M4NO_ERROR: No error 9921 ****************************************************************************** 9922 */ 9923 static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) 9924 { 9925 M4OSA_UInt32 frameSize = 0; 9926 M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F; 9927 9928 switch( frameType ) 9929 { 9930 case 0: 9931 frameSize = 0; 9932 break; /* blank */ 9933 9934 case 1: 9935 frameSize = 16; 9936 break; /* 1/8 */ 9937 9938 case 2: 9939 frameSize = 40; 9940 break; /* 1/4 */ 9941 9942 case 3: 9943 frameSize = 80; 9944 break; /* 1/2 */ 9945 9946 case 4: 9947 frameSize = 171; 9948 break; /* 1 */ 9949 9950 case 5: 9951 frameSize = 0; 9952 break; /* erasure */ 9953 9954 default: 9955 M4OSA_TRACE3_0( 9956 "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0."); 9957 return 0; 9958 } 9959 9960 return (1 + (( frameSize + 7) / 8)); 9961 } 9962 9963 /** 9964 ****************************************************************************** 9965 * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext) 9966 * @brief Check if max file size is greater enough to encode a file with the 9967 * current selected bitrates and duration. 9968 * @param pContext (IN) MCS context 9969 * @return M4NO_ERROR 9970 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL 9971 ****************************************************************************** 9972 */ 9973 static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext ) 9974 { 9975 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 9976 9977 M4OSA_UInt32 duration; 9978 M4OSA_UInt32 audiobitrate; 9979 M4OSA_UInt32 videobitrate; 9980 9981 /* free file size : OK */ 9982 if( pC->uiMaxFileSize == 0 ) 9983 return M4NO_ERROR; 9984 9985 /* duration */ 9986 if( pC->uiEndCutTime == 0 ) 9987 { 9988 duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime; 9989 } 9990 else 9991 { 9992 duration = pC->uiEndCutTime - pC->uiBeginCutTime; 9993 } 9994 9995 /* audio bitrate */ 9996 if( pC->noaudio ) 9997 { 9998 audiobitrate = 0; 9999 } 10000 else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 10001 { 10002 audiobitrate = pC->InputFileProperties.uiAudioBitrate; 10003 } 10004 else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate ) 10005 { 10006 switch( pC->AudioEncParams.Format ) 10007 { 10008 case M4ENCODER_kAMRNB: 10009 audiobitrate = M4VIDEOEDITING_k12_2_KBPS; 10010 break; 10011 //EVRC 10012 // case M4ENCODER_kEVRC: 10013 // audiobitrate = M4VIDEOEDITING_k9_2_KBPS; 10014 // break; 10015 10016 default: /* AAC and MP3*/ 10017 audiobitrate = 10018 (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 10019 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; 10020 break; 10021 } 10022 } 10023 else 10024 { 10025 audiobitrate = pC->uiAudioBitrate; 10026 } 10027 10028 /* video bitrate */ 10029 if( pC->novideo ) 10030 { 10031 videobitrate = 0; 10032 } 10033 else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 10034 { 10035 videobitrate = pC->InputFileProperties.uiVideoBitrate; 10036 } 10037 else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate ) 10038 { 10039 videobitrate = M4VIDEOEDITING_k16_KBPS; 10040 } 10041 else 10042 { 10043 videobitrate = pC->uiVideoBitrate; 10044 } 10045 10046 /* max file size */ 10047 if( (M4OSA_UInt32)pC->uiMaxFileSize 10048 < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO 10049 * (audiobitrate + videobitrate) * (duration / 8000.0)) ) 10050 return M4MCS_ERR_MAXFILESIZE_TOO_SMALL; 10051 else 10052 return M4NO_ERROR; 10053 } 10054 10055 /** 10056 ****************************************************************************** 10057 * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode) 10058 * @brief Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate 10059 * @param freebitrate: unsigned int value 10060 * @param mode: -1:previous,0:current,1:next 10061 * @return bitrate value in enum list M4VIDEOEDITING_Bitrate 10062 ****************************************************************************** 10063 */ 10064 static M4VIDEOEDITING_Bitrate 10065 M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode ) 10066 { 10067 M4OSA_Int32 bitarray [] = 10068 { 10069 0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS, 10070 M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS, 10071 M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS, 10072 M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS, 10073 M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS, 10074 M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS, 10075 M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS, 10076 M4VIDEOEDITING_k5_MBPS, 10077 M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */ 10078 M4OSA_INT32_MAX 10079 }; 10080 10081 const M4OSA_UInt32 nbbitrates = 14; 10082 M4OSA_UInt32 i; 10083 10084 for ( i = 0; freebitrate >= bitarray[i]; i++ ); 10085 10086 switch( mode ) 10087 { 10088 case -1: /* previous */ 10089 if( i <= 2 ) 10090 return 0; 10091 else 10092 return bitarray[i - 2]; 10093 break; 10094 10095 case 0: /* current */ 10096 if( i <= 1 ) 10097 return 0; 10098 else 10099 return bitarray[i - 1]; 10100 break; 10101 10102 case 1: /* next */ 10103 if( i >= nbbitrates ) 10104 return M4OSA_INT32_MAX; 10105 else 10106 return bitarray[i]; 10107 break; 10108 } 10109 10110 return 0; 10111 } 10112 10113 /** 10114 ****************************************************************************** 10115 * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC); 10116 * @brief Free all resources allocated by M4MCS_open() 10117 * @param pContext (IN) MCS context 10118 * @return M4NO_ERROR: No error 10119 ****************************************************************************** 10120 */ 10121 static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC ) 10122 { 10123 M4OSA_ERR err = M4NO_ERROR; 10124 10125 M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC); 10126 10127 /**/ 10128 /* ----- Free video decoder stuff, if needed ----- */ 10129 10130 if( M4OSA_NULL != pC->pViDecCtxt ) 10131 { 10132 err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); 10133 pC->pViDecCtxt = M4OSA_NULL; 10134 10135 if( M4NO_ERROR != err ) 10136 { 10137 M4OSA_TRACE1_1( 10138 "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x", 10139 err); 10140 /**< don't return, we still have stuff to free */ 10141 } 10142 } 10143 10144 /* ----- Free the audio decoder stuff ----- */ 10145 10146 if( M4OSA_NULL != pC->pAudioDecCtxt ) 10147 { 10148 err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt); 10149 pC->pAudioDecCtxt = M4OSA_NULL; 10150 10151 if( M4NO_ERROR != err ) 10152 { 10153 M4OSA_TRACE1_1( 10154 "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 10155 err); 10156 /**< don't return, we still have stuff to free */ 10157 } 10158 } 10159 10160 if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress ) 10161 { 10162 free(pC->AudioDecBufferOut.m_dataAddress); 10163 pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 10164 } 10165 10166 /* ----- Free reader stuff, if needed ----- */ 10167 // We cannot free the reader before decoders because the decoders may read 10168 // from the reader (in another thread) before being stopped. 10169 10170 if( M4OSA_NULL != pC-> 10171 pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */ 10172 { 10173 err = pC->m_pReader->m_pFctClose(pC->pReaderContext); 10174 10175 if( M4NO_ERROR != err ) 10176 { 10177 M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x", 10178 err); 10179 /**< don't return, we still have stuff to free */ 10180 } 10181 10182 err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext); 10183 pC->pReaderContext = M4OSA_NULL; 10184 10185 if( M4NO_ERROR != err ) 10186 { 10187 M4OSA_TRACE1_1( 10188 "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err); 10189 /**< don't return, we still have stuff to free */ 10190 } 10191 } 10192 10193 if( pC->m_pDataAddress1 != M4OSA_NULL ) 10194 { 10195 free(pC->m_pDataAddress1); 10196 pC->m_pDataAddress1 = M4OSA_NULL; 10197 } 10198 10199 if( pC->m_pDataAddress2 != M4OSA_NULL ) 10200 { 10201 free(pC->m_pDataAddress2); 10202 pC->m_pDataAddress2 = M4OSA_NULL; 10203 } 10204 /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/ 10205 if( pC->m_pDataVideoAddress1 != M4OSA_NULL ) 10206 { 10207 free(pC->m_pDataVideoAddress1); 10208 pC->m_pDataVideoAddress1 = M4OSA_NULL; 10209 } 10210 10211 if( pC->m_pDataVideoAddress2 != M4OSA_NULL ) 10212 { 10213 free(pC->m_pDataVideoAddress2); 10214 pC->m_pDataVideoAddress2 = M4OSA_NULL; 10215 } 10216 10217 return M4NO_ERROR; 10218 } 10219 10220 10221 /** 10222 10223 ****************************************************************************** 10224 * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, 10225 * M4OSA_Void* pFileOut, M4OSA_Void* pTempFile); 10226 * @brief Set the MCS input and output files. It is the same as M4MCS_open without 10227 * M4MCS_WITH_FAST_OPEN flag 10228 It is used in VideoArtist 10229 * @note It opens the input file, but the output file is not created yet. 10230 * @param pContext (IN) MCS context 10231 * @param pFileIn (IN) Input file to transcode (The type of this parameter 10232 * (URL, pipe...) depends on the OSAL implementation). 10233 * @param mediaType (IN) Container type (.3gp,.amr, ...) of input file. 10234 * @param pFileOut (IN) Output file to create (The type of this parameter 10235 * (URL, pipe...) depends on the OSAL implementation). 10236 * @param pTempFile (IN) Temporary file for the constant memory writer to store 10237 * metadata ("moov.bin"). 10238 * @return M4NO_ERROR: No error 10239 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 10240 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 10241 * @return M4ERR_ALLOC: There is no more available memory 10242 * @return M4ERR_FILE_NOT_FOUND: The input file has not been found 10243 * @return M4MCS_ERR_INVALID_INPUT_FILE: The input file is not a valid file, or is corrupted 10244 * @return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM: The input file contains no 10245 * supported audio or video stream 10246 ****************************************************************************** 10247 */ 10248 M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, 10249 M4VIDEOEDITING_FileType InputFileType, 10250 M4OSA_Void* pFileOut, M4OSA_Void* pTempFile) 10251 { 10252 M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext); 10253 M4OSA_ERR err; 10254 10255 M4READER_MediaFamily mediaFamily; 10256 M4_StreamHandler* pStreamHandler; 10257 10258 M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\ 10259 pFileOut=0x%x", pContext, pFileIn, pFileOut); 10260 10261 /** 10262 * Check input parameters */ 10263 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 10264 "M4MCS_open_normalMode: pContext is M4OSA_NULL"); 10265 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER, 10266 "M4MCS_open_normalMode: pFileIn is M4OSA_NULL"); 10267 10268 if ((InputFileType == M4VIDEOEDITING_kFileType_JPG) 10269 ||(InputFileType == M4VIDEOEDITING_kFileType_PNG) 10270 ||(InputFileType == M4VIDEOEDITING_kFileType_GIF) 10271 ||(InputFileType == M4VIDEOEDITING_kFileType_BMP)) 10272 { 10273 M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\ 10274 supported with this function"); 10275 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 10276 } 10277 10278 /** 10279 * Check state automaton */ 10280 if (M4MCS_kState_CREATED != pC->State) 10281 { 10282 M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE", 10283 pC->State); 10284 return M4ERR_STATE; 10285 } 10286 10287 /* Copy function input parameters into our context */ 10288 pC->pInputFile = pFileIn; 10289 pC->InputFileType = InputFileType; 10290 pC->pOutputFile = pFileOut; 10291 pC->pTemporaryFile = pTempFile; 10292 10293 /***********************************/ 10294 /* Open input file with the reader */ 10295 /***********************************/ 10296 10297 err = M4MCS_setCurrentReader(pContext, pC->InputFileType); 10298 M4ERR_CHECK_RETURN(err); 10299 10300 /** 10301 * Reset reader related variables */ 10302 pC->VideoState = M4MCS_kStreamState_NOSTREAM; 10303 pC->AudioState = M4MCS_kStreamState_NOSTREAM; 10304 pC->pReaderVideoStream = M4OSA_NULL; 10305 pC->pReaderAudioStream = M4OSA_NULL; 10306 10307 /*******************************************************/ 10308 /* Initializes the reader shell and open the data file */ 10309 /*******************************************************/ 10310 err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext); 10311 if (M4NO_ERROR != err) 10312 { 10313 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err); 10314 return err; 10315 } 10316 10317 /** 10318 * Link the reader interface to the reader context */ 10319 pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext; 10320 10321 /** 10322 * Set the reader shell file access functions */ 10323 err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, 10324 M4READER_kOptionID_SetOsaFileReaderFctsPtr, 10325 (M4OSA_DataOption)pC->pOsaFileReadPtr); 10326 if (M4NO_ERROR != err) 10327 { 10328 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err); 10329 return err; 10330 } 10331 10332 /** 10333 * Open the input file */ 10334 err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile); 10335 if (M4NO_ERROR != err) 10336 { 10337 M4OSA_UInt32 uiDummy, uiCoreId; 10338 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err); 10339 10340 if (err == ((M4OSA_UInt32)M4ERR_UNSUPPORTED_MEDIA_TYPE)) { 10341 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_FILE_DRM_PROTECTED"); 10342 return M4MCS_ERR_FILE_DRM_PROTECTED; 10343 } else { 10344 /** 10345 * If the error is from the core reader, we change it to a public VXS error */ 10346 M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); 10347 if (M4MP4_READER == uiCoreId) 10348 { 10349 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE"); 10350 return M4MCS_ERR_INVALID_INPUT_FILE; 10351 } 10352 } 10353 return err; 10354 } 10355 10356 /** 10357 * Get the streams from the input file */ 10358 while (M4NO_ERROR == err) 10359 { 10360 err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily, 10361 &pStreamHandler); 10362 10363 /** 10364 * In case we found a BIFS stream or something else...*/ 10365 if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) 10366 || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))) 10367 { 10368 err = M4NO_ERROR; 10369 continue; 10370 } 10371 10372 if (M4NO_ERROR == err) /**< One stream found */ 10373 { 10374 /** 10375 * Found the first video stream */ 10376 if ((M4READER_kMediaFamilyVideo == mediaFamily) \ 10377 && (M4OSA_NULL == pC->pReaderVideoStream)) 10378 { 10379 if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) || 10380 (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType) 10381 #ifdef M4VSS_SUPPORT_VIDEO_AVC 10382 ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)) 10383 #else 10384 ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType) 10385 &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL))) 10386 #endif 10387 { 10388 M4OSA_TRACE3_0("M4MCS_open_normalMode():\ 10389 Found a H263 or MPEG-4 video stream in input 3gpp clip"); 10390 10391 /** 10392 * Keep pointer to the video stream */ 10393 pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler; 10394 pC->bUnsupportedVideoFound = M4OSA_FALSE; 10395 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 10396 10397 /** 10398 * Init our video stream state variable */ 10399 pC->VideoState = M4MCS_kStreamState_STARTED; 10400 10401 /** 10402 * Reset the stream reader */ 10403 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 10404 (M4_StreamHandler*)pC->pReaderVideoStream); 10405 if (M4NO_ERROR != err) 10406 { 10407 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10408 m_pReader->m_pFctReset(video) returns 0x%x", err); 10409 return err; 10410 } 10411 10412 /** 10413 * Initializes an access Unit */ 10414 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, 10415 &pC->ReaderVideoAU); 10416 if (M4NO_ERROR != err) 10417 { 10418 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10419 m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err); 10420 return err; 10421 } 10422 } 10423 else /**< Not H263 or MPEG-4 (H264, etc.) */ 10424 { 10425 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10426 Found an unsupported video stream (0x%x) in input 3gpp clip", 10427 pStreamHandler->m_streamType); 10428 10429 pC->bUnsupportedVideoFound = M4OSA_TRUE; 10430 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 10431 } 10432 } 10433 /** 10434 * Found the first audio stream */ 10435 else if ((M4READER_kMediaFamilyAudio == mediaFamily) 10436 && (M4OSA_NULL == pC->pReaderAudioStream)) 10437 { 10438 if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) || 10439 (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) || 10440 (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) || 10441 (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) ) 10442 { 10443 M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \ 10444 or MP3 audio stream in input clip"); 10445 10446 /** 10447 * Keep pointer to the audio stream */ 10448 pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler; 10449 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 10450 pC->bUnsupportedAudioFound = M4OSA_FALSE; 10451 10452 /** 10453 * Init our audio stream state variable */ 10454 pC->AudioState = M4MCS_kStreamState_STARTED; 10455 10456 /** 10457 * Reset the stream reader */ 10458 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 10459 (M4_StreamHandler*)pC->pReaderAudioStream); 10460 if (M4NO_ERROR != err) 10461 { 10462 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10463 m_pReader->m_pFctReset(audio) returns 0x%x", err); 10464 return err; 10465 } 10466 10467 /** 10468 * Initializes an access Unit */ 10469 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, 10470 &pC->ReaderAudioAU); 10471 if (M4NO_ERROR != err) 10472 { 10473 M4OSA_TRACE1_1("M4MCS_open_normalMode(): \ 10474 m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err); 10475 return err; 10476 } 10477 10478 /** 10479 * Output max AU size is equal to input max AU size (this value 10480 * will be changed if there is audio transcoding) */ 10481 pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize; 10482 10483 } 10484 else 10485 { 10486 /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */ 10487 M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\ 10488 (0x%x) in input 3gpp clip", pStreamHandler->m_streamType); 10489 10490 pC->bUnsupportedAudioFound = M4OSA_TRUE; 10491 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 10492 } 10493 } 10494 } 10495 } /**< end of while (M4NO_ERROR == err) */ 10496 10497 /** 10498 * Check we found at least one supported stream */ 10499 if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream)) 10500 { 10501 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \ 10502 M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM"); 10503 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 10504 } 10505 10506 #ifndef M4VSS_ENABLE_EXTERNAL_DECODERS 10507 if(pC->VideoState == M4MCS_kStreamState_STARTED) 10508 { 10509 err = M4MCS_setCurrentVideoDecoder(pContext, 10510 pC->pReaderVideoStream->m_basicProperties.m_streamType); 10511 M4ERR_CHECK_RETURN(err); 10512 } 10513 #endif 10514 10515 if(pC->AudioState == M4MCS_kStreamState_STARTED) 10516 { 10517 //EVRC 10518 if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType) 10519 /* decoder not supported yet, but allow to do null encoding */ 10520 { 10521 err = M4MCS_setCurrentAudioDecoder(pContext, 10522 pC->pReaderAudioStream->m_basicProperties.m_streamType); 10523 M4ERR_CHECK_RETURN(err); 10524 } 10525 } 10526 10527 /** 10528 * Get the audio and video stream properties */ 10529 err = M4MCS_intGetInputClipProperties(pC); 10530 if (M4NO_ERROR != err) 10531 { 10532 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10533 M4MCS_intGetInputClipProperties returns 0x%x", err); 10534 return err; 10535 } 10536 10537 /** 10538 * Set the begin cut decoding increment according to the input frame rate */ 10539 if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */ 10540 { 10541 pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \ 10542 / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */ 10543 } 10544 else 10545 { 10546 pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/ 10547 } 10548 10549 /** 10550 * Update state automaton */ 10551 pC->State = M4MCS_kState_OPENED; 10552 10553 /** 10554 * Return with no error */ 10555 M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR"); 10556 return M4NO_ERROR; 10557 } 10558 10559 M4OSA_ERR M4MCS_intCheckAndGetCodecProperties( 10560 M4MCS_InternalContext *pC) { 10561 10562 M4OSA_ERR err = M4NO_ERROR; 10563 M4AD_Buffer outputBuffer; 10564 uint32_t optionValue =0; 10565 10566 M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecProperties :start"); 10567 10568 // Decode first audio frame from clip to get properties from codec 10569 10570 if (M4DA_StreamTypeAudioAac == 10571 pC->pReaderAudioStream->m_basicProperties.m_streamType) { 10572 10573 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 10574 &pC->pAudioDecCtxt, 10575 pC->pReaderAudioStream, &(pC->AacProperties)); 10576 } else { 10577 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 10578 &pC->pAudioDecCtxt, 10579 pC->pReaderAudioStream, 10580 pC->m_pCurrentAudioDecoderUserData); 10581 } 10582 if (M4NO_ERROR != err) { 10583 10584 M4OSA_TRACE1_1( 10585 "M4MCS_intCheckAndGetCodecProperties: m_pFctCreateAudioDec \ 10586 returns 0x%x", err); 10587 return err; 10588 } 10589 10590 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 10591 M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); 10592 10593 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 10594 M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); 10595 10596 if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { 10597 10598 err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); 10599 if( M4NO_ERROR != err ) { 10600 10601 M4OSA_TRACE1_1( 10602 "M4MCS_intCheckAndGetCodecProperties: m_pFctStartAudioDec \ 10603 returns 0x%x", err); 10604 return err; 10605 } 10606 } 10607 10608 /** 10609 * Allocate output buffer for the audio decoder */ 10610 outputBuffer.m_bufferSize = 10611 pC->pReaderAudioStream->m_byteFrameLength 10612 * pC->pReaderAudioStream->m_byteSampleSize 10613 * pC->pReaderAudioStream->m_nbChannels; 10614 10615 if( outputBuffer.m_bufferSize > 0 ) { 10616 10617 outputBuffer.m_dataAddress = 10618 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \ 10619 *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize"); 10620 10621 if( M4OSA_NULL == outputBuffer.m_dataAddress ) { 10622 10623 M4OSA_TRACE1_0( 10624 "M4MCS_intCheckAndGetCodecProperties():\ 10625 unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC"); 10626 return M4ERR_ALLOC; 10627 } 10628 } 10629 10630 err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, 10631 M4OSA_NULL, &outputBuffer, M4OSA_FALSE); 10632 10633 if ( err == M4WAR_INFO_FORMAT_CHANGE ) { 10634 10635 // Get the properties from codec node 10636 pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, 10637 M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue); 10638 10639 // Reset Reader structure value also 10640 pC->pReaderAudioStream->m_nbChannels = optionValue; 10641 10642 pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, 10643 M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue); 10644 10645 // Reset Reader structure value also 10646 pC->pReaderAudioStream->m_samplingFrequency = optionValue; 10647 10648 if (M4DA_StreamTypeAudioAac == 10649 pC->pReaderAudioStream->m_basicProperties.m_streamType) { 10650 10651 pC->AacProperties.aNumChan = 10652 pC->pReaderAudioStream->m_nbChannels; 10653 pC->AacProperties.aSampFreq = 10654 pC->pReaderAudioStream->m_samplingFrequency; 10655 10656 } 10657 10658 } else if( err != M4NO_ERROR) { 10659 M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties:\ 10660 m_pFctStepAudioDec returns err = 0x%x", err); 10661 } 10662 10663 free(outputBuffer.m_dataAddress); 10664 10665 // Reset the stream reader 10666 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 10667 (M4_StreamHandler *)pC->pReaderAudioStream); 10668 10669 if (M4NO_ERROR != err) { 10670 M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties\ 10671 Error in reseting reader: 0x%x", err); 10672 } 10673 10674 return err; 10675 10676 } 10677 10678 M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel( 10679 M4ENCODER_AdvancedParams* EncParams) { 10680 10681 M4OSA_ERR err = M4NO_ERROR; 10682 10683 switch (EncParams->Format) { 10684 case M4ENCODER_kH263: 10685 EncParams->Bitrate = M4MCS_intLimitBitrateForH263Enc( 10686 EncParams->videoProfile, 10687 EncParams->videoLevel, EncParams->Bitrate); 10688 break; 10689 10690 case M4ENCODER_kMPEG4: 10691 EncParams->Bitrate = M4MCS_intLimitBitrateForMpeg4Enc( 10692 EncParams->videoProfile, 10693 EncParams->videoLevel, EncParams->Bitrate); 10694 break; 10695 10696 case M4ENCODER_kH264: 10697 EncParams->Bitrate = M4MCS_intLimitBitrateForH264Enc( 10698 EncParams->videoProfile, 10699 EncParams->videoLevel, EncParams->Bitrate); 10700 break; 10701 10702 default: 10703 M4OSA_TRACE1_1("M4MCS_intLimitBitratePerCodecProfileLevel: \ 10704 Wrong enc format %d", EncParams->Format); 10705 err = M4ERR_PARAMETER; 10706 break; 10707 } 10708 10709 return err; 10710 10711 } 10712 10713 M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile, 10714 M4OSA_Int32 level, M4OSA_Int32 bitrate) { 10715 10716 M4OSA_Int32 vidBitrate = 0; 10717 10718 switch (profile) { 10719 case OMX_VIDEO_AVCProfileBaseline: 10720 case OMX_VIDEO_AVCProfileMain: 10721 10722 switch (level) { 10723 10724 case OMX_VIDEO_AVCLevel1: 10725 vidBitrate = (bitrate > 64000) ? 64000 : bitrate; 10726 break; 10727 10728 case OMX_VIDEO_AVCLevel1b: 10729 vidBitrate = (bitrate > 128000) ? 128000 : bitrate; 10730 break; 10731 10732 case OMX_VIDEO_AVCLevel11: 10733 vidBitrate = (bitrate > 192000) ? 192000 : bitrate; 10734 break; 10735 10736 case OMX_VIDEO_AVCLevel12: 10737 vidBitrate = (bitrate > 384000) ? 384000 : bitrate; 10738 break; 10739 10740 case OMX_VIDEO_AVCLevel13: 10741 vidBitrate = (bitrate > 768000) ? 768000 : bitrate; 10742 break; 10743 10744 case OMX_VIDEO_AVCLevel2: 10745 vidBitrate = (bitrate > 2000000) ? 2000000 : bitrate; 10746 break; 10747 10748 case OMX_VIDEO_AVCLevel21: 10749 vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate; 10750 break; 10751 10752 case OMX_VIDEO_AVCLevel22: 10753 vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate; 10754 break; 10755 10756 case OMX_VIDEO_AVCLevel3: 10757 vidBitrate = (bitrate > 10000000) ? 10000000 : bitrate; 10758 break; 10759 10760 case OMX_VIDEO_AVCLevel31: 10761 vidBitrate = (bitrate > 14000000) ? 14000000 : bitrate; 10762 break; 10763 10764 case OMX_VIDEO_AVCLevel32: 10765 vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate; 10766 break; 10767 10768 case OMX_VIDEO_AVCLevel4: 10769 vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate; 10770 break; 10771 10772 case OMX_VIDEO_AVCLevel41: 10773 vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate; 10774 break; 10775 10776 case OMX_VIDEO_AVCLevel42: 10777 vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate; 10778 break; 10779 10780 case OMX_VIDEO_AVCLevel5: 10781 vidBitrate = (bitrate > 135000000) ? 135000000 : bitrate; 10782 break; 10783 10784 case OMX_VIDEO_AVCLevel51: 10785 vidBitrate = (bitrate > 240000000) ? 240000000 : bitrate; 10786 break; 10787 10788 default: 10789 vidBitrate = bitrate; 10790 break; 10791 } 10792 break; 10793 10794 case OMX_VIDEO_AVCProfileHigh: 10795 switch (level) { 10796 case OMX_VIDEO_AVCLevel1: 10797 vidBitrate = (bitrate > 80000) ? 80000 : bitrate; 10798 break; 10799 10800 case OMX_VIDEO_AVCLevel1b: 10801 vidBitrate = (bitrate > 160000) ? 160000 : bitrate; 10802 break; 10803 10804 case OMX_VIDEO_AVCLevel11: 10805 vidBitrate = (bitrate > 240000) ? 240000 : bitrate; 10806 break; 10807 10808 case OMX_VIDEO_AVCLevel12: 10809 vidBitrate = (bitrate > 480000) ? 480000 : bitrate; 10810 break; 10811 10812 case OMX_VIDEO_AVCLevel13: 10813 vidBitrate = (bitrate > 960000) ? 960000 : bitrate; 10814 break; 10815 10816 case OMX_VIDEO_AVCLevel2: 10817 vidBitrate = (bitrate > 2500000) ? 2500000 : bitrate; 10818 break; 10819 10820 case OMX_VIDEO_AVCLevel21: 10821 vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate; 10822 break; 10823 10824 case OMX_VIDEO_AVCLevel22: 10825 vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate; 10826 break; 10827 10828 case OMX_VIDEO_AVCLevel3: 10829 vidBitrate = (bitrate > 12500000) ? 12500000 : bitrate; 10830 break; 10831 10832 case OMX_VIDEO_AVCLevel31: 10833 vidBitrate = (bitrate > 17500000) ? 17500000 : bitrate; 10834 break; 10835 10836 case OMX_VIDEO_AVCLevel32: 10837 vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate; 10838 break; 10839 10840 case OMX_VIDEO_AVCLevel4: 10841 vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate; 10842 break; 10843 10844 case OMX_VIDEO_AVCLevel41: 10845 vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate; 10846 break; 10847 10848 case OMX_VIDEO_AVCLevel42: 10849 vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate; 10850 break; 10851 10852 case OMX_VIDEO_AVCLevel5: 10853 vidBitrate = (bitrate > 168750000) ? 168750000 : bitrate; 10854 break; 10855 10856 case OMX_VIDEO_AVCLevel51: 10857 vidBitrate = (bitrate > 300000000) ? 300000000 : bitrate; 10858 break; 10859 10860 default: 10861 vidBitrate = bitrate; 10862 break; 10863 } 10864 break; 10865 10866 default: 10867 // We do not handle any other AVC profile for now. 10868 // Return input bitrate 10869 vidBitrate = bitrate; 10870 break; 10871 } 10872 10873 return vidBitrate; 10874 } 10875 10876 M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile, 10877 M4OSA_Int32 level, M4OSA_Int32 bitrate) { 10878 10879 M4OSA_Int32 vidBitrate = 0; 10880 10881 switch (profile) { 10882 case OMX_VIDEO_MPEG4ProfileSimple: 10883 switch (level) { 10884 10885 case OMX_VIDEO_MPEG4Level0: 10886 vidBitrate = (bitrate > 64000) ? 64000 : bitrate; 10887 break; 10888 10889 case OMX_VIDEO_MPEG4Level0b: 10890 vidBitrate = (bitrate > 128000) ? 128000 : bitrate; 10891 break; 10892 10893 case OMX_VIDEO_MPEG4Level1: 10894 vidBitrate = (bitrate > 64000) ? 64000 : bitrate; 10895 break; 10896 10897 case OMX_VIDEO_MPEG4Level2: 10898 vidBitrate = (bitrate > 128000) ? 128000 : bitrate; 10899 break; 10900 10901 case OMX_VIDEO_MPEG4Level3: 10902 vidBitrate = (bitrate > 384000) ? 384000 : bitrate; 10903 break; 10904 10905 default: 10906 vidBitrate = bitrate; 10907 break; 10908 } 10909 break; 10910 10911 default: 10912 // We do not handle any other MPEG4 profile for now. 10913 // Return input bitrate 10914 vidBitrate = bitrate; 10915 break; 10916 } 10917 10918 return vidBitrate; 10919 } 10920 10921 M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile, 10922 M4OSA_Int32 level, M4OSA_Int32 bitrate) { 10923 10924 M4OSA_Int32 vidBitrate = 0; 10925 10926 switch (profile) { 10927 case OMX_VIDEO_H263ProfileBaseline: 10928 switch (level) { 10929 10930 case OMX_VIDEO_H263Level10: 10931 vidBitrate = (bitrate > 64000) ? 64000 : bitrate; 10932 break; 10933 10934 case OMX_VIDEO_H263Level20: 10935 vidBitrate = (bitrate > 128000) ? 128000 : bitrate; 10936 break; 10937 10938 case OMX_VIDEO_H263Level30: 10939 vidBitrate = (bitrate > 384000) ? 384000 : bitrate; 10940 break; 10941 10942 default: 10943 vidBitrate = bitrate; 10944 break; 10945 } 10946 break; 10947 10948 default: 10949 // We do not handle any other H263 profile for now. 10950 // Return input bitrate 10951 vidBitrate = bitrate; 10952 break; 10953 } 10954 10955 return vidBitrate; 10956 } 10957