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