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