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