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