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