M4MCS_API.c revision 7c9d8018755adf1857571125ba1b3598c96ea506
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 "gLVAudioResampler.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_malloc(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( !M4OSA_memcmp((M4OSA_MemAddr8)inbuff, 760 (M4OSA_MemAddr8)"\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_malloc(inbuf_size + 4, M4MCS, 772 (M4OSA_Char *)"tmpNALU"); 773 M4OSA_memcpy((M4OSA_MemAddr8)(pTmpBuff1 + 4), (M4OSA_MemAddr8)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 M4OSA_free((M4OSA_MemAddr32)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_malloc(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 M4OSA_memcpy((M4OSA_MemAddr8)instance->m_pFinalDSI, 1580 (M4OSA_MemAddr8)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_malloc(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 M4OSA_memcpy((M4OSA_MemAddr8)instance->m_pFinalDSI, 1609 (M4OSA_MemAddr8)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 M4OSA_memcpy((M4OSA_MemAddr8) &outbuff[outbuffpos], 1959 (M4OSA_MemAddr8)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 M4OSA_free((M4OSA_MemAddr32)instance->encoder_pps.slice_group_id); 2040 } 2041 2042 if( M4OSA_NULL != instance->p_encoder_sps ) 2043 { 2044 M4OSA_free((M4OSA_MemAddr32)instance->p_encoder_sps); 2045 instance->p_encoder_sps = M4OSA_NULL; 2046 } 2047 2048 if( M4OSA_NULL != instance->p_encoder_pps ) 2049 { 2050 M4OSA_free((M4OSA_MemAddr32)instance->p_encoder_pps); 2051 instance->p_encoder_pps = M4OSA_NULL; 2052 } 2053 2054 if( M4OSA_NULL != instance->m_pFinalDSI ) 2055 { 2056 M4OSA_free((M4OSA_MemAddr32)instance->m_pFinalDSI); 2057 instance->m_pFinalDSI = M4OSA_NULL; 2058 } 2059 2060 if( M4OSA_NULL != instance ) 2061 { 2062 M4OSA_free((M4OSA_MemAddr32)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_malloc(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 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#ifdef TIMESCALE_BUG 2255 2256 /* By default, timescale is not modified; if this value is not 0, timescale is 2257 * modified without decode/encode process 2258 */ 2259 pC->uiVideoTimescale = 0; 2260 pC->uiTimescaleLength = 0; 2261 pC->uiOrigVideoTimescale = 0; 2262 pC->uiOrigTimescaleLength = 0; 2263 2264#endif 2265 2266 pC->WriterVideoStream.streamType = M4SYS_kVideoUnknown; 2267 pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL; 2268 pC->WriterAudioStream.streamType = M4SYS_kAudioUnknown; 2269 2270 pC->outputVideoTimescale = 0; 2271 2272 /*FB 2008/10/20: add media rendering parameter and AIR context to keep media aspect ratio*/ 2273 pC->MediaRendering = M4MCS_kResizing; 2274 pC->m_air_context = M4OSA_NULL; 2275 /**/ 2276 2277 /** 2278 * FlB 2009.03.04: add audio Effects*/ 2279 pC->pEffects = M4OSA_NULL; 2280 pC->nbEffects = 0; 2281 pC->pActiveEffectNumber = -1; 2282 /**/ 2283 2284 /* 2285 * Reset pointers for media and codecs interfaces */ 2286 err = M4MCS_clearInterfaceTables(pC); 2287 M4ERR_CHECK_RETURN(err); 2288 2289 /* 2290 * Call the media and codecs subscription module */ 2291 err = M4MCS_subscribeMediaAndCodec(pC); 2292 M4ERR_CHECK_RETURN(err); 2293 2294#ifdef M4MCS_SUPPORT_STILL_PICTURE 2295 /** 2296 * Initialize the Still picture part of MCS*/ 2297 2298 err = M4MCS_stillPicInit(pC, pFileReadPtrFct, pFileWritePtrFct); 2299 M4ERR_CHECK_RETURN(err); 2300 2301 pC->m_bIsStillPicture = M4OSA_FALSE; 2302 2303#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 2304 2305 pC->m_pInstance = M4OSA_NULL; 2306 pC->H264MCSTempBuffer = M4OSA_NULL; 2307 pC->H264MCSTempBufferSize = 0; 2308 pC->H264MCSTempBufferDataSize = 0; 2309 pC->bH264Trim = M4OSA_FALSE; 2310 2311 /* Flag to get the last decoded frame cts */ 2312 pC->bLastDecodedFrameCTS = M4OSA_FALSE; 2313 2314 if( pC->m_pInstance == M4OSA_NULL ) 2315 { 2316 err = H264MCS_Getinstance(&pC->m_pInstance); 2317 } 2318 pC->bExtOMXAudDecoder = M4OSA_FALSE; 2319 2320 /** 2321 * Return with no error */ 2322 M4OSA_TRACE3_0("M4MCS_init(): returning M4NO_ERROR"); 2323 return M4NO_ERROR; 2324} 2325 2326/** 2327 ****************************************************************************** 2328 * M4OSA_ERR M4MCS_open(M4MCS_Context pContext, M4OSA_Void* pFileIn, 2329 * M4OSA_Void* pFileOut, M4OSA_Void* pTempFile); 2330 * @brief Set the MCS input and output files. 2331 * @note It opens the input file, but the output file is not created yet. 2332 * @param pContext (IN) MCS context 2333 * @param pFileIn (IN) Input file to transcode (The type of this parameter 2334 * (URL, pipe...) depends on the OSAL implementation). 2335 * @param mediaType (IN) Container type (.3gp,.amr,mp3 ...) of input file. 2336 * @param pFileOut (IN) Output file to create (The type of this parameter 2337 * (URL, pipe...) depends on the OSAL implementation). 2338 * @param pTempFile (IN) Temporary file for the constant memory writer to 2339 * store metadata ("moov.bin"). 2340 * @return M4NO_ERROR: No error 2341 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 2342 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 2343 * @return M4ERR_ALLOC: There is no more available memory 2344 * @return M4ERR_FILE_NOT_FOUND: The input file has not been found 2345 * @return M4MCS_ERR_INVALID_INPUT_FILE: The input file is not a valid file, or is corrupted 2346 * @return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM: The input file contains no 2347 * supported audio or video stream 2348 ****************************************************************************** 2349 */ 2350M4OSA_ERR M4MCS_open( M4MCS_Context pContext, M4OSA_Void *pFileIn, 2351 M4VIDEOEDITING_FileType InputFileType, M4OSA_Void *pFileOut, 2352 M4OSA_Void *pTempFile ) 2353{ 2354 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 2355 M4OSA_ERR err; 2356 2357 M4READER_MediaFamily mediaFamily; 2358 M4_StreamHandler *pStreamHandler; 2359 2360 M4OSA_TRACE2_3( 2361 "M4MCS_open called with pContext=0x%x, pFileIn=0x%x, pFileOut=0x%x", 2362 pContext, pFileIn, pFileOut); 2363 2364 /** 2365 * Check input parameters */ 2366 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 2367 "M4MCS_open: pContext is M4OSA_NULL"); 2368 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn), M4ERR_PARAMETER, 2369 "M4MCS_open: pFileIn is M4OSA_NULL"); 2370 2371 if( ( InputFileType == M4VIDEOEDITING_kFileType_JPG) 2372 || (InputFileType == M4VIDEOEDITING_kFileType_PNG) 2373 || (InputFileType == M4VIDEOEDITING_kFileType_GIF) 2374 || (InputFileType == M4VIDEOEDITING_kFileType_BMP) ) 2375 { 2376#ifdef M4MCS_SUPPORT_STILL_PICTURE 2377 /** 2378 * Indicate that we must use the still picture functions*/ 2379 2380 pC->m_bIsStillPicture = M4OSA_TRUE; 2381 2382 /** 2383 * Call the still picture MCS functions*/ 2384 return M4MCS_stillPicOpen(pC, pFileIn, InputFileType, pFileOut); 2385 2386#else 2387 2388 M4OSA_TRACE1_0( 2389 "M4MCS_open: Still picture is not supported with this version of MCS"); 2390 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 2391 2392#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 2393 2394 } 2395 2396 /** 2397 * Check state automaton */ 2398 if( M4MCS_kState_CREATED != pC->State ) 2399 { 2400 M4OSA_TRACE1_1("M4MCS_open(): Wrong State (%d), returning M4ERR_STATE", 2401 pC->State); 2402 return M4ERR_STATE; 2403 } 2404 2405 /* Copy function input parameters into our context */ 2406 pC->pInputFile = pFileIn; 2407 pC->InputFileType = InputFileType; 2408 pC->pOutputFile = pFileOut; 2409 pC->pTemporaryFile = pTempFile; 2410 pC->uiProgress = 0; 2411 2412 /***********************************/ 2413 /* Open input file with the reader */ 2414 /***********************************/ 2415 2416 err = M4MCS_setCurrentReader(pContext, pC->InputFileType); 2417 M4ERR_CHECK_RETURN(err); 2418 2419 /** 2420 * Reset reader related variables */ 2421 pC->VideoState = M4MCS_kStreamState_NOSTREAM; 2422 pC->AudioState = M4MCS_kStreamState_NOSTREAM; 2423 pC->pReaderVideoStream = M4OSA_NULL; 2424 pC->pReaderAudioStream = M4OSA_NULL; 2425 2426 /*******************************************************/ 2427 /* Initializes the reader shell and open the data file */ 2428 /*******************************************************/ 2429 err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext); 2430 2431 if( M4NO_ERROR != err ) 2432 { 2433 M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctCreate returns 0x%x", 2434 err); 2435 return err; 2436 } 2437 2438 /** 2439 * Link the reader interface to the reader context */ 2440 pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext; 2441 2442 /** 2443 * Set the reader shell file access functions */ 2444 err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, 2445 M4READER_kOptionID_SetOsaFileReaderFctsPtr, 2446 (M4OSA_DataOption)pC->pOsaFileReadPtr); 2447 2448 if( M4NO_ERROR != err ) 2449 { 2450 M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctSetOption returns 0x%x", 2451 err); 2452 return err; 2453 } 2454 2455#ifdef M4MCS_WITH_FAST_OPEN 2456 2457 if( M4OSA_FALSE == pC->bFileOpenedInFastMode ) 2458 { 2459 M4OSA_Bool trueValue = M4OSA_TRUE; 2460 2461 /* For first call use fast open mode */ 2462 err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, 2463 M4READER_3GP_kOptionID_FastOpenMode, &trueValue); 2464 2465 if( M4NO_ERROR == err ) 2466 { 2467 pC->bFileOpenedInFastMode = M4OSA_TRUE; 2468 } 2469 else 2470 { 2471 M4OSA_TRACE1_1( 2472 "M4MCS_open(): M4READER_3GP_kOptionID_FastOpenMode returns 0x%x", 2473 err); 2474 2475 if( ( ( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) == err) 2476 || (( (M4OSA_UInt32)M4ERR_PARAMETER) == err) ) 2477 { 2478 /* Not fatal, some readers may not support fast open mode */ 2479 pC->bFileOpenedInFastMode = M4OSA_FALSE; 2480 } 2481 else 2482 return err; 2483 } 2484 } 2485 else 2486 { 2487 M4OSA_Bool falseValue = M4OSA_FALSE; 2488 2489 /* For second call use normal open mode */ 2490 err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, 2491 M4READER_3GP_kOptionID_FastOpenMode, &falseValue); 2492 } 2493 2494#endif /* M4MCS_WITH_FAST_OPEN */ 2495 2496 /** 2497 * Open the input file */ 2498 2499 err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile); 2500 2501 if( M4NO_ERROR != err ) 2502 { 2503 M4OSA_UInt32 uiDummy, uiCoreId; 2504 M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctOpen returns 0x%x", err); 2505 2506 /** 2507 * If the error is from the core reader, we change it to a public VXS error */ 2508 M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); 2509 2510 if( M4MP4_READER == uiCoreId ) 2511 { 2512 M4OSA_TRACE1_0( 2513 "M4MCS_open(): returning M4MCS_ERR_INVALID_INPUT_FILE"); 2514 return M4MCS_ERR_INVALID_INPUT_FILE; 2515 } 2516 return err; 2517 } 2518 2519 /** 2520 * Get the streams from the input file */ 2521 while( M4NO_ERROR == err ) 2522 { 2523 err = 2524 pC->m_pReader->m_pFctGetNextStream( pC->pReaderContext, 2525 &mediaFamily, 2526 &pStreamHandler); 2527 2528 /** 2529 * In case we found a BIFS stream or something else...*/ 2530 if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) 2531 || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) ) 2532 { 2533 err = M4NO_ERROR; 2534 continue; 2535 } 2536 2537 if( M4NO_ERROR == err ) /**< One stream found */ 2538 { 2539 /** 2540 * Found the first video stream */ 2541 if( ( M4READER_kMediaFamilyVideo == mediaFamily) 2542 && (M4OSA_NULL == pC->pReaderVideoStream) ) 2543 { 2544 if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType) 2545 || (M4DA_StreamTypeVideoMpeg4 2546 == pStreamHandler->m_streamType) 2547 || (M4DA_StreamTypeVideoMpeg4Avc 2548 == pStreamHandler->m_streamType) ) 2549 { 2550 M4OSA_TRACE3_0( 2551 "M4MCS_open(): Found a H263 or MPEG-4 video stream in input 3gpp clip"); 2552 2553 /** 2554 * Keep pointer to the video stream */ 2555 pC->pReaderVideoStream = 2556 (M4_VideoStreamHandler *)pStreamHandler; 2557 pC->bUnsupportedVideoFound = M4OSA_FALSE; 2558 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 2559 2560 /** 2561 * Init our video stream state variable */ 2562 pC->VideoState = M4MCS_kStreamState_STARTED; 2563 2564 /** 2565 * Reset the stream reader */ 2566 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 2567 (M4_StreamHandler *)pC->pReaderVideoStream); 2568 2569 if( M4NO_ERROR != err ) 2570 { 2571 M4OSA_TRACE1_1( 2572 "M4MCS_open():\ 2573 m_pReader->m_pFctReset(video) returns 0x%x", 2574 err); 2575 return err; 2576 } 2577 2578 /** 2579 * Initializes an access Unit */ 2580 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 2581 pStreamHandler, &pC->ReaderVideoAU); 2582 2583 if( M4NO_ERROR != err ) 2584 { 2585 M4OSA_TRACE1_1( 2586 "M4MCS_open():\ 2587 m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 2588 err); 2589 return err; 2590 } 2591 } 2592 else /**< Not H263 or MPEG-4 (H264, etc.) */ 2593 { 2594 M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported video stream (0x%x) in\ 2595 input 3gpp clip", 2596 pStreamHandler->m_streamType); 2597 2598 pC->bUnsupportedVideoFound = M4OSA_TRUE; 2599 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 2600 } 2601 /* +CRLV6775 -H.264 Trimming */ 2602 if( M4DA_StreamTypeVideoMpeg4Avc 2603 == pStreamHandler->m_streamType ) 2604 { 2605 2606 // SPS and PPS are storead as per the 3gp file format 2607 pC->m_pInstance->m_pDecoderSpecificInfo = 2608 pStreamHandler->m_pH264DecoderSpecificInfo; 2609 pC->m_pInstance->m_decoderSpecificInfoSize = 2610 pStreamHandler->m_H264decoderSpecificInfoSize; 2611 } 2612 /* -CRLV6775 -H.264 Trimming */ 2613 } 2614 /** 2615 * Found the first audio stream */ 2616 else if( ( M4READER_kMediaFamilyAudio == mediaFamily) 2617 && (M4OSA_NULL == pC->pReaderAudioStream) ) 2618 { 2619 if( ( M4DA_StreamTypeAudioAmrNarrowBand 2620 == pStreamHandler->m_streamType) 2621 || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType) 2622 || (M4DA_StreamTypeAudioMp3 2623 == pStreamHandler->m_streamType) 2624 || (M4DA_StreamTypeAudioEvrc 2625 == pStreamHandler->m_streamType) ) 2626 { 2627 M4OSA_TRACE3_0( 2628 "M4MCS_open(): Found an AMR-NB, AAC or MP3 audio stream in input clip"); 2629 2630 /** 2631 * Keep pointer to the audio stream */ 2632 pC->pReaderAudioStream = 2633 (M4_AudioStreamHandler *)pStreamHandler; 2634 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 2635 pC->bUnsupportedAudioFound = M4OSA_FALSE; 2636 2637 /** 2638 * Init our audio stream state variable */ 2639 pC->AudioState = M4MCS_kStreamState_STARTED; 2640 2641 /** 2642 * Reset the stream reader */ 2643 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 2644 (M4_StreamHandler *)pC->pReaderAudioStream); 2645 2646 if( M4NO_ERROR != err ) 2647 { 2648 M4OSA_TRACE1_1( 2649 "M4MCS_open():\ 2650 m_pReader->m_pFctReset(audio) returns 0x%x", 2651 err); 2652 return err; 2653 } 2654 2655 /** 2656 * Initializes an access Unit */ 2657 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 2658 pStreamHandler, &pC->ReaderAudioAU); 2659 2660 if( M4NO_ERROR != err ) 2661 { 2662 M4OSA_TRACE1_1( 2663 "M4MCS_open():\ 2664 m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 2665 err); 2666 return err; 2667 } 2668 2669 /** 2670 * Output max AU size is equal to input max AU size (this value 2671 * will be changed if there is audio transcoding) */ 2672 pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize; 2673 } 2674 else 2675 { 2676 /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */ 2677 M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported audio stream (0x%x) in \ 2678 input 3gpp clip", pStreamHandler->m_streamType); 2679 2680 pC->bUnsupportedAudioFound = M4OSA_TRUE; 2681 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 2682 } 2683 } 2684 } 2685 } /**< end of while (M4NO_ERROR == err) */ 2686 2687 /** 2688 * Check we found at least one supported stream */ 2689 if( ( M4OSA_NULL == pC->pReaderVideoStream) 2690 && (M4OSA_NULL == pC->pReaderAudioStream) ) 2691 { 2692 M4OSA_TRACE1_0( 2693 "M4MCS_open(): returning M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM"); 2694 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 2695 } 2696 2697 if( pC->VideoState == M4MCS_kStreamState_STARTED ) 2698 { 2699 err = M4MCS_setCurrentVideoDecoder(pContext, 2700 pC->pReaderVideoStream->m_basicProperties.m_streamType); 2701 /*FB 2009-02-09: the error is check and returned only if video codecs are compiled, 2702 else only audio is used, that is why the editing process can continue*/ 2703#ifndef M4MCS_AUDIOONLY 2704 2705 M4ERR_CHECK_RETURN(err); 2706 2707#else 2708 2709 if( ( M4NO_ERROR != err) && (M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED != err) ) 2710 { 2711 M4ERR_CHECK_RETURN(err); 2712 } 2713 2714#endif /*M4MCS_AUDIOONLY*/ 2715 2716 } 2717 2718 if( pC->AudioState == M4MCS_kStreamState_STARTED ) 2719 { 2720 //EVRC 2721 if( M4DA_StreamTypeAudioEvrc 2722 != pStreamHandler-> 2723 m_streamType ) /* decoder not supported yet, but allow to do null encoding */ 2724 { 2725 err = M4MCS_setCurrentAudioDecoder(pContext, 2726 pC->pReaderAudioStream->m_basicProperties.m_streamType); 2727 M4ERR_CHECK_RETURN(err); 2728 } 2729 } 2730 2731 /** 2732 * Get the audio and video stream properties */ 2733 err = M4MCS_intGetInputClipProperties(pC); 2734 2735 if( M4NO_ERROR != err ) 2736 { 2737 M4OSA_TRACE1_1( 2738 "M4MCS_open(): M4MCS_intGetInputClipProperties returns 0x%x", err); 2739 return err; 2740 } 2741 2742 /** 2743 * Set the begin cut decoding increment according to the input frame rate */ 2744 if( 0. != pC->InputFileProperties.fAverageFrameRate ) /**< sanity check */ 2745 { 2746 pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. 2747 / pC->InputFileProperties. 2748 fAverageFrameRate); /**< about 3 frames */ 2749 } 2750 else 2751 { 2752 pC->iVideoBeginDecIncr = 2753 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/ 2754 } 2755 2756 /** 2757 * Update state automaton */ 2758 pC->State = M4MCS_kState_OPENED; 2759 2760 /** 2761 * Return with no error */ 2762 M4OSA_TRACE3_0("M4MCS_open(): returning M4NO_ERROR"); 2763 return M4NO_ERROR; 2764} 2765 2766/** 2767 ****************************************************************************** 2768 * M4OSA_ERR M4MCS_step(M4MCS_Context pContext, M4OSA_UInt8 *pProgress); 2769 * @brief Perform one step of trancoding. 2770 * @note 2771 * @param pContext (IN) MCS context 2772 * @param pProgress (OUT) Progress percentage (0 to 100) of the transcoding 2773 * @note pProgress must be a valid address. 2774 * @return M4NO_ERROR: No error 2775 * @return M4ERR_PARAMETER: One of the parameters is M4OSA_NULL (debug only) 2776 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 2777 * @return M4MCS_WAR_TRANSCODING_DONE: Transcoding is over, user should now call M4MCS_close() 2778 * @return M4MCS_ERR_AUDIO_CONVERSION_FAILED: The audio conversion (AAC to AMR-NB or MP3) failed 2779 * @return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY: The input file contains an AAC audio track 2780 * with an invalid sampling frequency (should never happen) 2781 ****************************************************************************** 2782 */ 2783M4OSA_ERR M4MCS_step( M4MCS_Context pContext, M4OSA_UInt8 *pProgress ) 2784{ 2785 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 2786 2787 M4OSA_TRACE3_1("M4MCS_step called with pContext=0x%x", pContext); 2788 2789 /** 2790 * Check input parameters */ 2791 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 2792 "M4MCS_step: pContext is M4OSA_NULL"); 2793 M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER, 2794 "M4MCS_step: pProgress is M4OSA_NULL"); 2795 2796#ifdef M4MCS_SUPPORT_STILL_PICTURE 2797 2798 if( pC->m_bIsStillPicture ) 2799 { 2800 /** 2801 * Call the still picture MCS functions*/ 2802 return M4MCS_stillPicStep(pC, pProgress); 2803 } 2804 2805#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 2806 2807 /** 2808 * Check state automaton */ 2809 2810 switch( pC->State ) 2811 { 2812 case M4MCS_kState_READY: 2813 *pProgress = 0; 2814 return M4MCS_intStepSet(pC); 2815 break; 2816 2817 case M4MCS_kState_BEGINVIDEOJUMP: 2818 *pProgress = pC->uiProgress; 2819 return M4MCS_intStepBeginVideoJump(pC); 2820 break; 2821 2822 case M4MCS_kState_BEGINVIDEODECODE: 2823 *pProgress = pC->uiProgress; 2824 return M4MCS_intStepBeginVideoDecode(pC); 2825 break; 2826 2827 case M4MCS_kState_PROCESSING: 2828 { 2829 M4OSA_ERR err = M4NO_ERROR; 2830 err = M4MCS_intStepEncoding(pC, pProgress); 2831 /* Save progress info in case of pause */ 2832 pC->uiProgress = *pProgress; 2833 return err; 2834 } 2835 break; 2836 2837 default: /**< State error */ 2838 M4OSA_TRACE1_1( 2839 "M4MCS_step(): Wrong State (%d), returning M4ERR_STATE", 2840 pC->State); 2841 return M4ERR_STATE; 2842 } 2843} 2844 2845/** 2846 ****************************************************************************** 2847 * M4OSA_ERR M4MCS_pause(M4MCS_Context pContext); 2848 * @brief Pause the transcoding i.e. release the (external hardware) video decoder. 2849 * @note This function is not needed if no hardware accelerators are used. 2850 * In that case, pausing the MCS is simply achieved by temporarily suspending 2851 * the M4MCS_step function calls. 2852 * @param pContext (IN) MCS context 2853 * @return M4NO_ERROR: No error 2854 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 2855 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 2856 ****************************************************************************** 2857 */ 2858M4OSA_ERR M4MCS_pause( M4MCS_Context pContext ) 2859{ 2860 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 2861 M4OSA_ERR err; 2862 2863 M4OSA_TRACE2_1("M4MCS_pause called with pContext=0x%x", pContext); 2864 2865 /** 2866 * Check input parameters */ 2867 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 2868 "M4MCS_pause: pContext is M4OSA_NULL"); 2869 2870#ifdef M4MCS_SUPPORT_STILL_PICTURE 2871 2872 if( pC->m_bIsStillPicture ) 2873 { 2874 /** 2875 * Call the corresponding still picture MCS function*/ 2876 return M4MCS_stillPicPause(pC); 2877 } 2878 2879#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 2880 2881 /** 2882 * Check state automaton */ 2883 2884 switch( pC->State ) 2885 { 2886 case M4MCS_kState_BEGINVIDEOJUMP: /**< the video decoder has been created, 2887 we must destroy it */ 2888 case M4MCS_kState_BEGINVIDEODECODE: /**< the video is being used, we must destroy it */ 2889 case M4MCS_kState_PROCESSING: /**< the video is being used, we must destroy it */ 2890 /**< OK, nothing to do here */ 2891 break; 2892 2893 default: /**< State error */ 2894 M4OSA_TRACE1_1( 2895 "M4MCS_pause(): Wrong State (%d), returning M4ERR_STATE", 2896 pC->State); 2897 return M4ERR_STATE; 2898 } 2899 2900 /** 2901 * Set the CTS at which we will resume the decoding */ 2902 if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) 2903 { 2904 /** 2905 * We passed the starting CTS, so the resume target is the current CTS */ 2906 pC->dViDecStartingCts = pC->dViDecCurrentCts; 2907 } 2908 else { 2909 /** 2910 * We haven't passed the starting CTS yet, so the resume target is still the starting CTS 2911 * --> nothing to do in the else block */ 2912 } 2913 2914 /** 2915 * Free video decoder stuff */ 2916 if( M4OSA_NULL != pC->pViDecCtxt ) 2917 { 2918 err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); 2919 pC->pViDecCtxt = M4OSA_NULL; 2920 2921 if( M4NO_ERROR != err ) 2922 { 2923 M4OSA_TRACE1_1( 2924 "M4MCS_pause: m_pVideoDecoder->pFctDestroy returns 0x%x", err); 2925 return err; 2926 } 2927 } 2928 2929 /** 2930 * State transition */ 2931 pC->State = M4MCS_kState_PAUSED; 2932 2933 M4OSA_TRACE3_0("M4MCS_pause(): returning M4NO_ERROR"); 2934 return M4NO_ERROR; 2935} 2936 2937/** 2938 ****************************************************************************** 2939 * M4OSA_ERR M4MCS_resume(M4MCS_Context pContext); 2940 * @brief Resume the transcoding after a pause (see M4MCS_pause). 2941 * @note This function is not needed if no hardware accelerators are used. 2942 * In that case, resuming the MCS is simply achieved by calling 2943 * the M4MCS_step function. 2944 * @param pContext (IN) MCS context 2945 * @return M4NO_ERROR: No error 2946 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 2947 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 2948 ****************************************************************************** 2949 */ 2950M4OSA_ERR M4MCS_resume( M4MCS_Context pContext ) 2951{ 2952 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 2953 M4OSA_ERR err; 2954 2955 M4OSA_TRACE2_1("M4MCS_resume called with pContext=0x%x", pContext); 2956 2957 /** 2958 * Check input parameters */ 2959 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 2960 "M4MCS_resume: pContext is M4OSA_NULL"); 2961 2962#ifdef M4MCS_SUPPORT_STILL_PICTURE 2963 2964 if( pC->m_bIsStillPicture ) 2965 { 2966 /** 2967 * Call the corresponding still picture MCS function*/ 2968 return M4MCS_stillPicResume(pC); 2969 } 2970 2971#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 2972 2973 /** 2974 * Check state automaton */ 2975 2976 switch( pC->State ) 2977 { 2978 case M4MCS_kState_PAUSED: /**< OK, nothing to do here */ 2979 break; 2980 2981 default: /**< State error */ 2982 M4OSA_TRACE1_1( 2983 "M4MCS_resume(): Wrong State (%d), returning M4ERR_STATE", 2984 pC->State); 2985 return M4ERR_STATE; 2986 break; 2987 } 2988 2989 /** 2990 * Prepare the video decoder */ 2991 err = M4MCS_intPrepareVideoDecoder(pC); 2992 2993 if( M4NO_ERROR != err ) 2994 { 2995 M4OSA_TRACE1_1( 2996 "M4MCS_resume(): M4MCS_intPrepareVideoDecoder() returns 0x%x", err); 2997 return err; 2998 } 2999 3000 /** 3001 * State transition */ 3002 if( 0.0 == pC->dViDecStartingCts ) 3003 { 3004 /** 3005 * We are still at the beginning of the decoded stream, no need to jump, we can proceed */ 3006 pC->State = M4MCS_kState_PROCESSING; 3007 } 3008 else 3009 { 3010 /** 3011 * Jumping */ 3012 pC->State = M4MCS_kState_BEGINVIDEOJUMP; 3013 } 3014 3015 M4OSA_TRACE3_0("M4MCS_resume(): returning M4NO_ERROR"); 3016 return M4NO_ERROR; 3017} 3018 3019/** 3020 ****************************************************************************** 3021 * M4OSA_ERR M4MCS_close(M4MCS_Context pContext); 3022 * @brief Finish the MCS transcoding. 3023 * @note The output 3GPP file is ready to be played after this call 3024 * @param pContext (IN) MCS context 3025 * @return M4NO_ERROR: No error 3026 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) 3027 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 3028 ****************************************************************************** 3029 */ 3030M4OSA_ERR M4MCS_close( M4MCS_Context pContext ) 3031{ 3032 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 3033 M4ENCODER_Header *encHeader; 3034 M4SYS_StreamIDmemAddr streamHeader; 3035 3036 M4OSA_ERR err = M4NO_ERROR, err2; 3037 3038 M4OSA_TRACE2_1("M4MCS_close called with pContext=0x%x", pContext); 3039 3040 /** 3041 * Check input parameters */ 3042 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 3043 "M4MCS_close: pContext is M4OSA_NULL"); 3044 3045#ifdef M4MCS_SUPPORT_STILL_PICTURE 3046 3047 if( pC->m_bIsStillPicture ) 3048 { 3049 /** 3050 * Indicate that current file is no longer a still picture*/ 3051 pC->m_bIsStillPicture = M4OSA_FALSE; 3052 3053 /** 3054 * Call the corresponding still picture MCS function*/ 3055 return M4MCS_stillPicClose(pC); 3056 } 3057 3058#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 3059 3060 /** 3061 * Check state automaton */ 3062 3063 if( M4MCS_kState_FINISHED != pC->State ) 3064 { 3065 M4OSA_TRACE1_1("M4MCS_close(): Wrong State (%d), returning M4ERR_STATE", 3066 pC->State); 3067 return M4ERR_STATE; 3068 } 3069 3070 /* Close the encoder before the writer to be certain all the AUs have been written and we can 3071 get the DSI. */ 3072 3073 /* Has the encoder actually been started? Don't stop it if that's not the case. */ 3074 if( M4MCS_kEncoderRunning == pC->encoderState ) 3075 { 3076 if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL ) 3077 { 3078 err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt); 3079 3080 if( M4NO_ERROR != err ) 3081 { 3082 M4OSA_TRACE1_1( 3083 "M4MCS_close: pVideoEncoderGlobalFcts->pFctStop returns 0x%x", 3084 err); 3085 /* Well... how the heck do you handle a failed cleanup? */ 3086 } 3087 } 3088 3089 pC->encoderState = M4MCS_kEncoderStopped; 3090 } 3091 3092 /* Has the encoder actually been opened? Don't close it if that's not the case. */ 3093 if( M4MCS_kEncoderStopped == pC->encoderState ) 3094 { 3095 err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt); 3096 3097 if( M4NO_ERROR != err ) 3098 { 3099 M4OSA_TRACE1_1( 3100 "M4MCS_close: pVideoEncoderGlobalFcts->pFctClose returns 0x%x", 3101 err); 3102 /* Well... how the heck do you handle a failed cleanup? */ 3103 } 3104 3105 pC->encoderState = M4MCS_kEncoderClosed; 3106 } 3107 3108 /**********************************/ 3109 /******** Close the writer ********/ 3110 /**********************************/ 3111 if( M4OSA_NULL != pC->pWriterContext ) /* happens in state _SET */ 3112 { 3113 /* HW encoder: fetch the DSI from the shell video encoder, and feed it to the writer before 3114 closing it. */ 3115 3116 if( pC->novideo != M4OSA_TRUE ) 3117 { 3118 if( ( M4ENCODER_kMPEG4 == pC->EncodingVideoFormat) 3119 || (M4ENCODER_kH264 == pC->EncodingVideoFormat) ) 3120 { 3121 err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt, 3122 M4ENCODER_kOptionID_EncoderHeader, 3123 (M4OSA_DataOption) &encHeader); 3124 3125 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) 3126 { 3127 M4OSA_TRACE1_1( 3128 "M4MCS_close: failed to get the encoder header (err 0x%x)", 3129 err); 3130 /**< no return here, we still have stuff to deallocate after close, even 3131 if it fails. */ 3132 } 3133 else 3134 { 3135 /* set this header in the writer */ 3136 streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 3137 streamHeader.size = encHeader->Size; 3138 streamHeader.addr = (M4OSA_MemAddr32)encHeader->pBuf; 3139 } 3140 3141 M4OSA_TRACE1_0("calling set option"); 3142 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 3143 M4WRITER_kDSI, &streamHeader); 3144 M4OSA_TRACE1_0("set option done"); 3145 3146 if( M4NO_ERROR != err ) 3147 { 3148 M4OSA_TRACE1_1( 3149 "M4MCS_close: failed to set the DSI in the writer (err 0x%x)", 3150 err); 3151 } 3152 } 3153 3154 if( ( M4OSA_TRUE == pC->bH264Trim) 3155 && (M4ENCODER_kNULL == pC->EncodingVideoFormat) ) 3156 { 3157 if(pC->uiBeginCutTime == 0) 3158 { 3159 M4OSA_TRACE1_1("Decoder specific info size = %d", 3160 pC->m_pInstance->m_decoderSpecificInfoSize); 3161 pC->m_pInstance->m_pFinalDSISize = 3162 pC->m_pInstance->m_decoderSpecificInfoSize; 3163 M4OSA_TRACE1_1("Decoder specific info pointer = %d", 3164 (M4OSA_MemAddr8)pC->m_pInstance->m_pDecoderSpecificInfo); 3165 3166 pC->m_pInstance->m_pFinalDSI = 3167 (M4OSA_UInt8 *)M4OSA_malloc(pC->m_pInstance-> \ 3168 m_decoderSpecificInfoSize, M4MCS, 3169 (M4OSA_Char *)"instance->m_pFinalDSI"); 3170 3171 if( pC->m_pInstance->m_pFinalDSI == M4OSA_NULL ) 3172 { 3173 M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error"); 3174 return M4ERR_ALLOC; 3175 } 3176 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pInstance->m_pFinalDSI, 3177 (M4OSA_MemAddr8)pC-> \ 3178 m_pInstance->m_pDecoderSpecificInfo, 3179 pC->m_pInstance->m_decoderSpecificInfoSize); 3180 } 3181 streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 3182 streamHeader.size = pC->m_pInstance->m_pFinalDSISize; 3183 streamHeader.addr = 3184 (M4OSA_MemAddr32)pC->m_pInstance->m_pFinalDSI; 3185 M4OSA_TRACE1_0("calling set option"); 3186 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 3187 M4WRITER_kDSI, &streamHeader); 3188 M4OSA_TRACE1_0("set option done"); 3189 3190 if( M4NO_ERROR != err ) 3191 { 3192 M4OSA_TRACE1_1( 3193 "M4MCS_close: failed to set the DSI in the writer (err 0x%x)", 3194 err); 3195 } 3196 } 3197 } 3198 /* Write and close the 3GP output file */ 3199 err2 = pC->pWriterGlobalFcts->pFctCloseWrite(pC->pWriterContext); 3200 pC->pWriterContext = M4OSA_NULL; 3201 3202 if( M4NO_ERROR != err2 ) 3203 { 3204 M4OSA_TRACE1_1( 3205 "M4MCS_close: pWriterGlobalFcts->pFctCloseWrite returns 0x%x", 3206 err2); 3207 3208 if( M4NO_ERROR == err ) 3209 err = err2; 3210 /**< no return here, we still have stuff to deallocate after close, even if it fails.*/ 3211 } 3212 } 3213 3214 /* Close output PCM file if needed */ 3215 if( pC->pOutputPCMfile != M4OSA_NULL ) 3216 { 3217 pC->pOsaFileWritPtr->closeWrite(pC->pOutputPCMfile); 3218 pC->pOutputPCMfile = M4OSA_NULL; 3219 } 3220 3221 /*FlB 2009.03.04: add audio effects, 3222 free effects list*/ 3223 if( M4OSA_NULL != pC->pEffects ) 3224 { 3225 M4OSA_free((M4OSA_MemAddr32)pC->pEffects); 3226 pC->pEffects = M4OSA_NULL; 3227 } 3228 pC->nbEffects = 0; 3229 pC->pActiveEffectNumber = -1; 3230 3231 /** 3232 * State transition */ 3233 pC->State = M4MCS_kState_CLOSED; 3234 3235 if( M4OSA_NULL != pC->H264MCSTempBuffer ) 3236 { 3237 M4OSA_free((M4OSA_MemAddr32)pC->H264MCSTempBuffer); 3238 } 3239 3240 if( M4OSA_NULL != pC->m_pInstance ) 3241 { 3242 err = H264MCS_Freeinstance(pC->m_pInstance); 3243 pC->m_pInstance = M4OSA_NULL; 3244 } 3245 3246 M4OSA_TRACE3_0("M4MCS_close(): returning M4NO_ERROR"); 3247 return err; 3248} 3249 3250/** 3251 ****************************************************************************** 3252 * M4OSA_ERR M4MCS_cleanUp(M4MCS_Context pContext); 3253 * @brief Free all resources used by the MCS. 3254 * @note The context is no more valid after this call 3255 * @param pContext (IN) MCS context 3256 * @return M4NO_ERROR: No error 3257 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) 3258 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 3259 ****************************************************************************** 3260 */ 3261M4OSA_ERR M4MCS_cleanUp( M4MCS_Context pContext ) 3262{ 3263 M4OSA_ERR err = M4NO_ERROR; 3264 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 3265 3266 M4OSA_TRACE3_1("M4MCS_cleanUp called with pContext=0x%x", pContext); 3267 3268#ifdef MCS_DUMP_PCM_TO_FILE 3269 3270 if( file_au_reader ) 3271 { 3272 fclose(file_au_reader); 3273 file_au_reader = NULL; 3274 } 3275 3276 if( file_pcm_decoder ) 3277 { 3278 fclose(file_pcm_decoder); 3279 file_pcm_decoder = NULL; 3280 } 3281 3282 if( file_pcm_encoder ) 3283 { 3284 fclose(file_pcm_encoder); 3285 file_pcm_encoder = NULL; 3286 } 3287 3288#endif 3289 3290 /** 3291 * Check input parameter */ 3292 3293 if( M4OSA_NULL == pContext ) 3294 { 3295 M4OSA_TRACE1_0( 3296 "M4MCS_cleanUp: pContext is M4OSA_NULL, returning M4ERR_PARAMETER"); 3297 return M4ERR_PARAMETER; 3298 } 3299 3300 /** 3301 * Check state automaton */ 3302 if( M4MCS_kState_CLOSED != pC->State ) 3303 { 3304 M4OSA_TRACE1_1( 3305 "M4MCS_cleanUp(): Wrong State (%d), returning M4ERR_STATE", 3306 pC->State); 3307 return M4ERR_STATE; 3308 } 3309 3310 /* ----- Free video encoder stuff, if needed ----- */ 3311 3312 if( ( M4OSA_NULL != pC->pViEncCtxt) 3313 && (M4OSA_NULL != pC->pVideoEncoderGlobalFcts) ) 3314 { 3315 err = pC->pVideoEncoderGlobalFcts->pFctCleanup(pC->pViEncCtxt); 3316 pC->pViEncCtxt = M4OSA_NULL; 3317 3318 if( M4NO_ERROR != err ) 3319 { 3320 M4OSA_TRACE1_1( 3321 "M4MCS_cleanUp: pVideoEncoderGlobalFcts->pFctCleanup returns 0x%x", 3322 err); 3323 /**< don't return, we still have stuff to free */ 3324 } 3325 3326 pC->encoderState = M4MCS_kNoEncoder; 3327 } 3328 3329 /** 3330 * In the H263 case, we allocated our own DSI buffer */ 3331 if( ( M4ENCODER_kH263 == pC->EncodingVideoFormat) 3332 && (M4OSA_NULL != pC->WriterVideoStreamInfo.Header.pBuf) ) 3333 { 3334 M4OSA_free((M4OSA_MemAddr32)pC->WriterVideoStreamInfo.Header.pBuf); 3335 pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL; 3336 } 3337 3338 if( M4OSA_NULL != pC->pPreResizeFrame ) 3339 { 3340 if( M4OSA_NULL != pC->pPreResizeFrame[0].pac_data ) 3341 { 3342 M4OSA_free((M4OSA_MemAddr32)pC->pPreResizeFrame[0].pac_data); 3343 pC->pPreResizeFrame[0].pac_data = M4OSA_NULL; 3344 } 3345 3346 if( M4OSA_NULL != pC->pPreResizeFrame[1].pac_data ) 3347 { 3348 M4OSA_free((M4OSA_MemAddr32)pC->pPreResizeFrame[1].pac_data); 3349 pC->pPreResizeFrame[1].pac_data = M4OSA_NULL; 3350 } 3351 3352 if( M4OSA_NULL != pC->pPreResizeFrame[2].pac_data ) 3353 { 3354 M4OSA_free((M4OSA_MemAddr32)pC->pPreResizeFrame[2].pac_data); 3355 pC->pPreResizeFrame[2].pac_data = M4OSA_NULL; 3356 } 3357 M4OSA_free((M4OSA_MemAddr32)pC->pPreResizeFrame); 3358 pC->pPreResizeFrame = M4OSA_NULL; 3359 } 3360 3361 /* ----- Free the ssrc stuff ----- */ 3362 3363 if( M4OSA_NULL != pC->SsrcScratch ) 3364 { 3365 M4OSA_free((M4OSA_MemAddr32)pC->SsrcScratch); 3366 pC->SsrcScratch = M4OSA_NULL; 3367 } 3368 3369 if( M4OSA_NULL != pC->pSsrcBufferIn ) 3370 { 3371 M4OSA_free((M4OSA_MemAddr32)pC->pSsrcBufferIn); 3372 pC->pSsrcBufferIn = M4OSA_NULL; 3373 } 3374 3375 if( M4OSA_NULL != pC->pSsrcBufferOut ) 3376 { 3377 M4OSA_free((M4OSA_MemAddr32)pC->pSsrcBufferOut); 3378 pC->pSsrcBufferOut = M4OSA_NULL; 3379 } 3380 3381 /* ----- Free the audio encoder stuff ----- */ 3382 3383 if( M4OSA_NULL != pC->pAudioEncCtxt ) 3384 { 3385 err = pC->pAudioEncoderGlobalFcts->pFctClose(pC->pAudioEncCtxt); 3386 3387 if( M4NO_ERROR != err ) 3388 { 3389 M4OSA_TRACE1_1( 3390 "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x", 3391 err); 3392 /**< don't return, we still have stuff to free */ 3393 } 3394 3395 err = pC->pAudioEncoderGlobalFcts->pFctCleanUp(pC->pAudioEncCtxt); 3396 3397 if( M4NO_ERROR != err ) 3398 { 3399 M4OSA_TRACE1_1( 3400 "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x", 3401 err); 3402 /**< don't return, we still have stuff to free */ 3403 } 3404 3405 pC->pAudioEncCtxt = M4OSA_NULL; 3406 } 3407 3408 if( M4OSA_NULL != pC->pAudioEncoderBuffer ) 3409 { 3410 M4OSA_free((M4OSA_MemAddr32)pC->pAudioEncoderBuffer); 3411 pC->pAudioEncoderBuffer = M4OSA_NULL; 3412 } 3413 3414 /* ----- Free all other stuff ----- */ 3415 3416 /** 3417 * Free the readers and the decoders */ 3418 M4MCS_intCleanUp_ReadersDecoders(pC); 3419 3420#ifdef M4MCS_SUPPORT_STILL_PICTURE 3421 /** 3422 * Free the still picture resources */ 3423 3424 M4MCS_stillPicCleanUp(pC); 3425 3426#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 3427 3428 /** 3429 * Free the shells interfaces */ 3430 3431 M4MCS_unRegisterAllWriters(pContext); 3432 M4MCS_unRegisterAllEncoders(pContext); 3433 M4MCS_unRegisterAllReaders(pContext); 3434 M4MCS_unRegisterAllDecoders(pContext); 3435 3436 /** 3437 * Free the context itself */ 3438 M4OSA_free((M4OSA_MemAddr32)pC); 3439 pC = M4OSA_NULL; 3440 3441 M4OSA_TRACE3_0("M4MCS_cleanUp(): returning M4NO_ERROR"); 3442 return M4NO_ERROR; 3443} 3444 3445/** 3446 ****************************************************************************** 3447 * M4OSA_ERR M4MCS_abort(M4MCS_Context pContext); 3448 * @brief Finish the MCS transcoding and free all resources used by the MCS 3449 * whatever the state is. 3450 * @note The context is no more valid after this call 3451 * @param pContext (IN) MCS context 3452 * @return M4NO_ERROR: No error 3453 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 3454 ****************************************************************************** 3455 */ 3456M4OSA_ERR M4MCS_abort( M4MCS_Context pContext ) 3457{ 3458 M4OSA_ERR err = M4NO_ERROR; 3459 M4OSA_ERR err1 = M4NO_ERROR; 3460 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 3461 3462 if( M4OSA_NULL == pContext ) 3463 { 3464 return M4NO_ERROR; 3465 } 3466 3467 if( ( pC->State == M4MCS_kState_CREATED) 3468 || (pC->State == M4MCS_kState_CLOSED) ) 3469 { 3470 pC->State = M4MCS_kState_CLOSED; 3471 3472 err = M4MCS_cleanUp(pContext); 3473 3474 if( err != M4NO_ERROR ) 3475 { 3476 M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err); 3477 } 3478 } 3479 else 3480 { 3481#ifdef M4MCS_SUPPORT_STILL_PICTURE 3482 3483 if( pC->m_bIsStillPicture ) 3484 { 3485 /** 3486 * Cancel the ongoing processes if any*/ 3487 err = M4MCS_stillPicCancel(pC); 3488 3489 if( err != M4NO_ERROR ) 3490 { 3491 M4OSA_TRACE1_1( 3492 "M4MCS_abort : M4MCS_stillPicCancel fails err = 0x%x", err); 3493 } 3494 /*Still picture process is now stopped; Carry on with close and cleanup*/ 3495 } 3496 3497#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 3498 3499 pC->State = M4MCS_kState_FINISHED; 3500 3501 err = M4MCS_close(pContext); 3502 3503 if( err != M4NO_ERROR ) 3504 { 3505 M4OSA_TRACE1_1("M4MCS_abort : M4MCS_close fails err = 0x%x", err); 3506 err1 = err; 3507 } 3508 3509 err = M4MCS_cleanUp(pContext); 3510 3511 if( err != M4NO_ERROR ) 3512 { 3513 M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err); 3514 } 3515 } 3516 err = (err1 == M4NO_ERROR) ? err : err1; 3517 return err; 3518} 3519 3520/** 3521 ****************************************************************************** 3522 * M4OSA_ERR M4MCS_getInputFileProperties(M4MCS_Context pContext, 3523 * M4VIDEOEDITING_ClipProperties* pFileProperties); 3524 * @brief Retrieves the properties of the audio and video streams from the input file. 3525 * @param pContext (IN) MCS context 3526 * @param pProperties (OUT) Pointer on an allocated M4VIDEOEDITING_ClipProperties 3527structure which is filled with the input stream properties. 3528 * @note The structure pProperties must be allocated and further de-allocated 3529by the application. The function must be called in the opened state. 3530 * @return M4NO_ERROR: No error 3531 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL 3532 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 3533 ****************************************************************************** 3534 */ 3535M4OSA_ERR M4MCS_getInputFileProperties( M4MCS_Context pContext, 3536 M4VIDEOEDITING_ClipProperties *pFileProperties ) 3537{ 3538 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 3539 3540 M4OSA_TRACE2_2("M4MCS_getInputFileProperties called with pContext=0x%x, \ 3541 pFileProperties=0x%x", pContext, pFileProperties); 3542 3543 /** 3544 * Check input parameters */ 3545 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 3546 "M4MCS_getInputFileProperties: pContext is M4OSA_NULL"); 3547 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileProperties), M4ERR_PARAMETER, 3548 "M4MCS_getInputFileProperties: pProperties is M4OSA_NULL"); 3549 3550#ifdef M4MCS_SUPPORT_STILL_PICTURE 3551 3552 if( pC->m_bIsStillPicture ) 3553 { 3554 /** 3555 * Call the corresponding still picture MCS function*/ 3556 return M4MCS_stillPicGetInputFileProperties(pC, pFileProperties); 3557 } 3558 3559#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 3560 3561 /** 3562 * Check state automaton */ 3563 3564 if( M4MCS_kState_OPENED != pC->State ) 3565 { 3566 M4OSA_TRACE1_1( 3567 "M4MCS_getInputFileProperties(): Wrong State (%d), returning M4ERR_STATE", 3568 pC->State); 3569 return M4ERR_STATE; 3570 } 3571 3572 /** 3573 * Copy previously computed properties into given structure */ 3574 M4OSA_memcpy((M4OSA_MemAddr8)pFileProperties, 3575 (M4OSA_MemAddr8) &pC->InputFileProperties, 3576 sizeof(M4VIDEOEDITING_ClipProperties)); 3577 3578 return M4NO_ERROR; 3579} 3580 3581/** 3582 ****************************************************************************** 3583 * M4OSA_ERR M4MCS_setOutputParams(M4MCS_Context pContext, M4MCS_OutputParams* pParams); 3584 * @brief Set the MCS video output parameters. 3585 * @note Must be called after M4MCS_open. Must be called before M4MCS_step. 3586 * @param pContext (IN) MCS context 3587 * @param pParams (IN/OUT) Transcoding parameters 3588 * @return M4NO_ERROR: No error 3589 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 3590 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 3591 * @return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 : Output video frame size parameter is 3592 * incompatible with H263 encoding 3593 * @return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 : Output video frame size parameter is 3594 * incompatible with H263 encoding 3595 * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT : Undefined output video format parameter 3596 * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE : Undefined output video frame size 3597 * @return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE : Undefined output video frame rate 3598 * @return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT : Undefined output audio format parameter 3599 * @return M4MCS_ERR_DURATION_IS_NULL : Specified output parameters define a null duration stream 3600 * (no audio and video) 3601 ****************************************************************************** 3602 */ 3603M4OSA_ERR M4MCS_setOutputParams( M4MCS_Context pContext, 3604 M4MCS_OutputParams *pParams ) 3605{ 3606 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 3607 M4OSA_UInt32 uiFrameWidth; 3608 M4OSA_UInt32 uiFrameHeight; 3609 M4OSA_ERR err; 3610 3611 M4OSA_TRACE2_2( 3612 "M4MCS_setOutputParams called with pContext=0x%x, pParams=0x%x", 3613 pContext, pParams); 3614 3615 /** 3616 * Check input parameters */ 3617 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 3618 "M4MCS_setOutputParams: pContext is M4OSA_NULL"); 3619 M4OSA_DEBUG_IF2((M4OSA_NULL == pParams), M4ERR_PARAMETER, 3620 "M4MCS_setOutputParams: pParam is M4OSA_NULL"); 3621 3622#ifdef M4MCS_SUPPORT_STILL_PICTURE 3623 3624 if( pC->m_bIsStillPicture ) 3625 { 3626 /** 3627 * Call the corresponding still picture MCS function*/ 3628 return M4MCS_stillPicSetOutputParams(pC, pParams); 3629 } 3630 3631#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 3632 3633 /** 3634 * Check state automaton */ 3635 3636 if( M4MCS_kState_OPENED != pC->State ) 3637 { 3638 M4OSA_TRACE1_1( 3639 "M4MCS_setOutputParams(): Wrong State (%d), returning M4ERR_STATE", 3640 pC->State); 3641 return M4ERR_STATE; 3642 } 3643 3644 /* Ignore audio or video stream if the output do not need it, */ 3645 /* or if the input file does not have any audio or video stream */ 3646 /*FlB 26.02.2009: add mp3 as mcs output format*/ 3647 if( ( pParams->OutputVideoFormat == M4VIDEOEDITING_kNoneVideo) 3648 || (pC->VideoState == M4MCS_kStreamState_NOSTREAM) 3649 || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_AMR) 3650 || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP3) ) 3651 { 3652 pC->novideo = M4OSA_TRUE; 3653 } 3654 3655 if( ( pParams->OutputAudioFormat == M4VIDEOEDITING_kNoneAudio) 3656 || (pC->AudioState == M4MCS_kStreamState_NOSTREAM) ) 3657 { 3658 pC->noaudio = M4OSA_TRUE; 3659 } 3660 3661 if( pC->noaudio && pC->novideo ) 3662 { 3663 M4OSA_TRACE1_0( 3664 "!!! M4MCS_setOutputParams : clip is NULL, there is no audio, no video"); 3665 return M4MCS_ERR_DURATION_IS_NULL; 3666 } 3667 3668 /* Set writer */ 3669 err = M4MCS_setCurrentWriter(pContext, pParams->OutputFileType); 3670 M4ERR_CHECK_RETURN(err); 3671 3672 /* Set video parameters */ 3673 if( pC->novideo == M4OSA_FALSE ) 3674 { 3675#ifdef TIMESCALE_BUG 3676 /* Check if we are in timescale modification */ 3677 3678 if( pParams->OutputVideoTimescale != 0 ) 3679 { 3680 pC->uiVideoTimescale = pParams->OutputVideoTimescale; 3681 3682 /* If timescale modification mode is on, we force NULL video encoding ... */ 3683 pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo; 3684 } 3685 3686#endif 3687 3688 /** 3689 * Check Video Format correctness */ 3690 3691 switch( pParams->OutputVideoFormat ) 3692 { 3693 case M4VIDEOEDITING_kH263: 3694 if( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4 ) 3695 return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE; 3696 3697 pC->EncodingVideoFormat = M4ENCODER_kH263; 3698 err = M4MCS_setCurrentVideoEncoder(pContext, 3699 pParams->OutputVideoFormat); 3700 M4ERR_CHECK_RETURN(err); 3701 break; 3702 3703 case M4VIDEOEDITING_kMPEG4_EMP: 3704 pC->bActivateEmp = M4OSA_TRUE; 3705 3706 case M4VIDEOEDITING_kMPEG4: 3707 3708 pC->EncodingVideoFormat = M4ENCODER_kMPEG4; 3709 err = M4MCS_setCurrentVideoEncoder(pContext, 3710 pParams->OutputVideoFormat); 3711 M4ERR_CHECK_RETURN(err); 3712 break; 3713 3714 case M4VIDEOEDITING_kH264: 3715 3716 pC->EncodingVideoFormat = M4ENCODER_kH264; 3717 err = M4MCS_setCurrentVideoEncoder(pContext, 3718 pParams->OutputVideoFormat); 3719 M4ERR_CHECK_RETURN(err); 3720 break; 3721 3722 case M4VIDEOEDITING_kNullVideo: 3723 if( ( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4) 3724 && (pC->InputFileProperties.VideoStreamType 3725 == M4VIDEOEDITING_kH263) ) 3726 return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE; 3727 3728 3729 /* If input file is EMP, output file will be too */ 3730 3731 if( pC->InputFileProperties.VideoStreamType 3732 == M4VIDEOEDITING_kMPEG4_EMP ) 3733 pC->bActivateEmp = M4OSA_TRUE; 3734 3735 /* Encoder needed for begin cut to generate an I-frame */ 3736 pC->EncodingVideoFormat = M4ENCODER_kNULL; 3737 err = M4MCS_setCurrentVideoEncoder(pContext, 3738 pC->InputFileProperties.VideoStreamType); 3739 M4ERR_CHECK_RETURN(err); 3740 break; 3741 3742 default: 3743 M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output video format (%d),\ 3744 returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", 3745 pParams->OutputVideoFormat); 3746 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; 3747 } 3748 3749 /** 3750 * Check Video frame size correctness */ 3751 if( M4VIDEOEDITING_kNullVideo == pParams->OutputVideoFormat ) 3752 { 3753 uiFrameWidth = 3754 pC->EncodingWidth = pC->InputFileProperties.uiVideoWidth; 3755 uiFrameHeight = 3756 pC->EncodingHeight = pC->InputFileProperties.uiVideoHeight; 3757 } 3758 else 3759 { 3760 switch( pParams->OutputVideoFrameSize ) 3761 { 3762 case M4VIDEOEDITING_kSQCIF: 3763 uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width; 3764 uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height; 3765 break; 3766 3767 case M4VIDEOEDITING_kQQVGA: 3768 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width; 3769 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height; 3770 break; 3771 3772 case M4VIDEOEDITING_kQCIF: 3773 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width; 3774 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height; 3775 break; 3776 3777 case M4VIDEOEDITING_kQVGA: 3778 uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width; 3779 uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height; 3780 break; 3781 3782 case M4VIDEOEDITING_kCIF: 3783 uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width; 3784 uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height; 3785 break; 3786 3787 case M4VIDEOEDITING_kVGA: 3788 uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width; 3789 uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height; 3790 break; 3791 /* +PR LV5807 */ 3792 case M4VIDEOEDITING_kWVGA: 3793 uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width; 3794 uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height; 3795 break; 3796 3797 case M4VIDEOEDITING_kNTSC: 3798 uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width; 3799 uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height; 3800 break; 3801 /* -PR LV5807*/ 3802 /* +CR Google */ 3803 case M4VIDEOEDITING_k640_360: 3804 uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width; 3805 uiFrameHeight = 3806 pC->EncodingHeight = M4ENCODER_640_360_Height; 3807 break; 3808 3809 case M4VIDEOEDITING_k854_480: 3810 uiFrameWidth = pC->EncodingWidth = M4ENCODER_854_480_Width; 3811 uiFrameHeight = 3812 pC->EncodingHeight = M4ENCODER_854_480_Height; 3813 break; 3814 3815 case M4VIDEOEDITING_kHD1280: 3816 uiFrameWidth = pC->EncodingWidth = M4ENCODER_HD1280_Width; 3817 uiFrameHeight = 3818 pC->EncodingHeight = M4ENCODER_HD1280_Height; 3819 break; 3820 3821 case M4VIDEOEDITING_kHD1080: 3822 uiFrameWidth = pC->EncodingWidth = M4ENCODER_HD1080_Width; 3823 uiFrameHeight = 3824 pC->EncodingHeight = M4ENCODER_HD1080_Height; 3825 break; 3826 3827 case M4VIDEOEDITING_kHD960: 3828 uiFrameWidth = pC->EncodingWidth = M4ENCODER_HD960_Width; 3829 uiFrameHeight = pC->EncodingHeight = M4ENCODER_HD960_Height; 3830 break; 3831 /* -CR Google */ 3832 default: 3833 M4OSA_TRACE1_1( 3834 "M4MCS_setOutputParams: Undefined output video frame size \ 3835 (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE", 3836 pParams->OutputVideoFrameSize); 3837 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; 3838 } 3839 } 3840 3841 /** 3842 * Compute video max au size and max chunck size. 3843 * We do it here because it depends on the frame size only, and 3844 * because we need it for the file size/video bitrate estimations */ 3845 pC->uiVideoMaxAuSize = 3846 (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \ 3847 *M4MCS_VIDEO_MIN_COMPRESSION_RATIO); 3848 pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize \ 3849 * 3850 M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */ 3851 3852 if( 0 == pC->uiVideoMaxAuSize ) 3853 { 3854 /* Size may be zero in case of null encoding with unrecognized stream */ 3855 M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\ 3856 M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE"); 3857 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE; 3858 } 3859 3860 3861 /** 3862 * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */ 3863 3864 if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) 3865 { 3866 switch( pParams->OutputVideoFrameSize ) 3867 { 3868 case M4VIDEOEDITING_kSQCIF: 3869 case M4VIDEOEDITING_kQCIF: 3870 case M4VIDEOEDITING_kCIF: 3871 /* OK */ 3872 break; 3873 3874 default: 3875 M4OSA_TRACE1_0( 3876 "M4MCS_setOutputParams():\ 3877 returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263"); 3878 return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263; 3879 } 3880 } 3881 3882 /** 3883 * Check Video Frame rate correctness */ 3884 if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat ) 3885 { 3886 switch( pParams->OutputVideoFrameRate ) 3887 { 3888 case M4VIDEOEDITING_k5_FPS: 3889 pC->EncodingVideoFramerate = M4ENCODER_k5_FPS; 3890 break; 3891 3892 case M4VIDEOEDITING_k7_5_FPS: 3893 pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS; 3894 break; 3895 3896 case M4VIDEOEDITING_k10_FPS: 3897 pC->EncodingVideoFramerate = M4ENCODER_k10_FPS; 3898 break; 3899 3900 case M4VIDEOEDITING_k12_5_FPS: 3901 pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS; 3902 break; 3903 3904 case M4VIDEOEDITING_k15_FPS: 3905 pC->EncodingVideoFramerate = M4ENCODER_k15_FPS; 3906 break; 3907 3908 case M4VIDEOEDITING_k20_FPS: 3909 pC->EncodingVideoFramerate = M4ENCODER_k20_FPS; 3910 break; 3911 3912 case M4VIDEOEDITING_k25_FPS: 3913 pC->EncodingVideoFramerate = M4ENCODER_k25_FPS; 3914 break; 3915 3916 case M4VIDEOEDITING_k30_FPS: 3917 pC->EncodingVideoFramerate = M4ENCODER_k30_FPS; 3918 break; 3919 3920 default: 3921 M4OSA_TRACE1_1( 3922 "M4MCS_setOutputParams: Undefined output video frame rate\ 3923 (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", 3924 pParams->OutputVideoFrameRate); 3925 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; 3926 } 3927 } 3928 3929 /** 3930 * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */ 3931 if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat ) 3932 { 3933 switch( pC->EncodingVideoFramerate ) 3934 { 3935 case M4ENCODER_k5_FPS: 3936 case M4ENCODER_k7_5_FPS: 3937 case M4ENCODER_k10_FPS: 3938 case M4ENCODER_k15_FPS: 3939 case M4ENCODER_k30_FPS: 3940 /* OK */ 3941 break; 3942 3943 default: 3944 M4OSA_TRACE1_0( 3945 "M4MCS_setOutputParams():\ 3946 returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263"); 3947 return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263; 3948 } 3949 } 3950 } 3951 3952 /* Set audio parameters */ 3953 if( pC->noaudio == M4OSA_FALSE ) 3954 { 3955 /** 3956 * Check Audio Format correctness */ 3957 switch( pParams->OutputAudioFormat ) 3958 { 3959 case M4VIDEOEDITING_kAMR_NB: 3960 3961 err = M4MCS_setCurrentAudioEncoder(pContext, 3962 pParams->OutputAudioFormat); 3963 M4ERR_CHECK_RETURN(err); 3964 3965 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 3966 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 3967 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 3968 pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID; 3969 break; 3970 3971 case M4VIDEOEDITING_kAAC: 3972 3973 err = M4MCS_setCurrentAudioEncoder(pContext, 3974 pParams->OutputAudioFormat); 3975 M4ERR_CHECK_RETURN(err); 3976 3977 pC->AudioEncParams.Format = M4ENCODER_kAAC; 3978 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 3979 3980 switch( pParams->OutputAudioSamplingFrequency ) 3981 { 3982 case M4VIDEOEDITING_k8000_ASF: 3983 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 3984 break; 3985 3986 case M4VIDEOEDITING_k16000_ASF: 3987 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 3988 break; 3989 3990 case M4VIDEOEDITING_k22050_ASF: 3991 pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; 3992 break; 3993 3994 case M4VIDEOEDITING_k24000_ASF: 3995 pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; 3996 break; 3997 3998 case M4VIDEOEDITING_k32000_ASF: 3999 pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; 4000 break; 4001 4002 case M4VIDEOEDITING_k44100_ASF: 4003 pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; 4004 break; 4005 4006 case M4VIDEOEDITING_k48000_ASF: 4007 pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; 4008 break; 4009 4010 case M4VIDEOEDITING_k11025_ASF: 4011 case M4VIDEOEDITING_k12000_ASF: 4012 case M4VIDEOEDITING_kDefault_ASF: 4013 break; 4014 } 4015 pC->AudioEncParams.ChannelNum = 4016 (pParams->bAudioMono == M4OSA_TRUE) ? \ 4017 M4ENCODER_kMono : M4ENCODER_kStereo; 4018 pC->AudioEncParams.SpecifParam.AacParam.Regulation = 4019 M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir 4020 /* unused */ 4021 pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE; 4022 pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE; 4023 pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE; 4024 pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE; 4025 /* TODO change into highspeed asap */ 4026 pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = 4027 M4OSA_FALSE; 4028 break; 4029 4030 /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ 4031 case M4VIDEOEDITING_kMP3: 4032 err = M4MCS_setCurrentAudioEncoder(pContext, 4033 pParams->OutputAudioFormat); 4034 M4ERR_CHECK_RETURN(err); 4035 4036 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4037 pC->AudioEncParams.ChannelNum = 4038 (pParams->bAudioMono == M4OSA_TRUE) ? \ 4039 M4ENCODER_kMono : M4ENCODER_kStereo; 4040 4041 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4042 4043 switch( pParams->OutputAudioSamplingFrequency ) 4044 { 4045 case M4VIDEOEDITING_k8000_ASF: 4046 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4047 break; 4048 4049 case M4VIDEOEDITING_k11025_ASF: 4050 pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz; 4051 break; 4052 4053 case M4VIDEOEDITING_k12000_ASF: 4054 pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz; 4055 break; 4056 4057 case M4VIDEOEDITING_k16000_ASF: 4058 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4059 break; 4060 4061 case M4VIDEOEDITING_k22050_ASF: 4062 pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz; 4063 break; 4064 4065 case M4VIDEOEDITING_k24000_ASF: 4066 pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz; 4067 break; 4068 4069 case M4VIDEOEDITING_k32000_ASF: 4070 pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz; 4071 break; 4072 4073 case M4VIDEOEDITING_k44100_ASF: 4074 pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz; 4075 break; 4076 4077 case M4VIDEOEDITING_k48000_ASF: 4078 pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz; 4079 break; 4080 4081 case M4VIDEOEDITING_kDefault_ASF: 4082 break; 4083 } 4084 4085 break; 4086 4087 case M4VIDEOEDITING_kNullAudio: 4088 if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 ) 4089 { 4090 /* no encoder needed */ 4091 pC->AudioEncParams.Format = M4ENCODER_kAudioNULL; 4092 pC->AudioEncParams.Frequency = 4093 pC->pReaderAudioStream->m_samplingFrequency; 4094 pC->AudioEncParams.ChannelNum = 4095 (pC->pReaderAudioStream->m_nbChannels == 1) ? \ 4096 M4ENCODER_kMono : M4ENCODER_kStereo; 4097 } 4098 else 4099 { 4100 pC->AudioEncParams.Frequency = 4101 pC->pReaderAudioStream->m_samplingFrequency; 4102 pC->AudioEncParams.ChannelNum = 4103 (pC->pReaderAudioStream->m_nbChannels == 1) ? \ 4104 M4ENCODER_kMono : M4ENCODER_kStereo; 4105 4106 switch( pC->InputFileProperties.AudioStreamType ) 4107 { 4108 case M4VIDEOEDITING_kAMR_NB: 4109 M4OSA_TRACE3_0( 4110 "M4MCS_setOutputParams calling \ 4111 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR"); 4112 err = M4MCS_setCurrentAudioEncoder(pContext, 4113 pC->InputFileProperties.AudioStreamType); 4114 M4ERR_CHECK_RETURN(err); 4115 4116 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 4117 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4118 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 4119 4120 if( pC->pReaderAudioStream->m_samplingFrequency 4121 != 8000 ) 4122 { 4123 pC->AudioEncParams.Format = M4ENCODER_kAMRNB; 4124 } 4125 pC->AudioEncParams.SpecifParam.AmrSID = 4126 M4ENCODER_kAmrNoSID; 4127 break; 4128 4129 case M4VIDEOEDITING_kAAC: 4130 M4OSA_TRACE3_0( 4131 "M4MCS_setOutputParams calling \ 4132 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC"); 4133 err = M4MCS_setCurrentAudioEncoder(pContext, 4134 pC->InputFileProperties.AudioStreamType); 4135 M4ERR_CHECK_RETURN(err); 4136 4137 pC->AudioEncParams.Format = M4ENCODER_kAAC; 4138 pC->AudioEncParams.SpecifParam.AacParam.Regulation = 4139 M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir 4140 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4141 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4142 4143 switch( pC->pReaderAudioStream-> 4144 m_samplingFrequency ) 4145 { 4146 case 16000: 4147 pC->AudioEncParams.Frequency = 4148 M4ENCODER_k16000Hz; 4149 break; 4150 4151 case 22050: 4152 pC->AudioEncParams.Frequency = 4153 M4ENCODER_k22050Hz; 4154 break; 4155 4156 case 24000: 4157 pC->AudioEncParams.Frequency = 4158 M4ENCODER_k24000Hz; 4159 break; 4160 4161 case 32000: 4162 pC->AudioEncParams.Frequency = 4163 M4ENCODER_k32000Hz; 4164 break; 4165 4166 case 44100: 4167 pC->AudioEncParams.Frequency = 4168 M4ENCODER_k44100Hz; 4169 break; 4170 4171 case 48000: 4172 pC->AudioEncParams.Frequency = 4173 M4ENCODER_k48000Hz; 4174 break; 4175 4176 default: 4177 pC->AudioEncParams.Format = M4ENCODER_kAAC; 4178 break; 4179 } 4180 /* unused */ 4181 pC->AudioEncParams.SpecifParam.AacParam.bIS = 4182 M4OSA_FALSE; 4183 pC->AudioEncParams.SpecifParam.AacParam.bMS = 4184 M4OSA_FALSE; 4185 pC->AudioEncParams.SpecifParam.AacParam.bPNS = 4186 M4OSA_FALSE; 4187 pC->AudioEncParams.SpecifParam.AacParam.bTNS = 4188 M4OSA_FALSE; 4189 /* TODO change into highspeed asap */ 4190 pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed = 4191 M4OSA_FALSE; 4192 break; 4193 4194 case M4VIDEOEDITING_kMP3: 4195 M4OSA_TRACE3_0( 4196 "M4MCS_setOutputParams calling\ 4197 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3"); 4198 err = M4MCS_setCurrentAudioEncoder(pContext, 4199 pC->InputFileProperties.AudioStreamType); 4200 M4ERR_CHECK_RETURN(err); 4201 4202 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4203 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz; 4204 4205 switch( pC->pReaderAudioStream-> 4206 m_samplingFrequency ) 4207 { 4208 case 8000: 4209 pC->AudioEncParams.Frequency = 4210 M4ENCODER_k8000Hz; 4211 break; 4212 4213 case 16000: 4214 pC->AudioEncParams.Frequency = 4215 M4ENCODER_k16000Hz; 4216 break; 4217 4218 case 22050: 4219 pC->AudioEncParams.Frequency = 4220 M4ENCODER_k22050Hz; 4221 break; 4222 4223 case 24000: 4224 pC->AudioEncParams.Frequency = 4225 M4ENCODER_k24000Hz; 4226 break; 4227 4228 case 32000: 4229 pC->AudioEncParams.Frequency = 4230 M4ENCODER_k32000Hz; 4231 break; 4232 4233 case 44100: 4234 pC->AudioEncParams.Frequency = 4235 M4ENCODER_k44100Hz; 4236 break; 4237 4238 case 48000: 4239 pC->AudioEncParams.Frequency = 4240 M4ENCODER_k48000Hz; 4241 break; 4242 4243 default: 4244 pC->AudioEncParams.Format = M4ENCODER_kMP3; 4245 break; 4246 } 4247 break; 4248 4249 case M4VIDEOEDITING_kEVRC: 4250 case M4VIDEOEDITING_kUnsupportedAudio: 4251 default: 4252 M4OSA_TRACE1_1( 4253 "M4MCS_setOutputParams: Output audio format (%d) is\ 4254 incompatible with audio effects, returning \ 4255 M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 4256 pC->InputFileProperties.AudioStreamType); 4257 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 4258 } 4259 } 4260 break; 4261 /* EVRC 4262 // case M4VIDEOEDITING_kEVRC: 4263 // 4264 // err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\ 4265 // OutputAudioFormat); 4266 // M4ERR_CHECK_RETURN(err); 4267 // 4268 // pC->AudioEncParams.Format = M4ENCODER_kEVRC; 4269 // pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz; 4270 // pC->AudioEncParams.ChannelNum = M4ENCODER_kMono; 4271 // break; */ 4272 4273 default: 4274 M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\ 4275 returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 4276 pParams->OutputAudioFormat); 4277 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 4278 } 4279 } 4280 4281 if( pParams->pOutputPCMfile != M4OSA_NULL ) 4282 { 4283 pC->pOutputPCMfile = pParams->pOutputPCMfile; 4284 4285 /* Open output PCM file */ 4286 pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile), 4287 pParams->pOutputPCMfile, M4OSA_kFileWrite); 4288 } 4289 else 4290 { 4291 pC->pOutputPCMfile = M4OSA_NULL; 4292 } 4293 4294 /*Store media rendering parameter into the internal context*/ 4295 pC->MediaRendering = pParams->MediaRendering; 4296 4297 /* Add audio effects*/ 4298 /*Copy MCS effects structure into internal context*/ 4299 if( pParams->nbEffects > 0 ) 4300 { 4301 M4OSA_UInt32 j = 0; 4302 pC->nbEffects = pParams->nbEffects; 4303 pC->pEffects = (M4MCS_EffectSettings *)M4OSA_malloc(pC->nbEffects \ 4304 *sizeof(M4MCS_EffectSettings), M4MCS, 4305 (M4OSA_Char *)"Allocation of effects list"); 4306 4307 if( pC->pEffects == M4OSA_NULL ) 4308 { 4309 M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error"); 4310 return M4ERR_ALLOC; 4311 } 4312 4313 for ( j = 0; j < pC->nbEffects; j++ ) 4314 { 4315 /* Copy effect to "local" structure */ 4316 M4OSA_memcpy((M4OSA_MemAddr8) &(pC->pEffects[j]), 4317 (M4OSA_MemAddr8) &(pParams->pEffects[j]), 4318 sizeof(M4MCS_EffectSettings)); 4319 4320 switch( pC->pEffects[j].AudioEffectType ) 4321 { 4322 case M4MCS_kAudioEffectType_None: 4323 M4OSA_TRACE3_1( 4324 "M4MCS_setOutputParams(): effect type %i is None", j); 4325 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4326 pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL; 4327 break; 4328 4329 case M4MCS_kAudioEffectType_FadeIn: 4330 M4OSA_TRACE3_1( 4331 "M4MCS_setOutputParams(): effect type %i is FadeIn", j); 4332 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4333 pC->pEffects[j].ExtAudioEffectFct = 4334 M4MCS_editAudioEffectFct_FadeIn; 4335 break; 4336 4337 case M4MCS_kAudioEffectType_FadeOut: 4338 M4OSA_TRACE3_1( 4339 "M4MCS_setOutputParams(): effect type %i is FadeOut", 4340 j); 4341 pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL; 4342 pC->pEffects[j].ExtAudioEffectFct = 4343 M4MCS_editAudioEffectFct_FadeOut; 4344 break; 4345 4346 case M4MCS_kAudioEffectType_External: 4347 M4OSA_TRACE3_1( 4348 "M4MCS_setOutputParams(): effect type %i is External", 4349 j); 4350 4351 if( pParams->pEffects != M4OSA_NULL ) 4352 { 4353 if( pParams->pEffects[j].ExtAudioEffectFct 4354 == M4OSA_NULL ) 4355 { 4356 M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\ 4357 associated to external effect number %i", j); 4358 return M4ERR_PARAMETER; 4359 } 4360 pC->pEffects[j].pExtAudioEffectFctCtxt = 4361 pParams->pEffects[j].pExtAudioEffectFctCtxt; 4362 4363 pC->pEffects[j].ExtAudioEffectFct = 4364 pParams->pEffects[j].ExtAudioEffectFct; 4365 } 4366 4367 break; 4368 4369 default: 4370 M4OSA_TRACE1_0( 4371 "M4MCS_setOutputParams(): effect type not recognized"); 4372 return M4ERR_PARAMETER; 4373 } 4374 } 4375 } 4376 else 4377 { 4378 pC->nbEffects = 0; 4379 pC->pEffects = M4OSA_NULL; 4380 } 4381 4382 /** 4383 * Update state automaton */ 4384 pC->State = M4MCS_kState_SET; 4385 4386 /** 4387 * Return with no error */ 4388 M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR"); 4389 return M4NO_ERROR; 4390} 4391 4392/** 4393 ****************************************************************************** 4394 * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) 4395 * @brief Set the values of the encoding parameters 4396 * @note Must be called before M4MCS_checkParamsAndStart(). 4397 * @param pContext (IN) MCS context 4398 * @param pRates (IN) Transcoding parameters 4399 * @return M4NO_ERROR: No error 4400 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 4401 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 4402 * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps) 4403 * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2 4404 * for amr, 8 for mp3) 4405 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals 4406 * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip 4407 * duration 4408 * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time 4409 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given 4410 * bitrates 4411 * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps) 4412 * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: Video bitrate too low 4413 ****************************************************************************** 4414 */ 4415M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext, 4416 M4MCS_EncodingParams *pRates ) 4417{ 4418 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 4419 M4OSA_UInt32 j = 0; 4420 4421 M4OSA_TRACE2_2( 4422 "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x", 4423 pContext, pRates); 4424 4425 /** 4426 * Check input parameters */ 4427 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 4428 "M4MCS_setEncodingParams: pContext is M4OSA_NULL"); 4429 M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER, 4430 "M4MCS_setEncodingParams: pRates is M4OSA_NULL"); 4431 4432#ifdef M4MCS_SUPPORT_STILL_PICTURE 4433 4434 if( pC->m_bIsStillPicture ) 4435 { 4436 /** 4437 * Call the corresponding still picture MCS function*/ 4438 return M4MCS_stillPicSetEncodingParams(pC, pRates); 4439 } 4440 4441#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 4442 4443 /** 4444 * Check state automaton */ 4445 4446 if( M4MCS_kState_SET != pC->State ) 4447 { 4448 M4OSA_TRACE1_1( 4449 "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE", 4450 pC->State); 4451 return M4ERR_STATE; 4452 } 4453 4454 /* Set given values */ 4455 pC->uiVideoBitrate = pRates->OutputVideoBitrate; 4456 pC->uiAudioBitrate = pRates->OutputAudioBitrate; 4457 pC->uiBeginCutTime = pRates->BeginCutTime; 4458 pC->uiEndCutTime = pRates->EndCutTime; 4459 pC->uiMaxFileSize = pRates->OutputFileSize; 4460 4461 /** 4462 * Check begin cut time validity */ 4463 if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration ) 4464 { 4465 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\ 4466 returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION", 4467 pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration); 4468 return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION; 4469 } 4470 4471 /** 4472 * If end cut time is too large, we set it to the clip duration */ 4473 if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration ) 4474 { 4475 pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; 4476 } 4477 4478 /** 4479 * Check end cut time validity */ 4480 if( pC->uiEndCutTime > 0 ) 4481 { 4482 if( pC->uiEndCutTime < pC->uiBeginCutTime ) 4483 { 4484 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \ 4485 returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT", 4486 pC->uiBeginCutTime, pC->uiEndCutTime); 4487 return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT; 4488 } 4489 4490 if( pC->uiEndCutTime == pC->uiBeginCutTime ) 4491 { 4492 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\ 4493 returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT", 4494 pC->uiBeginCutTime, pC->uiEndCutTime); 4495 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 4496 } 4497 } 4498 4499 /** 4500 * FlB 2009.03.04: check audio effects start time and duration validity*/ 4501 for ( j = 0; j < pC->nbEffects; j++ ) 4502 { 4503 M4OSA_UInt32 outputEndCut = pC->uiEndCutTime; 4504 4505 if( pC->uiEndCutTime == 0 ) 4506 { 4507 outputEndCut = pC->InputFileProperties.uiClipDuration; 4508 } 4509 4510 if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) ) 4511 { 4512 M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\ 4513 duration (%d,%d), returning M4ERR_PARAMETER", 4514 pC->pEffects[j].uiStartTime, 4515 (pC->uiEndCutTime - pC->uiBeginCutTime)); 4516 return M4ERR_PARAMETER; 4517 } 4518 4519 if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \ 4520 (outputEndCut - pC->uiBeginCutTime) ) 4521 { 4522 /* Re-adjust the effect duration until the end of the output clip*/ 4523 pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \ 4524 pC->pEffects[j].uiStartTime; 4525 } 4526 } 4527 4528 /* Check audio bitrate consistency */ 4529 if( ( pC->noaudio == M4OSA_FALSE) 4530 && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) ) 4531 { 4532 if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 4533 { 4534 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 4535 { 4536 if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS ) 4537 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4538 4539 if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS ) 4540 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4541 } 4542 //EVRC 4543 // else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) 4544 // { 4545 // if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS) 4546 // return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4547 // if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS) 4548 // return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4549 // } 4550 /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/ 4551 else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 4552 { 4553 if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz ) 4554 { 4555 /*Mpeg layer 1*/ 4556 if( pC->uiAudioBitrate > 320000 ) 4557 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4558 4559 if( pC->uiAudioBitrate < 32000 ) 4560 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4561 } 4562 else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz ) 4563 { 4564 /*Mpeg layer 2*/ 4565 if( pC->uiAudioBitrate > 160000 ) 4566 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4567 4568 if( ( pC->uiAudioBitrate < 8000 4569 && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4570 || (pC->uiAudioBitrate < 16000 4571 && pC->AudioEncParams.ChannelNum 4572 == M4ENCODER_kStereo) ) 4573 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4574 } 4575 else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz 4576 || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz 4577 || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz ) 4578 { 4579 /*Mpeg layer 2.5*/ 4580 if( pC->uiAudioBitrate > 64000 ) 4581 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4582 4583 if( ( pC->uiAudioBitrate < 8000 4584 && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4585 || (pC->uiAudioBitrate < 16000 4586 && pC->AudioEncParams.ChannelNum 4587 == M4ENCODER_kStereo) ) 4588 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4589 } 4590 else 4591 { 4592 M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\ 4593 (%d)", pC->AudioEncParams.Frequency); 4594 return M4ERR_PARAMETER; 4595 } 4596 } 4597 else 4598 { 4599 if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS ) 4600 return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH; 4601 4602 if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono ) 4603 { 4604 if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS ) 4605 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4606 } 4607 else 4608 { 4609 if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS ) 4610 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 4611 } 4612 } 4613 } 4614 } 4615 else 4616 { 4617 /* NULL audio : copy input file bitrate */ 4618 pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate; 4619 } 4620 4621 /* Check video bitrate consistency */ 4622 if( ( pC->novideo == M4OSA_FALSE) 4623 && (pC->EncodingVideoFormat != M4ENCODER_kNULL) ) 4624 { 4625 if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 4626 { 4627 if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4628 return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH; 4629 4630 if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS ) 4631 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; 4632 } 4633 } 4634 else 4635 { 4636 /* NULL video : copy input file bitrate */ 4637 pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate; 4638 } 4639 4640 if( pRates->OutputVideoTimescale <= 30000 4641 && pRates->OutputVideoTimescale > 0 ) 4642 { 4643 pC->outputVideoTimescale = pRates->OutputVideoTimescale; 4644 } 4645 4646 /* Check file size */ 4647 return M4MCS_intCheckMaxFileSize(pC); 4648} 4649 4650/** 4651 ****************************************************************************** 4652 * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates) 4653 * @brief Get the extended values of the encoding parameters 4654 * @note Could be called after M4MCS_setEncodingParams. 4655 * @param pContext (IN) MCS context 4656 * @param pRates (OUT) Transcoding parameters 4657 * @return M4NO_ERROR: No error 4658 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 4659 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 4660 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration 4661 * clip = encoding is impossible 4662 ****************************************************************************** 4663 */ 4664M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext, 4665 M4MCS_EncodingParams *pRates ) 4666{ 4667 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 4668 4669 M4OSA_Int32 minaudiobitrate; 4670 M4OSA_Int32 minvideobitrate; 4671 M4OSA_Int32 maxcombinedbitrate; 4672 4673 M4OSA_Int32 calcbitrate; 4674 4675 M4OSA_UInt32 maxduration; 4676 M4OSA_UInt32 calcduration; 4677 4678 M4OSA_Bool fixed_audio = M4OSA_FALSE; 4679 M4OSA_Bool fixed_video = M4OSA_FALSE; 4680 4681#ifdef M4MCS_SUPPORT_STILL_PICTURE 4682 4683 if( pC->m_bIsStillPicture ) 4684 { 4685 /** 4686 * Call the corresponding still picture MCS function*/ 4687 return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates); 4688 } 4689 4690#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 4691 4692 pRates->OutputVideoBitrate = 4693 M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0); 4694 pRates->OutputAudioBitrate = 4695 M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0); 4696 pRates->BeginCutTime = pC->uiBeginCutTime; 4697 pRates->EndCutTime = pC->uiEndCutTime; 4698 pRates->OutputFileSize = pC->uiMaxFileSize; 4699 4700 /** 4701 * Check state automaton */ 4702 if( M4MCS_kState_SET != pC->State ) 4703 { 4704 M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\ 4705 returning M4ERR_STATE", pC->State); 4706 return M4ERR_STATE; 4707 } 4708 4709 /* Compute min audio bitrate */ 4710 if( pC->noaudio ) 4711 { 4712 fixed_audio = M4OSA_TRUE; 4713 pRates->OutputAudioBitrate = 0; 4714 minaudiobitrate = 0; 4715 } 4716 else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 4717 { 4718 fixed_audio = M4OSA_TRUE; 4719 pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate; 4720 minaudiobitrate = pC->InputFileProperties.uiAudioBitrate; 4721 } 4722 else 4723 { 4724 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 4725 { 4726 fixed_audio = M4OSA_TRUE; 4727 pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS; 4728 minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS; 4729 } 4730 //EVRC 4731 // if(pC->AudioEncParams.Format == M4ENCODER_kEVRC) 4732 // { 4733 // fixed_audio = M4OSA_TRUE; 4734 // pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS; 4735 // minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS; 4736 // } 4737 /*FlB 26.02.2009: add mp3 as mcs output format*/ 4738 else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 4739 { 4740 minaudiobitrate = 4741 M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1, 4742 for both mono and stereo channels*/ 4743 } 4744 else 4745 { 4746 minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 4747 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; 4748 } 4749 } 4750 4751 /* Check audio bitrate is in the correct range */ 4752 if( fixed_audio == M4OSA_FALSE ) 4753 { 4754 if( ( pC->uiAudioBitrate > 0) 4755 && (pRates->OutputAudioBitrate < minaudiobitrate) ) 4756 { 4757 pRates->OutputAudioBitrate = minaudiobitrate; 4758 } 4759 4760 if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) 4761 { 4762 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4763 } 4764 } 4765 4766 /* Compute min video bitrate */ 4767 if( pC->novideo ) 4768 { 4769 fixed_video = M4OSA_TRUE; 4770 pRates->OutputVideoBitrate = 0; 4771 minvideobitrate = 0; 4772 } 4773 else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 4774 { 4775 fixed_video = M4OSA_TRUE; 4776 pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate; 4777 minvideobitrate = pC->InputFileProperties.uiVideoBitrate; 4778 } 4779 else 4780 { 4781 minvideobitrate = M4VIDEOEDITING_k16_KBPS; 4782 } 4783 4784 /* Check video bitrate is in the correct range */ 4785 if( fixed_video == M4OSA_FALSE ) 4786 { 4787 if( ( pC->uiVideoBitrate > 0) 4788 && (pRates->OutputVideoBitrate < minvideobitrate) ) 4789 { 4790 pRates->OutputVideoBitrate = minvideobitrate; 4791 } 4792 /*+ New Encoder bitrates */ 4793 if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4794 { 4795 pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; 4796 } 4797 /*- New Encoder bitrates */ 4798 } 4799 4800 /* Check cut times are in correct range */ 4801 if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration) 4802 || (( pRates->BeginCutTime >= pRates->EndCutTime) 4803 && (pRates->EndCutTime > 0)) ) 4804 { 4805 pRates->BeginCutTime = 0; 4806 pRates->EndCutTime = 0; 4807 } 4808 4809 if( pRates->EndCutTime == 0 ) 4810 calcduration = 4811 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 4812 else 4813 calcduration = pRates->EndCutTime - pRates->BeginCutTime; 4814 4815 /* priority 1 : max file size */ 4816 if( pRates->OutputFileSize == 0 ) 4817 { 4818 /* we can put maximum values for all undefined parameters */ 4819 if( pRates->EndCutTime == 0 ) 4820 { 4821 pRates->EndCutTime = pC->InputFileProperties.uiClipDuration; 4822 } 4823 4824 if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) 4825 && (fixed_audio == M4OSA_FALSE) ) 4826 { 4827 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4828 } 4829 4830 if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) 4831 && (fixed_video == M4OSA_FALSE) ) 4832 { 4833 /*+ New Encoder bitrates */ 4834 pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS; 4835 /*- New Encoder bitrates */ 4836 } 4837 } 4838 else 4839 { 4840 /* compute max duration */ 4841 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 4842 / M4MCS_MOOV_OVER_FILESIZE_RATIO 4843 / (minvideobitrate + minaudiobitrate) * 8000.0); 4844 4845 if( maxduration 4846 + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) 4847 { 4848 maxduration = 4849 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 4850 } 4851 4852 /* priority 2 : cut times */ 4853 if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) ) 4854 { 4855 if( calcduration > maxduration ) 4856 { 4857 calcduration = maxduration; 4858 } 4859 4860 if( calcduration == 0 ) 4861 { 4862 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 4863 } 4864 4865 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 4866 / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0)); 4867 4868 /* audio and video bitrates */ 4869 if( ( pRates->OutputAudioBitrate 4870 == M4VIDEOEDITING_kUndefinedBitrate) 4871 && (pRates->OutputVideoBitrate 4872 == M4VIDEOEDITING_kUndefinedBitrate) ) 4873 { 4874 /* set audio = 1/3 and video = 2/3 */ 4875 if( fixed_audio == M4OSA_FALSE ) 4876 { 4877 if( pC->novideo ) 4878 pRates->OutputAudioBitrate = 4879 M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0); 4880 else 4881 pRates->OutputAudioBitrate = 4882 M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3, 4883 0); 4884 4885 if( pRates->OutputAudioBitrate < minaudiobitrate ) 4886 pRates->OutputAudioBitrate = minaudiobitrate; 4887 4888 if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS ) 4889 pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS; 4890 } 4891 4892 if( fixed_video == M4OSA_FALSE ) 4893 { 4894 pRates->OutputVideoBitrate = 4895 M4MCS_intGetNearestBitrate(maxcombinedbitrate 4896 - pRates->OutputAudioBitrate, 0); 4897 4898 if( pRates->OutputVideoBitrate < minvideobitrate ) 4899 pRates->OutputVideoBitrate = minvideobitrate; 4900 4901 if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS ) 4902 pRates->OutputVideoBitrate = 4903 M4VIDEOEDITING_k8_MBPS; /*+ New Encoder 4904 bitrates */ 4905 } 4906 } 4907 else 4908 { 4909 /* priority 3 : audio bitrate */ 4910 if( pRates->OutputAudioBitrate 4911 != M4VIDEOEDITING_kUndefinedBitrate ) 4912 { 4913 while( ( fixed_audio == M4OSA_FALSE) 4914 && (pRates->OutputAudioBitrate >= minaudiobitrate) 4915 && (pRates->OutputAudioBitrate 4916 + minvideobitrate > maxcombinedbitrate) ) 4917 { 4918 pRates->OutputAudioBitrate = 4919 M4MCS_intGetNearestBitrate( 4920 pRates->OutputAudioBitrate, -1); 4921 } 4922 4923 if( ( fixed_audio == M4OSA_FALSE) 4924 && (pRates->OutputAudioBitrate < minaudiobitrate) ) 4925 { 4926 pRates->OutputAudioBitrate = minaudiobitrate; 4927 } 4928 4929 calcbitrate = M4MCS_intGetNearestBitrate( 4930 maxcombinedbitrate 4931 - pRates->OutputAudioBitrate, 0); 4932 4933 if( calcbitrate < minvideobitrate ) 4934 calcbitrate = minvideobitrate; 4935 4936 if( calcbitrate > M4VIDEOEDITING_k8_MBPS ) 4937 calcbitrate = M4VIDEOEDITING_k8_MBPS; 4938 4939 if( ( fixed_video == M4OSA_FALSE) 4940 && (( pRates->OutputVideoBitrate 4941 == M4VIDEOEDITING_kUndefinedBitrate) 4942 || (pRates->OutputVideoBitrate > calcbitrate)) ) 4943 { 4944 pRates->OutputVideoBitrate = calcbitrate; 4945 } 4946 } 4947 else 4948 { 4949 /* priority 4 : video bitrate */ 4950 if( pRates->OutputVideoBitrate 4951 != M4VIDEOEDITING_kUndefinedBitrate ) 4952 { 4953 while( ( fixed_video == M4OSA_FALSE) 4954 && (pRates->OutputVideoBitrate >= minvideobitrate) 4955 && (pRates->OutputVideoBitrate 4956 + minaudiobitrate > maxcombinedbitrate) ) 4957 { 4958 pRates->OutputVideoBitrate = 4959 M4MCS_intGetNearestBitrate( 4960 pRates->OutputVideoBitrate, -1); 4961 } 4962 4963 if( ( fixed_video == M4OSA_FALSE) 4964 && (pRates->OutputVideoBitrate < minvideobitrate) ) 4965 { 4966 pRates->OutputVideoBitrate = minvideobitrate; 4967 } 4968 4969 calcbitrate = 4970 M4MCS_intGetNearestBitrate(maxcombinedbitrate 4971 - pRates->OutputVideoBitrate, 0); 4972 4973 if( calcbitrate < minaudiobitrate ) 4974 calcbitrate = minaudiobitrate; 4975 4976 if( calcbitrate > M4VIDEOEDITING_k96_KBPS ) 4977 calcbitrate = M4VIDEOEDITING_k96_KBPS; 4978 4979 if( ( fixed_audio == M4OSA_FALSE) 4980 && (( pRates->OutputAudioBitrate 4981 == M4VIDEOEDITING_kUndefinedBitrate) 4982 || (pRates->OutputAudioBitrate > calcbitrate)) ) 4983 { 4984 pRates->OutputAudioBitrate = calcbitrate; 4985 } 4986 } 4987 } 4988 } 4989 } 4990 else 4991 { 4992 /* priority 3 : audio bitrate */ 4993 if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate ) 4994 { 4995 /* priority 4 : video bitrate */ 4996 if( pRates->OutputVideoBitrate 4997 != M4VIDEOEDITING_kUndefinedBitrate ) 4998 { 4999 /* compute max duration */ 5000 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5001 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5002 / (pRates->OutputVideoBitrate 5003 + pRates->OutputAudioBitrate) * 8000.0); 5004 5005 if( maxduration + pRates->BeginCutTime 5006 > pC->InputFileProperties.uiClipDuration ) 5007 { 5008 maxduration = pC->InputFileProperties.uiClipDuration 5009 - pRates->BeginCutTime; 5010 } 5011 5012 if( calcduration > maxduration ) 5013 { 5014 calcduration = maxduration; 5015 } 5016 5017 if( calcduration == 0 ) 5018 { 5019 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5020 } 5021 } 5022 else 5023 { 5024 /* start with min video bitrate */ 5025 pRates->OutputVideoBitrate = minvideobitrate; 5026 5027 /* compute max duration */ 5028 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5029 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5030 / (pRates->OutputVideoBitrate 5031 + pRates->OutputAudioBitrate) * 8000.0); 5032 5033 if( maxduration + pRates->BeginCutTime 5034 > pC->InputFileProperties.uiClipDuration ) 5035 { 5036 maxduration = pC->InputFileProperties.uiClipDuration 5037 - pRates->BeginCutTime; 5038 } 5039 5040 if( calcduration > maxduration ) 5041 { 5042 calcduration = maxduration; 5043 } 5044 5045 if( calcduration == 0 ) 5046 { 5047 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5048 } 5049 5050 /* search max possible video bitrate */ 5051 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5052 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5053 / (calcduration / 8000.0)); 5054 5055 while( ( fixed_video == M4OSA_FALSE) 5056 && (pRates->OutputVideoBitrate 5057 < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */ 5058 { 5059 calcbitrate = M4MCS_intGetNearestBitrate( 5060 pRates->OutputVideoBitrate, +1); 5061 5062 if( calcbitrate 5063 + pRates->OutputAudioBitrate <= maxcombinedbitrate ) 5064 pRates->OutputVideoBitrate = calcbitrate; 5065 else 5066 break; 5067 } 5068 } 5069 } 5070 else 5071 { 5072 /* priority 4 : video bitrate */ 5073 if( pRates->OutputVideoBitrate 5074 != M4VIDEOEDITING_kUndefinedBitrate ) 5075 { 5076 /* start with min audio bitrate */ 5077 pRates->OutputAudioBitrate = minaudiobitrate; 5078 5079 /* compute max duration */ 5080 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5081 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5082 / (pRates->OutputVideoBitrate 5083 + pRates->OutputAudioBitrate) * 8000.0); 5084 5085 if( maxduration + pRates->BeginCutTime 5086 > pC->InputFileProperties.uiClipDuration ) 5087 { 5088 maxduration = pC->InputFileProperties.uiClipDuration 5089 - pRates->BeginCutTime; 5090 } 5091 5092 if( calcduration > maxduration ) 5093 { 5094 calcduration = maxduration; 5095 } 5096 5097 if( calcduration == 0 ) 5098 { 5099 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5100 } 5101 5102 /* search max possible audio bitrate */ 5103 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5104 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5105 / (calcduration / 8000.0)); 5106 5107 while( ( fixed_audio == M4OSA_FALSE) 5108 && (pRates->OutputAudioBitrate 5109 < M4VIDEOEDITING_k96_KBPS) ) 5110 { 5111 calcbitrate = M4MCS_intGetNearestBitrate( 5112 pRates->OutputAudioBitrate, +1); 5113 5114 if( calcbitrate 5115 + pRates->OutputVideoBitrate <= maxcombinedbitrate ) 5116 pRates->OutputAudioBitrate = calcbitrate; 5117 else 5118 break; 5119 } 5120 } 5121 else 5122 { 5123 /* compute max duration */ 5124 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5125 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5126 / (minvideobitrate + minaudiobitrate) * 8000.0); 5127 5128 if( maxduration + pRates->BeginCutTime 5129 > pC->InputFileProperties.uiClipDuration ) 5130 { 5131 maxduration = pC->InputFileProperties.uiClipDuration 5132 - pRates->BeginCutTime; 5133 } 5134 5135 if( calcduration > maxduration ) 5136 { 5137 calcduration = maxduration; 5138 } 5139 5140 if( calcduration == 0 ) 5141 { 5142 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5143 } 5144 5145 /* set audio = 1/3 and video = 2/3 */ 5146 maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize 5147 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5148 / (calcduration / 8000.0)); 5149 5150 if( fixed_audio == M4OSA_FALSE ) 5151 { 5152 if( pC->novideo ) 5153 pRates->OutputAudioBitrate = 5154 M4MCS_intGetNearestBitrate(maxcombinedbitrate, 5155 0); 5156 else 5157 pRates->OutputAudioBitrate = 5158 M4MCS_intGetNearestBitrate(maxcombinedbitrate 5159 / 3, 0); 5160 5161 if( pRates->OutputAudioBitrate < minaudiobitrate ) 5162 pRates->OutputAudioBitrate = minaudiobitrate; 5163 5164 if( pRates->OutputAudioBitrate 5165 > M4VIDEOEDITING_k96_KBPS ) 5166 pRates->OutputAudioBitrate = 5167 M4VIDEOEDITING_k96_KBPS; 5168 } 5169 5170 if( fixed_video == M4OSA_FALSE ) 5171 { 5172 pRates->OutputVideoBitrate = 5173 M4MCS_intGetNearestBitrate(maxcombinedbitrate 5174 - pRates->OutputAudioBitrate, 0); 5175 5176 if( pRates->OutputVideoBitrate < minvideobitrate ) 5177 pRates->OutputVideoBitrate = minvideobitrate; 5178 5179 if( pRates->OutputVideoBitrate 5180 > M4VIDEOEDITING_k8_MBPS ) 5181 pRates->OutputVideoBitrate = 5182 M4VIDEOEDITING_k8_MBPS; /*+ New Encoder 5183 bitrates */ 5184 } 5185 } 5186 } 5187 } 5188 } 5189 5190 /* recompute max duration with final bitrates */ 5191 if( pRates->OutputFileSize > 0 ) 5192 { 5193 maxduration = (M4OSA_UInt32)(pRates->OutputFileSize 5194 / M4MCS_MOOV_OVER_FILESIZE_RATIO 5195 / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) 5196 * 8000.0); 5197 } 5198 else 5199 { 5200 maxduration = pC->InputFileProperties.uiClipDuration; 5201 } 5202 5203 if( maxduration 5204 + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration ) 5205 { 5206 maxduration = 5207 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime; 5208 } 5209 5210 if( pRates->EndCutTime == 0 ) 5211 { 5212 pRates->EndCutTime = pRates->BeginCutTime + maxduration; 5213 } 5214 else 5215 { 5216 calcduration = pRates->EndCutTime - pRates->BeginCutTime; 5217 5218 if( calcduration > maxduration ) 5219 { 5220 pRates->EndCutTime = pRates->BeginCutTime + maxduration; 5221 } 5222 } 5223 5224 /* Should never happen : constraints are too strong */ 5225 if( pRates->EndCutTime == pRates->BeginCutTime ) 5226 { 5227 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT; 5228 } 5229 5230 /* estimated resulting file size */ 5231 pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO 5232 * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate) 5233 * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0)); 5234 5235 return M4NO_ERROR; 5236} 5237 5238/** 5239 ****************************************************************************** 5240 * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext) 5241 * @brief Check parameters to start 5242 * @note 5243 * @param pContext (IN) MCS context 5244 * @return M4NO_ERROR: No error 5245 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 5246 * @return M4ERR_STATE: MCS is not in an appropriate state for 5247 * this function to be called 5248 * @return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: 5249 * Audio bitrate too high (we limit to 96 kbps) 5250 * @return M4MCS_ERR_AUDIOBITRATE_TOO_LOW: 5251 * Audio bitrate is too low (16 kbps min for aac, 5252 * 12.2 for amr, 8 for mp3) 5253 * @return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: 5254 * Begin cut and End cut are equals 5255 * @return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: 5256 * Begin cut time is larger than the input 5257 * clip duration 5258 * @return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: 5259 * End cut time is smaller than begin cut time 5260 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL: 5261 * Not enough space to store whole output 5262 * file at given bitrates 5263 * @return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: 5264 * Video bitrate too high (we limit to 800 kbps) 5265 * @return M4MCS_ERR_VIDEOBITRATE_TOO_LOW: 5266 * Video bitrate too low 5267 ****************************************************************************** 5268 */ 5269M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext ) 5270{ 5271 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 5272 M4MCS_EncodingParams VerifyRates; 5273 M4OSA_ERR err; 5274 5275 /** 5276 * Check input parameters */ 5277 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 5278 "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL"); 5279 5280#ifdef M4MCS_SUPPORT_STILL_PICTURE 5281 5282 if( pC->m_bIsStillPicture ) 5283 { 5284 /** 5285 * Call the corresponding still picture MCS function*/ 5286 return M4MCS_stillPicCheckParamsAndStart(pC); 5287 } 5288 5289#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 5290 5291 /** 5292 * Check state automaton */ 5293 5294 if( M4MCS_kState_SET != pC->State ) 5295 { 5296 M4OSA_TRACE1_1( 5297 "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE", 5298 pC->State); 5299 return M4ERR_STATE; 5300 } 5301 5302 /* Audio bitrate should not stay undefined at this point */ 5303 if( ( pC->noaudio == M4OSA_FALSE) 5304 && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) 5305 && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) 5306 { 5307 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate"); 5308 return M4MCS_ERR_AUDIOBITRATE_TOO_LOW; 5309 } 5310 5311 /* Video bitrate should not stay undefined at this point */ 5312 if( ( pC->novideo == M4OSA_FALSE) 5313 && (pC->EncodingVideoFormat != M4ENCODER_kNULL) 5314 && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) ) 5315 { 5316 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate"); 5317 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW; 5318 } 5319 5320 /* Set end cut time if necessary (not an error) */ 5321 if( pC->uiEndCutTime == 0 ) 5322 { 5323 pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration; 5324 } 5325 5326 /* Force a re-set to check validity of parameters */ 5327 VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate; 5328 VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate; 5329 VerifyRates.BeginCutTime = pC->uiBeginCutTime; 5330 VerifyRates.EndCutTime = pC->uiEndCutTime; 5331 VerifyRates.OutputFileSize = pC->uiMaxFileSize; 5332 VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale; 5333 5334 err = M4MCS_setEncodingParams(pContext, &VerifyRates); 5335 5336 /** 5337 * Check parameters consistency */ 5338 if( err != M4NO_ERROR ) 5339 { 5340 M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found"); 5341 return err; 5342 } 5343 5344 /** 5345 * All is OK : update state automaton */ 5346 pC->uiEncVideoBitrate = pC->uiVideoBitrate; 5347 pC->AudioEncParams.Bitrate = pC->uiAudioBitrate; 5348 5349#ifdef M4MCS_WITH_FAST_OPEN 5350 /** 5351 * Remake the open if it was done in fast mode */ 5352 5353 if( M4OSA_TRUE == pC->bFileOpenedInFastMode ) 5354 { 5355 /* Close the file opened in fast mode */ 5356 M4MCS_intCleanUp_ReadersDecoders(pC); 5357 5358 pC->State = M4MCS_kState_CREATED; 5359 5360 /* Reopen it in normal mode */ 5361 err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType, 5362 pC->pOutputFile, pC->pTemporaryFile); 5363 5364 if( err != M4NO_ERROR ) 5365 { 5366 M4OSA_TRACE1_1( 5367 "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err); 5368 return err; 5369 } 5370 } 5371 5372#endif /* M4MCS_WITH_FAST_OPEN */ 5373 5374 pC->State = M4MCS_kState_READY; 5375 5376 return M4NO_ERROR; 5377} 5378 5379/** 5380 ****************************************************************************** 5381 * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC) 5382 ****************************************************************************** 5383 */ 5384static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC ) 5385{ 5386 M4OSA_ERR err; 5387 M4ENCODER_Header *encHeader; 5388 5389 /** 5390 * Prepare the video decoder */ 5391 err = M4MCS_intPrepareVideoDecoder(pC); 5392 5393 if( M4NO_ERROR != err ) 5394 { 5395 M4OSA_TRACE1_1( 5396 "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x", 5397 err); 5398 return err; 5399 } 5400 5401 if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) 5402 && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) 5403 { 5404 pC->bH264Trim = M4OSA_TRUE; 5405 } 5406 5407 /** 5408 * Prepare the video encoder */ 5409 err = M4MCS_intPrepareVideoEncoder(pC); 5410 5411 if( M4NO_ERROR != err ) 5412 { 5413 M4OSA_TRACE1_1( 5414 "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x", 5415 err); 5416 return err; 5417 } 5418 5419 if( ( pC->uiBeginCutTime != 0) 5420 && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264) 5421 && (pC->EncodingVideoFormat == M4ENCODER_kNULL) ) 5422 { 5423 5424 err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, 5425 M4ENCODER_kOptionID_H264ProcessNALUContext, 5426 (M4OSA_DataOption)pC->m_pInstance); 5427 5428 if( err != M4NO_ERROR ) 5429 { 5430 M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", 5431 err); 5432 return err; 5433 } 5434 5435 err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt, 5436 M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr, 5437 (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU); 5438 5439 if( err != M4NO_ERROR ) 5440 { 5441 M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed (err 0x%x)", 5442 err); 5443 return err; 5444 } 5445 5446 err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt, 5447 M4ENCODER_kOptionID_EncoderHeader, 5448 (M4OSA_DataOption) &encHeader); 5449 5450 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) 5451 { 5452 M4OSA_TRACE1_1( 5453 "M4MCS_close: failed to get the encoder header (err 0x%x)", 5454 err); 5455 /**< no return here, we still have stuff to deallocate after close, even if it fails.*/ 5456 } 5457 else 5458 { 5459 // Handle DSI first bits 5460#define SPS_START_POS 6 5461 5462 pC->m_pInstance->m_encoderSPSSize = 5463 ( encHeader->pBuf[SPS_START_POS] << 8) 5464 + encHeader->pBuf[SPS_START_POS + 1]; 5465 pC->m_pInstance->m_pEncoderSPS = 5466 (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2; 5467 5468 pC->m_pInstance->m_encoderPPSSize = 5469 ( encHeader->pBuf[SPS_START_POS + 3 5470 + pC->m_pInstance->m_encoderSPSSize] << 8) 5471 + encHeader->pBuf[SPS_START_POS + 4 5472 + pC->m_pInstance->m_encoderSPSSize]; 5473 pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5 5474 + pC->m_pInstance->m_encoderSPSSize; 5475 5476 /* Check the DSI integrity */ 5477 if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize 5478 + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) ) 5479 { 5480 M4OSA_TRACE1_3( 5481 "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d", 5482 encHeader->Size, pC->m_pInstance->m_encoderSPSSize, 5483 pC->m_pInstance->m_encoderPPSSize); 5484 return M4ERR_PARAMETER; 5485 } 5486 } 5487 } 5488 5489 /** 5490 * Prepare audio processing */ 5491 err = M4MCS_intPrepareAudioProcessing(pC); 5492 5493 if( M4NO_ERROR != err ) 5494 { 5495 M4OSA_TRACE1_1( 5496 "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x", 5497 err); 5498 return err; 5499 } 5500 5501 /** 5502 * Prepare the writer */ 5503 err = M4MCS_intPrepareWriter(pC); 5504 5505 if( M4NO_ERROR != err ) 5506 { 5507 M4OSA_TRACE1_1( 5508 "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err); 5509 return err; 5510 } 5511 5512 /** 5513 * Jump the audio stream to the begin cut time (all AUs are RAP) 5514 * Must be done after the 3gpp writer init, because it may write the first 5515 * audio AU in some cases */ 5516 err = M4MCS_intPrepareAudioBeginCut(pC); 5517 5518 if( M4NO_ERROR != err ) 5519 { 5520 M4OSA_TRACE1_1( 5521 "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x", 5522 err); 5523 return err; 5524 } 5525 5526 /** 5527 * Update state automaton */ 5528 if( 0 == pC->uiBeginCutTime ) 5529 { 5530 pC->dViDecStartingCts = 0.0; 5531 /** 5532 * No begin cut, do the encoding */ 5533 pC->State = M4MCS_kState_PROCESSING; 5534 } 5535 else 5536 { 5537 /** 5538 * Remember that we must start the decode/encode process at the begin cut time */ 5539 pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime; 5540 5541 /** 5542 * Jumping */ 5543 pC->State = M4MCS_kState_BEGINVIDEOJUMP; 5544 } 5545 5546 /** 5547 * Return with no error */ 5548 M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR"); 5549 return M4NO_ERROR; 5550} 5551 5552/** 5553 ****************************************************************************** 5554 * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC); 5555 * @brief Prepare the video decoder. 5556 * @param pC (IN) MCS private context 5557 * @return M4NO_ERROR No error 5558 * @return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED 5559 * @return Any error returned by an underlaying module 5560 ****************************************************************************** 5561 */ 5562static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC ) 5563{ 5564 M4OSA_ERR err; 5565 M4OSA_Void *decoderUserData; 5566 M4DECODER_OutputFilter FilterOption; 5567 5568 if( pC->novideo ) 5569 return M4NO_ERROR; 5570 5571 /** 5572 * Create the decoder, if it has not been created yet (to get video properties for example) */ 5573 if( M4OSA_NULL == pC->pViDecCtxt ) 5574 { 5575#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 5576 5577 decoderUserData = pC->m_pCurrentVideoDecoderUserData; 5578 5579#else 5580 5581 decoderUserData = M4OSA_NULL; 5582 5583#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */ 5584 5585 err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt, 5586 &pC->pReaderVideoStream->m_basicProperties, pC->m_pReaderDataIt, 5587 &pC->ReaderVideoAU, decoderUserData); 5588 5589 if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err ) 5590 { 5591 /** 5592 * Our decoder is not compatible with H263 profile other than 0. 5593 * So it returns this internal error code. 5594 * We translate it to our own error code */ 5595 M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\ 5596 returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED"); 5597 return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED; 5598 } 5599 else if( M4NO_ERROR != err ) 5600 { 5601 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ 5602 m_pVideoDecoder->m_pFctCreate returns 0x%x", err); 5603 return err; 5604 } 5605 5606 if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType ) 5607 { 5608 FilterOption.m_pFilterFunction = 5609 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420; 5610 FilterOption.m_pFilterUserData = M4OSA_NULL; 5611 err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt, 5612 M4DECODER_kOptionID_OutputFilter, 5613 (M4OSA_DataOption) &FilterOption); 5614 5615 if( M4NO_ERROR != err ) 5616 { 5617 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\ 5618 m_pVideoDecoder->m_pFctSetOption returns 0x%x", err); 5619 return err; 5620 } 5621 } 5622 } 5623 5624 /** 5625 * Return with no error */ 5626 M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR"); 5627 return M4NO_ERROR; 5628} 5629 5630/** 5631 ****************************************************************************** 5632 * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC); 5633 * @brief Prepare the video encoder. 5634 * @param pC (IN) MCS private context 5635 * @return M4NO_ERROR No error 5636 * @return Any error returned by an underlaying module 5637 ****************************************************************************** 5638 */ 5639static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC ) 5640{ 5641 M4OSA_ERR err; 5642 M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */ 5643 M4ENCODER_Params EncParams1; 5644 M4OSA_Double dFrameRate; /**< tmp variable */ 5645 5646 if( pC->novideo ) 5647 return M4NO_ERROR; 5648 5649 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 5650 { 5651 /* Approximative cts increment */ 5652 pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate; 5653 5654 if( pC->uiBeginCutTime == 0 ) 5655 { 5656 M4OSA_TRACE3_0( 5657 "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing."); 5658 return M4NO_ERROR; 5659 } 5660 else 5661 { 5662 M4OSA_TRACE3_0( 5663 "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults."); 5664 5665 /* Set useful parameters to encode the first I-frame */ 5666 EncParams.InputFormat = M4ENCODER_kIYUV420; 5667 5668 switch( pC->InputFileProperties.VideoStreamType ) 5669 { 5670 case M4VIDEOEDITING_kH263: 5671 EncParams.Format = M4ENCODER_kH263; 5672 break; 5673 5674 case M4VIDEOEDITING_kMPEG4: 5675 case M4VIDEOEDITING_kMPEG4_EMP: 5676 EncParams.Format = M4ENCODER_kMPEG4; 5677 break; 5678 5679 case M4VIDEOEDITING_kH264: 5680 EncParams.Format = M4ENCODER_kH264; 5681 break; 5682 5683 default: 5684 M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\ 5685 (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED", 5686 pC->InputFileProperties.VideoStreamType); 5687 return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED; 5688 } 5689 5690 EncParams.FrameWidth = pC->EncodingWidth; 5691 EncParams.FrameHeight = pC->EncodingHeight; 5692 EncParams.Bitrate = pC->uiEncVideoBitrate; 5693 EncParams.bInternalRegulation = 5694 M4OSA_FALSE; /* do not constrain the I-frame */ 5695 EncParams.FrameRate = pC->EncodingVideoFramerate; 5696 5697 /* Other encoding settings (quite all dummy...) */ 5698 EncParams.uiHorizontalSearchRange = 0; /* use default */ 5699 EncParams.uiVerticalSearchRange = 0; /* use default */ 5700 EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */ 5701 EncParams.uiIVopPeriod = 0; /* use default */ 5702 EncParams.uiMotionEstimationTools = 5703 0; /* M4V_MOTION_EST_TOOLS_ALL */ 5704 EncParams.bAcPrediction = M4OSA_TRUE; /* use AC prediction */ 5705 EncParams.uiStartingQuantizerValue = 5; /* initial QP = 5 */ 5706 EncParams.bDataPartitioning = 5707 M4OSA_FALSE; /* no data partitioning */ 5708 5709 /* Rate factor */ 5710 EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale; 5711 EncParams.uiRateFactor = 1; 5712 } 5713 } 5714 else 5715 { 5716 M4OSA_TRACE3_0( 5717 "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config."); 5718 5719 /** 5720 * Set encoder shell parameters according to MCS settings */ 5721 EncParams.Format = pC->EncodingVideoFormat; 5722 EncParams.InputFormat = M4ENCODER_kIYUV420; 5723 5724 /** 5725 * Video frame size */ 5726 EncParams.FrameWidth = pC->EncodingWidth; 5727 EncParams.FrameHeight = pC->EncodingHeight; 5728 5729 /** 5730 * Video bitrate has been previously computed */ 5731 EncParams.Bitrate = pC->uiEncVideoBitrate; 5732 5733 /** 5734 * MCS use the "true" core internal bitrate regulation */ 5735 EncParams.bInternalRegulation = M4OSA_TRUE; 5736 5737 /** 5738 * Other encoder settings */ 5739 if( M4OSA_TRUE == pC->bActivateEmp ) 5740 { 5741 EncParams.uiHorizontalSearchRange = 15; /* set value */ 5742 EncParams.uiVerticalSearchRange = 15; /* set value */ 5743 EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */ 5744 EncParams.uiIVopPeriod = 15; /* one I frame every 15 frames */ 5745 EncParams.uiMotionEstimationTools = 5746 1; /* M4V_MOTION_EST_TOOLS_NO_4MV */ 5747 EncParams.bAcPrediction = M4OSA_FALSE; /* no AC prediction */ 5748 EncParams.uiStartingQuantizerValue = 10; /* initial QP = 10 */ 5749 EncParams.bDataPartitioning = 5750 M4OSA_FALSE; /* no data partitioning */ 5751 } 5752 else 5753 { 5754 EncParams.uiHorizontalSearchRange = 0; /* use default */ 5755 EncParams.uiVerticalSearchRange = 0; /* use default */ 5756 EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */ 5757 EncParams.uiIVopPeriod = 0; /* use default */ 5758 EncParams.uiMotionEstimationTools = 5759 0; /* M4V_MOTION_EST_TOOLS_ALL */ 5760 EncParams.bAcPrediction = M4OSA_TRUE; /* use AC prediction */ 5761 EncParams.uiStartingQuantizerValue = 10; /* initial QP = 10 */ 5762 EncParams.bDataPartitioning = 5763 M4OSA_FALSE; /* no data partitioning */ 5764 } 5765 5766 /** 5767 * Video encoder frame rate and rate factor */ 5768 EncParams.FrameRate = pC->EncodingVideoFramerate; 5769 EncParams.uiTimeScale = pC->outputVideoTimescale; 5770 5771 switch( pC->EncodingVideoFramerate ) 5772 { 5773 case M4ENCODER_k5_FPS: 5774 dFrameRate = 5.0; 5775 break; 5776 5777 case M4ENCODER_k7_5_FPS: 5778 dFrameRate = 7.5; 5779 break; 5780 5781 case M4ENCODER_k10_FPS: 5782 dFrameRate = 10.0; 5783 break; 5784 5785 case M4ENCODER_k12_5_FPS: 5786 dFrameRate = 12.5; 5787 break; 5788 5789 case M4ENCODER_k15_FPS: 5790 dFrameRate = 15.0; 5791 break; 5792 5793 case M4ENCODER_k20_FPS: /**< MPEG-4 only */ 5794 dFrameRate = 20.0; 5795 break; 5796 5797 case M4ENCODER_k25_FPS: /**< MPEG-4 only */ 5798 dFrameRate = 25.0; 5799 break; 5800 5801 case M4ENCODER_k30_FPS: 5802 dFrameRate = 30.0; 5803 break; 5804 5805 default: 5806 M4OSA_TRACE1_1( 5807 "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\ 5808 (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE", 5809 pC->EncodingVideoFramerate); 5810 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE; 5811 } 5812 5813 /** 5814 * Compute the number of milliseconds between two frames */ 5815 if( M4ENCODER_kH263 == EncParams.Format ) 5816 { 5817 pC->dCtsIncrement = 1001.0 / dFrameRate; 5818 } 5819 else /**< MPEG4 or H.264 */ 5820 { 5821 pC->dCtsIncrement = 1000.0 / dFrameRate; 5822 } 5823 } 5824 5825 /** 5826 * Create video encoder */ 5827 err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt, 5828 pC->pWriterDataFcts, \ 5829 M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \ 5830 pC->pCurrentVideoEncoderUserData); 5831 5832 /**< We put the MCS context in place of the VPP context */ 5833 if( M4NO_ERROR != err ) 5834 { 5835 M4OSA_TRACE1_1( 5836 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x", 5837 err); 5838 return err; 5839 } 5840 5841 pC->encoderState = M4MCS_kEncoderClosed; 5842 5843 if( M4OSA_TRUE == pC->bH264Trim ) 5844 //if((M4ENCODER_kNULL == pC->EncodingVideoFormat) 5845 // && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType)) 5846 { 5847 EncParams1.InputFormat = EncParams.InputFormat; 5848 //EncParams1.InputFrameWidth = EncParams.InputFrameWidth; 5849 //EncParams1.InputFrameHeight = EncParams.InputFrameHeight; 5850 EncParams1.FrameWidth = EncParams.FrameWidth; 5851 EncParams1.FrameHeight = EncParams.FrameHeight; 5852 EncParams1.Bitrate = EncParams.Bitrate; 5853 EncParams1.FrameRate = EncParams.FrameRate; 5854 EncParams1.Format = M4ENCODER_kH264; //EncParams.Format; 5855 5856 err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, 5857 &pC->WriterVideoAU, &EncParams1); 5858 } 5859 else 5860 { 5861 err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt, 5862 &pC->WriterVideoAU, &EncParams); 5863 } 5864 5865 if( M4NO_ERROR != err ) 5866 { 5867 M4OSA_TRACE1_1( 5868 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x", 5869 err); 5870 return err; 5871 } 5872 5873 pC->encoderState = M4MCS_kEncoderStopped; 5874 5875 if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart ) 5876 { 5877 err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt); 5878 5879 if( M4NO_ERROR != err ) 5880 { 5881 M4OSA_TRACE1_1( 5882 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x", 5883 err); 5884 return err; 5885 } 5886 } 5887 5888 pC->encoderState = M4MCS_kEncoderRunning; 5889 5890 /******************************/ 5891 /* Video resize management */ 5892 /******************************/ 5893 /** 5894 * Compare video input size and video output size to check if resize is needed */ 5895 if( ( (M4OSA_UInt32)EncParams.FrameWidth 5896 != pC->pReaderVideoStream->m_videoWidth) 5897 || ((M4OSA_UInt32)EncParams.FrameHeight 5898 != pC->pReaderVideoStream->m_videoHeight) ) 5899 { 5900 /** 5901 * Allocate the intermediate video plane that will receive the decoded image before 5902 resizing */ 5903 pC->pPreResizeFrame = 5904 (M4VIFI_ImagePlane *)M4OSA_malloc(3 * sizeof(M4VIFI_ImagePlane), 5905 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame"); 5906 5907 if( M4OSA_NULL == pC->pPreResizeFrame ) 5908 { 5909 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\ 5910 unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC"); 5911 return M4ERR_ALLOC; 5912 } 5913 5914 pC->pPreResizeFrame[0].pac_data = M4OSA_NULL; 5915 pC->pPreResizeFrame[1].pac_data = M4OSA_NULL; 5916 pC->pPreResizeFrame[2].pac_data = M4OSA_NULL; 5917 5918 /** 5919 * Allocate the Y plane */ 5920 pC->pPreResizeFrame[0].u_topleft = 0; 5921 pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream-> 5922 m_videoWidth; /**< input width */ 5923 pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream-> 5924 m_videoHeight; /**< input height */ 5925 pC->pPreResizeFrame[0].u_stride = pC-> 5926 pPreResizeFrame[0].u_width; /**< simple case: stride equals width */ 5927 5928 pC->pPreResizeFrame[0].pac_data = 5929 (M4VIFI_UInt8 *)M4OSA_malloc(pC->pPreResizeFrame[0].u_stride \ 5930 *pC->pPreResizeFrame[0].u_height, M4MCS, 5931 (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); 5932 5933 if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data ) 5934 { 5935 M4OSA_TRACE1_0( 5936 "M4MCS_intPrepareVideoEncoder():\ 5937 unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC"); 5938 return M4ERR_ALLOC; 5939 } 5940 5941 /** 5942 * Allocate the U plane */ 5943 pC->pPreResizeFrame[1].u_topleft = 0; 5944 pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width 5945 >> 1; /**< U width is half the Y width */ 5946 pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height 5947 >> 1; /**< U height is half the Y height */ 5948 pC->pPreResizeFrame[1].u_stride = pC-> 5949 pPreResizeFrame[1].u_width; /**< simple case: stride equals width */ 5950 5951 pC->pPreResizeFrame[1].pac_data = 5952 (M4VIFI_UInt8 *)M4OSA_malloc(pC->pPreResizeFrame[1].u_stride \ 5953 *pC->pPreResizeFrame[1].u_height, M4MCS, 5954 (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 5955 5956 if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data ) 5957 { 5958 M4OSA_TRACE1_0( 5959 "M4MCS_intPrepareVideoEncoder():\ 5960 unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC"); 5961 return M4ERR_ALLOC; 5962 } 5963 5964 /** 5965 * Allocate the V plane */ 5966 pC->pPreResizeFrame[2].u_topleft = 0; 5967 pC->pPreResizeFrame[2].u_width = pC-> 5968 pPreResizeFrame[1].u_width; /**< V width equals U width */ 5969 pC->pPreResizeFrame[2].u_height = pC-> 5970 pPreResizeFrame[1].u_height; /**< V height equals U height */ 5971 pC->pPreResizeFrame[2].u_stride = pC-> 5972 pPreResizeFrame[2].u_width; /**< simple case: stride equals width */ 5973 5974 pC->pPreResizeFrame[2].pac_data = 5975 (M4VIFI_UInt8 *)M4OSA_malloc(pC->pPreResizeFrame[2].u_stride \ 5976 *pC->pPreResizeFrame[2].u_height, M4MCS, 5977 (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 5978 5979 if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data ) 5980 { 5981 M4OSA_TRACE1_0( 5982 "M4MCS_intPrepareVideoEncoder():\ 5983 unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC"); 5984 return M4ERR_ALLOC; 5985 } 5986 } 5987 5988 /** 5989 * Return with no error */ 5990 M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR"); 5991 return M4NO_ERROR; 5992} 5993 5994/** 5995 ****************************************************************************** 5996 * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC); 5997 * @brief Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder. 5998 * @param pC (IN) MCS private context 5999 * @return M4NO_ERROR No error 6000 * @return Any error returned by an underlaying module 6001 ****************************************************************************** 6002 */ 6003static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC ) 6004{ 6005 M4OSA_ERR err; 6006 6007 SSRC_ReturnStatus_en 6008 ReturnStatus; /* Function return status */ 6009 LVM_INT16 NrSamplesMin = 6010 0; /* Minimal number of samples on the input or on the output */ 6011 LVM_INT32 ScratchSize; /* The size of the scratch memory */ 6012 LVM_INT16 6013 *pInputInScratch; /* Pointer to input in the scratch buffer */ 6014 LVM_INT16 6015 *pOutputInScratch; /* Pointer to the output in the scratch buffer */ 6016 SSRC_Params_t ssrcParams; /* Memory for init parameters */ 6017 6018#ifdef MCS_DUMP_PCM_TO_FILE 6019 6020 file_au_reader = fopen("mcs_ReaderOutput.raw", "wb"); 6021 file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb"); 6022 file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb"); 6023 6024#endif 6025 6026 if( pC->noaudio ) 6027 return M4NO_ERROR; 6028 6029 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 6030 { 6031 M4OSA_TRACE3_0( 6032 "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing."); 6033 return M4NO_ERROR; 6034 } 6035 6036 /* ________________________________ */ 6037 /*| |*/ 6038 /*| Create and "start" the decoder |*/ 6039 /*|________________________________|*/ 6040 6041 if( M4OSA_NULL == pC->m_pAudioDecoder ) 6042 { 6043 M4OSA_TRACE1_0( 6044 "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder."); 6045 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 6046 } 6047 6048 if( M4OSA_NULL == pC->pAudioDecCtxt ) 6049 { 6050 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt, 6051 pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData); 6052 6053 if( M4NO_ERROR != err ) 6054 { 6055 M4OSA_TRACE1_1( 6056 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 6057 err); 6058 return err; 6059 } 6060 } 6061 6062 if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) { 6063 /* AMR DECODER CONFIGURATION */ 6064 6065 /* nothing specific to do */ 6066 } 6067 else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) { 6068 /* EVRC DECODER CONFIGURATION */ 6069 6070 /* nothing specific to do */ 6071 } 6072 else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) { 6073 /* MP3 DECODER CONFIGURATION */ 6074 6075 /* nothing specific to do */ 6076 } 6077 else 6078 { 6079 /* AAC DECODER CONFIGURATION */ 6080 M4_AacDecoderConfig AacDecParam; 6081 6082 AacDecParam.m_AACDecoderProfile = AAC_kAAC; 6083 AacDecParam.m_DownSamplingMode = AAC_kDS_OFF; 6084 6085 if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB ) 6086 { 6087 AacDecParam.m_OutputMode = AAC_kMono; 6088 } 6089 else 6090 { 6091 /* For this version, we encode only in AAC */ 6092 if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) 6093 { 6094 AacDecParam.m_OutputMode = AAC_kMono; 6095 } 6096 else 6097 { 6098 AacDecParam.m_OutputMode = AAC_kStereo; 6099 } 6100 } 6101 6102 pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, 6103 M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); 6104 } 6105 6106 if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) 6107 { 6108 /* Not implemented in all decoders */ 6109 err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); 6110 6111 if( M4NO_ERROR != err ) 6112 { 6113 M4OSA_TRACE1_1( 6114 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x", 6115 err); 6116 return err; 6117 } 6118 } 6119 6120 /** 6121 * Allocate output buffer for the audio decoder */ 6122 pC->InputFileProperties.uiDecodedPcmSize = 6123 pC->pReaderAudioStream->m_byteFrameLength 6124 * pC->pReaderAudioStream->m_byteSampleSize 6125 * pC->pReaderAudioStream->m_nbChannels; 6126 6127 if( pC->InputFileProperties.uiDecodedPcmSize > 0 ) 6128 { 6129 pC->AudioDecBufferOut.m_bufferSize = 6130 pC->InputFileProperties.uiDecodedPcmSize; 6131 pC->AudioDecBufferOut.m_dataAddress = 6132 (M4OSA_MemAddr8)M4OSA_malloc(pC->AudioDecBufferOut.m_bufferSize \ 6133 *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize"); 6134 } 6135 6136 if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress ) 6137 { 6138 M4OSA_TRACE1_0( 6139 "M4MCS_intPrepareVideoDecoder():\ 6140 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC"); 6141 return M4ERR_ALLOC; 6142 } 6143 6144 /* _________________________ */ 6145 /*| |*/ 6146 /*| Set the SSRC parameters |*/ 6147 /*|_________________________|*/ 6148 6149 switch( pC->pReaderAudioStream->m_samplingFrequency ) 6150 { 6151 case 8000: 6152 ssrcParams.SSRC_Fs_In = LVM_FS_8000; 6153 break; 6154 6155 case 11025: 6156 ssrcParams.SSRC_Fs_In = LVM_FS_11025; 6157 break; 6158 6159 case 12000: 6160 ssrcParams.SSRC_Fs_In = LVM_FS_12000; 6161 break; 6162 6163 case 16000: 6164 ssrcParams.SSRC_Fs_In = LVM_FS_16000; 6165 break; 6166 6167 case 22050: 6168 ssrcParams.SSRC_Fs_In = LVM_FS_22050; 6169 break; 6170 6171 case 24000: 6172 ssrcParams.SSRC_Fs_In = LVM_FS_24000; 6173 break; 6174 6175 case 32000: 6176 ssrcParams.SSRC_Fs_In = LVM_FS_32000; 6177 break; 6178 6179 case 44100: 6180 ssrcParams.SSRC_Fs_In = LVM_FS_44100; 6181 break; 6182 6183 case 48000: 6184 ssrcParams.SSRC_Fs_In = LVM_FS_48000; 6185 break; 6186 6187 default: 6188 M4OSA_TRACE1_1( 6189 "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\ 6190 returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", 6191 pC->pReaderAudioStream->m_samplingFrequency); 6192 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; 6193 } 6194 6195 if( 1 == pC->pReaderAudioStream->m_nbChannels ) 6196 { 6197 ssrcParams.SSRC_NrOfChannels = LVM_MONO; 6198 } 6199 else 6200 { 6201 ssrcParams.SSRC_NrOfChannels = LVM_STEREO; 6202 } 6203 6204 /*FlB 26.02.2009: add mp3 as output format*/ 6205 if( pC->AudioEncParams.Format == M4ENCODER_kAAC 6206 || pC->AudioEncParams.Format == M4ENCODER_kMP3 ) 6207 { 6208 switch( pC->AudioEncParams.Frequency ) 6209 { 6210 case M4ENCODER_k8000Hz: 6211 ssrcParams.SSRC_Fs_Out = LVM_FS_8000; 6212 break; 6213 6214 case M4ENCODER_k11025Hz: 6215 ssrcParams.SSRC_Fs_Out = LVM_FS_11025; 6216 break; 6217 6218 case M4ENCODER_k12000Hz: 6219 ssrcParams.SSRC_Fs_Out = LVM_FS_12000; 6220 break; 6221 6222 case M4ENCODER_k16000Hz: 6223 ssrcParams.SSRC_Fs_Out = LVM_FS_16000; 6224 break; 6225 6226 case M4ENCODER_k22050Hz: 6227 ssrcParams.SSRC_Fs_Out = LVM_FS_22050; 6228 break; 6229 6230 case M4ENCODER_k24000Hz: 6231 ssrcParams.SSRC_Fs_Out = LVM_FS_24000; 6232 break; 6233 6234 case M4ENCODER_k32000Hz: 6235 ssrcParams.SSRC_Fs_Out = LVM_FS_32000; 6236 break; 6237 6238 case M4ENCODER_k44100Hz: 6239 ssrcParams.SSRC_Fs_Out = LVM_FS_44100; 6240 break; 6241 6242 case M4ENCODER_k48000Hz: 6243 ssrcParams.SSRC_Fs_Out = LVM_FS_48000; 6244 break; 6245 6246 default: 6247 M4OSA_TRACE1_1( 6248 "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \ 6249 (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY", 6250 pC->AudioEncParams.Frequency); 6251 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY; 6252 break; 6253 } 6254 } 6255 else 6256 { 6257 ssrcParams.SSRC_Fs_Out = LVM_FS_8000; 6258 } 6259 6260 6261 6262 ReturnStatus = 0; 6263 6264 switch( ssrcParams.SSRC_Fs_In ) 6265 { 6266 case LVM_FS_8000: 6267 ssrcParams.NrSamplesIn = 320; 6268 break; 6269 6270 case LVM_FS_11025: 6271 ssrcParams.NrSamplesIn = 441; 6272 break; 6273 6274 case LVM_FS_12000: 6275 ssrcParams.NrSamplesIn = 480; 6276 break; 6277 6278 case LVM_FS_16000: 6279 ssrcParams.NrSamplesIn = 640; 6280 break; 6281 6282 case LVM_FS_22050: 6283 ssrcParams.NrSamplesIn = 882; 6284 break; 6285 6286 case LVM_FS_24000: 6287 ssrcParams.NrSamplesIn = 960; 6288 break; 6289 6290 case LVM_FS_32000: 6291 ssrcParams.NrSamplesIn = 1280; 6292 break; 6293 6294 case LVM_FS_44100: 6295 ssrcParams.NrSamplesIn = 1764; 6296 break; 6297 6298 case LVM_FS_48000: 6299 ssrcParams.NrSamplesIn = 1920; 6300 break; 6301 6302 default: 6303 ReturnStatus = -1; 6304 break; 6305 } 6306 6307 switch( ssrcParams.SSRC_Fs_Out ) 6308 { 6309 case LVM_FS_8000: 6310 ssrcParams.NrSamplesOut = 320; 6311 break; 6312 6313 case LVM_FS_11025: 6314 ssrcParams.NrSamplesOut = 441; 6315 break; 6316 6317 case LVM_FS_12000: 6318 ssrcParams.NrSamplesOut = 480; 6319 break; 6320 6321 case LVM_FS_16000: 6322 ssrcParams.NrSamplesOut = 640; 6323 break; 6324 6325 case LVM_FS_22050: 6326 ssrcParams.NrSamplesOut = 882; 6327 break; 6328 6329 case LVM_FS_24000: 6330 ssrcParams.NrSamplesOut = 960; 6331 break; 6332 6333 case LVM_FS_32000: 6334 ssrcParams.NrSamplesOut = 1280; 6335 break; 6336 6337 case LVM_FS_44100: 6338 ssrcParams.NrSamplesOut = 1764; 6339 break; 6340 6341 case LVM_FS_48000: 6342 ssrcParams.NrSamplesOut = 1920; 6343 break; 6344 6345 default: 6346 ReturnStatus = -1; 6347 break; 6348 } 6349 6350 6351 6352 if( ReturnStatus != SSRC_OK ) 6353 { 6354 M4OSA_TRACE1_1( 6355 "M4MCS_intPrepareAudioProcessing:\ 6356 Error code %d returned by the SSRC_GetNrSamples function", 6357 ReturnStatus); 6358 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 6359 } 6360 6361 NrSamplesMin = 6362 (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut) 6363 ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn); 6364 6365 while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE ) 6366 { /* Don't take blocks smaller that the minimal block size */ 6367 ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1); 6368 ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1); 6369 NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1); 6370 } 6371 6372 6373 pC->iSsrcNbSamplIn = (LVM_INT16)( 6374 ssrcParams. 6375 NrSamplesIn); /* multiplication by NrOfChannels is done below */ 6376 pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut); 6377 6378 /** 6379 * Allocate buffer for the input of the SSRC */ 6380 pC->pSsrcBufferIn = 6381 (M4OSA_MemAddr8)M4OSA_malloc(pC->iSsrcNbSamplIn * sizeof(short) \ 6382 *pC->pReaderAudioStream->m_nbChannels, M4MCS, 6383 (M4OSA_Char *)"pSsrcBufferIn"); 6384 6385 if( M4OSA_NULL == pC->pSsrcBufferIn ) 6386 { 6387 M4OSA_TRACE1_0( 6388 "M4MCS_intPrepareVideoDecoder():\ 6389 unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC"); 6390 return M4ERR_ALLOC; 6391 } 6392 pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn; 6393 6394 /** 6395 * Allocate buffer for the output of the SSRC */ 6396 pC->pSsrcBufferOut = 6397 (M4OSA_MemAddr8)M4OSA_malloc(pC->iSsrcNbSamplOut * sizeof(short) \ 6398 *pC->pReaderAudioStream->m_nbChannels, M4MCS, 6399 (M4OSA_Char *)"pSsrcBufferOut"); 6400 6401 if( M4OSA_NULL == pC->pSsrcBufferOut ) 6402 { 6403 M4OSA_TRACE1_0( 6404 "M4MCS_intPrepareVideoDecoder():\ 6405 unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC"); 6406 return M4ERR_ALLOC; 6407 } 6408 6409 6410 pC->pLVAudioResampler = (M4OSA_Int32)LVAudioResamplerCreate( 6411 16, /*gInputParams.lvBTChannelCount*/ 6412 /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiNbChannels*/ 6413 (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/, 6414 /* gInputParams.lvOutSampleRate*//*pSettings->outputASF*/ 6415 pC->AudioEncParams.Frequency/*ssrcParams.SSRC_Fs_Out*/, 1); 6416 LVAudiosetSampleRate((M4OSA_Int32)pC->pLVAudioResampler, 6417 /*gInputParams.lvInSampleRate*/ 6418 /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/ 6419 pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/); 6420 6421 LVAudiosetVolume((M4OSA_Int32)pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */), 6422 (M4OSA_Int16)(0x1000/*0x7fff*/)); 6423 6424 6425 /* ________________________ */ 6426 /*| |*/ 6427 /*| Init the audio encoder |*/ 6428 /*|________________________|*/ 6429 6430 /* Initialise the audio encoder */ 6431 6432 err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt, 6433 pC->pCurrentAudioEncoderUserData); 6434 6435 if( M4NO_ERROR != err ) 6436 { 6437 M4OSA_TRACE1_1( 6438 "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x", 6439 err); 6440 return err; 6441 } 6442 6443 /* Open the audio encoder */ 6444 err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt, 6445 &pC->AudioEncParams, &pC->pAudioEncDSI, 6446 M4OSA_NULL /* no grabbing */); 6447 6448 if( M4NO_ERROR != err ) 6449 { 6450 M4OSA_TRACE1_1( 6451 "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x", 6452 err); 6453 return err; 6454 } 6455 6456 /* Allocate the input buffer for the audio encoder */ 6457 switch( pC->AudioEncParams.Format ) 6458 { 6459 case M4ENCODER_kAMRNB: 6460 pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES; 6461 break; 6462 6463 case M4ENCODER_kAAC: 6464 pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES; 6465 break; 6466 6467 /*FlB 26.02.2009: add mp3 as output format*/ 6468 case M4ENCODER_kMP3: 6469 pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES; 6470 break; 6471 6472 default: 6473 break; 6474 } 6475 6476 if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum ) 6477 pC->audioEncoderGranularity *= sizeof(short); 6478 else 6479 pC->audioEncoderGranularity *= sizeof(short) * 2; 6480 6481 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 6482 pC->pAudioEncoderBuffer = 6483 (M4OSA_MemAddr8)M4OSA_malloc(pC->audioEncoderGranularity, M4MCS, 6484 (M4OSA_Char *)"pC->pAudioEncoderBuffer"); 6485 6486 /** 6487 * Return with no error */ 6488 M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR"); 6489 return M4NO_ERROR; 6490} 6491 6492/** 6493 ****************************************************************************** 6494 * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC); 6495 * @brief Prepare the writer. 6496 * @param pC (IN) MCS private context 6497 * @return M4NO_ERROR No error 6498 * @return Any error returned by an underlaying module 6499 ****************************************************************************** 6500 */ 6501static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC ) 6502{ 6503 M4OSA_ERR err; 6504 M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */ 6505 M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */ 6506 M4SYS_StreamIDValue optionValue; /**< For the setoption calls */ 6507 M4OSA_UInt32 TargetedFileSize; 6508 M4OSA_Bool bMULPPSSPS = M4OSA_FALSE; 6509 6510 /** 6511 * Init the writer */ 6512 err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile, 6513 pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr); 6514 6515 if( M4NO_ERROR != err ) 6516 { 6517 M4OSA_TRACE1_1( 6518 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x", 6519 err); 6520 return err; 6521 } 6522 6523 /** 6524 * Link to the writer context in the writer interface */ 6525 pC->pWriterDataFcts->pWriterContext = pC->pWriterContext; 6526 6527 /** 6528 * Set the product description string in the written file */ 6529 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6530 M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS "); 6531 6532 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6533 != err) ) /* this option may not be implemented by some writers */ 6534 { 6535 M4OSA_TRACE1_1( 6536 "M4MCS_intPrepareWriter:\ 6537 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x", 6538 err); 6539 return err; 6540 } 6541 6542 /** 6543 * Set the product version in the written file */ 6544 uiVersion = 6545 M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 6546 + M4VIDEOEDITING_VERSION_REVISION; 6547 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6548 M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); 6549 6550 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6551 != err) ) /* this option may not be implemented by some writers */ 6552 { 6553 M4OSA_TRACE1_1( 6554 "M4MCS_intPrepareWriter: \ 6555 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x", 6556 err); 6557 return err; 6558 } 6559 6560 /** 6561 * In case of EMP, we have to explicitely give an emp ftyp to the writer */ 6562 if( M4OSA_TRUE == pC->bActivateEmp ) 6563 { 6564 M4VIDEOEDITING_FtypBox ftyp; 6565 6566 ftyp.major_brand = M4VIDEOEDITING_BRAND_3GP4; 6567 ftyp.minor_version = M4VIDEOEDITING_BRAND_0000; 6568 ftyp.nbCompatibleBrands = 2; 6569 ftyp.compatible_brands[0] = M4VIDEOEDITING_BRAND_3GP4; 6570 ftyp.compatible_brands[1] = M4VIDEOEDITING_BRAND_EMP; 6571 6572 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6573 (M4OSA_UInt32)M4WRITER_kSetFtypBox, (M4OSA_DataOption) &ftyp); 6574 6575 if( M4NO_ERROR != err ) 6576 { 6577 M4OSA_TRACE1_1( 6578 "M4MCS_intPrepareWriter:\ 6579 pWriterGlobalFcts->pFctSetOption(M4WRITER_kSetFtypBox) returns 0x%x!", 6580 err); 6581 return err; 6582 } 6583 } 6584 6585 /** 6586 * If there is a video input, allocate and fill the video stream structures for the writer */ 6587 if( pC->novideo == M4OSA_FALSE ) 6588 { 6589 /** 6590 * Fill Video properties structure for the AddStream method */ 6591 pC->WriterVideoStreamInfo.height = pC->EncodingHeight; 6592 pC->WriterVideoStreamInfo.width = pC->EncodingWidth; 6593 pC->WriterVideoStreamInfo.fps = 6594 0; /**< Not used by the shell/core writer */ 6595 pC->WriterVideoStreamInfo.Header.pBuf = 6596 M4OSA_NULL; /**< Will be updated later */ 6597 pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */ 6598 6599 /** 6600 * Fill Video stream description structure for the AddStream method */ 6601 switch( pC->EncodingVideoFormat ) 6602 { 6603 case M4ENCODER_kMPEG4: 6604 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; 6605 break; 6606 6607 case M4ENCODER_kH263: 6608 pC->WriterVideoStream.streamType = M4SYS_kH263; 6609 break; 6610 6611 case M4ENCODER_kH264: 6612 pC->WriterVideoStream.streamType = M4SYS_kH264; 6613 break; 6614 6615 case M4ENCODER_kNULL: 6616 switch( pC->InputFileProperties.VideoStreamType ) 6617 { 6618 case M4VIDEOEDITING_kMPEG4: 6619 case M4VIDEOEDITING_kMPEG4_EMP: /* RC */ 6620 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4; 6621 break; 6622 6623 case M4VIDEOEDITING_kH263: 6624 pC->WriterVideoStream.streamType = M4SYS_kH263; 6625 break; 6626 6627 case M4VIDEOEDITING_kH264: 6628 pC->WriterVideoStream.streamType = M4SYS_kH264; 6629 break; 6630 6631 default: 6632 M4OSA_TRACE1_1( 6633 "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \ 6634 unknown format (0x%x),\ 6635 returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", 6636 pC->EncodingVideoFormat); 6637 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; 6638 } 6639 break; 6640 6641 default: /**< It should never happen, already tested */ 6642 M4OSA_TRACE1_1( 6643 "M4MCS_intPrepareWriter: unknown format (0x%x),\ 6644 returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT", 6645 pC->EncodingVideoFormat); 6646 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT; 6647 } 6648 6649 /** 6650 * Video bitrate value will be the real value */ 6651 pC->WriterVideoStream.averageBitrate = 6652 (M4OSA_Int32)pC->uiEncVideoBitrate; 6653 pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate; 6654 6655 /** 6656 * most other parameters are "dummy" */ 6657 pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 6658 pC->WriterVideoStream.timeScale = 6659 0; /**< Not used by the shell/core writer */ 6660 pC->WriterVideoStream.profileLevel = 6661 0; /**< Not used by the shell/core writer */ 6662 pC->WriterVideoStream.duration = 6663 0; /**< Not used by the shell/core writer */ 6664 pC->WriterVideoStream.decoderSpecificInfoSize = 6665 sizeof(M4WRITER_StreamVideoInfos); 6666 pC->WriterVideoStream.decoderSpecificInfo = 6667 (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo); 6668 6669 /** 6670 * Update Encoder Header properties for Video stream if needed */ 6671 if( M4ENCODER_kH263 == pC->EncodingVideoFormat ) 6672 { 6673 /** 6674 * Creates the H263 DSI */ 6675 pC->WriterVideoStreamInfo.Header.Size = 6676 7; /**< H263 output DSI is always 7 bytes */ 6677 pDSI = (M4OSA_MemAddr8)M4OSA_malloc(7, M4MCS, (M4OSA_Char 6678 *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)"); 6679 6680 if( M4OSA_NULL == pDSI ) 6681 { 6682 M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\ 6683 returning M4ERR_ALLOC"); 6684 return M4ERR_ALLOC; 6685 } 6686 6687 /** 6688 * Vendor is NXP Software: N, X, P, S. */ 6689 pDSI[0] = 'N'; 6690 pDSI[1] = 'X'; 6691 pDSI[2] = 'P'; 6692 pDSI[3] = 'S'; 6693 6694 /** 6695 * Decoder version is 0 */ 6696 pDSI[4] = 0; 6697 6698 /** 6699 * Level is the sixth byte of the DSI. */ 6700 switch( pC->EncodingWidth ) 6701 { 6702 case M4ENCODER_SQCIF_Width: 6703 case M4ENCODER_QCIF_Width: 6704 if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS) 6705 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6706 { 6707 pDSI[5] = 10; 6708 } 6709 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6710 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6711 { 6712 pDSI[5] = 45; 6713 } 6714 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6715 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6716 { 6717 pDSI[5] = 20; 6718 } 6719 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) 6720 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6721 { 6722 pDSI[5] = 30; 6723 } 6724 else if( ( pC->uiEncVideoBitrate 6725 <= M4ENCODER_k800_KBPS/*2048*/) 6726 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6727 { 6728 pDSI[5] = 40; 6729 } 6730 break; 6731 6732 case M4ENCODER_CIF_Width: 6733 if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS) 6734 && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) ) 6735 { 6736 pDSI[5] = 20; 6737 } 6738 else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS) 6739 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6740 { 6741 pDSI[5] = 30; 6742 } 6743 else if( ( pC->uiEncVideoBitrate 6744 <= M4ENCODER_k800_KBPS/*2048*/) 6745 && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) ) 6746 { 6747 pDSI[5] = 40; 6748 } 6749 break; 6750 6751 default: 6752 break; 6753 } 6754 6755 /** 6756 * Profile is the seventh byte of the DSI. */ 6757 pDSI[6] = 0; 6758 6759 pC->WriterVideoStreamInfo.Header.pBuf = pDSI; 6760 } 6761 else if( M4ENCODER_kNULL == pC->EncodingVideoFormat ) 6762 { 6763#ifdef TIMESCALE_BUG 6764 /* if we are in "timescale mode", we need to know on how many bits the v 6765 op_time_increment is coded and to change the DSI */ 6766 6767 if( pC->uiVideoTimescale == 0 ) 6768 { 6769 /* If we copy the stream from the input, we copy its DSI */ 6770 pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream-> 6771 m_basicProperties.m_decoderSpecificInfoSize; 6772 pC->WriterVideoStreamInfo.Header.pBuf = 6773 (M4OSA_MemAddr8)pC->pReaderVideoStream-> 6774 m_basicProperties.m_pDecoderSpecificInfo; 6775 } 6776 else 6777 { 6778 /* Allocate a new DSI */ 6779 pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream-> 6780 m_basicProperties.m_decoderSpecificInfoSize; 6781 pC->WriterVideoStreamInfo.Header.pBuf = 6782 (M4OSA_Void 6783 *)M4OSA_malloc(pC->WriterVideoStreamInfo.Header.Size, 6784 M4MCS, 6785 (M4OSA_Char 6786 *) 6787 "New decoder specific info for timescale modification"); 6788 6789 if( pC->WriterVideoStreamInfo.Header.pBuf == M4OSA_NULL ) 6790 { 6791 M4OSA_TRACE1_0("M4MCS_intPrepareWriter: Allocation error\ 6792 pC->WriterVideoStreamInfo.Header.pBuf"); 6793 return M4ERR_ALLOC; 6794 } 6795 6796 /* Copy Reading DSI to new DSI */ 6797 M4OSA_memcpy(pC->WriterVideoStreamInfo.Header.pBuf, 6798 pC->pReaderVideoStream-> 6799 m_basicProperties.m_pDecoderSpecificInfo, 6800 pC->WriterVideoStreamInfo.Header.Size); 6801 6802 /* Call a function to change DSI and to get the nb of bits on which the 6803 vop_time_increment is coded */ 6804 err = M4MCS_intParseVideoDSI(pC); 6805 } 6806 6807#else 6808 /* If we copy the stream from the input, we copy its DSI */ 6809 6810 pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream-> 6811 m_basicProperties.m_decoderSpecificInfoSize; 6812 pC->WriterVideoStreamInfo.Header.pBuf = 6813 (M4OSA_MemAddr8)pC->pReaderVideoStream-> 6814 m_basicProperties.m_pDecoderSpecificInfo; 6815 6816#endif 6817 6818 } 6819 /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */ 6820 6821 /*+CRLV6775 - H.264 Trimming */ 6822 if( pC->bH264Trim == M4OSA_TRUE ) 6823 { 6824 bMULPPSSPS = M4OSA_TRUE; 6825 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6826 (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS, 6827 (M4OSA_DataOption) &bMULPPSSPS); 6828 6829 if( ( M4NO_ERROR != err) 6830 && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6831 != err) ) /* this option may not be implemented by some writers */ 6832 { 6833 M4OSA_TRACE1_1( 6834 "M4MCS_intPrepareWriter:\ 6835 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x", 6836 err); 6837 return err; 6838 } 6839 } 6840 /*-CRLV6775 - H.264 Trimming */ 6841 /** 6842 * Add the video stream */ 6843 err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, 6844 &pC->WriterVideoStream); 6845 6846 if( M4NO_ERROR != err ) 6847 { 6848 M4OSA_TRACE1_1( 6849 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", 6850 err); 6851 return err; 6852 } 6853 6854 /** 6855 * Update AU properties for video stream */ 6856 pC->WriterVideoAU.stream = &(pC->WriterVideoStream); 6857 pC->WriterVideoAU.dataAddress = M4OSA_NULL; 6858 pC->WriterVideoAU.size = 0; 6859 pC->WriterVideoAU.CTS = 0; /** Reset time */ 6860 pC->WriterVideoAU.DTS = 0; 6861 pC->WriterVideoAU.attribute = AU_RAP; 6862 pC->WriterVideoAU.nbFrag = 0; /** No fragment */ 6863 pC->WriterVideoAU.frag = M4OSA_NULL; 6864 6865 /** 6866 * Set the writer max video AU size */ 6867 optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID; 6868 optionValue.value = pC->uiVideoMaxAuSize; 6869 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6870 (M4OSA_UInt32)M4WRITER_kMaxAUSize, 6871 (M4OSA_DataOption) &optionValue); 6872 6873 if( M4NO_ERROR != err ) 6874 { 6875 M4OSA_TRACE1_1( 6876 "M4MCS_intPrepareWriter: \ 6877 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 6878 err); 6879 return err; 6880 } 6881 6882 /** 6883 * Set the writer max video chunk size */ 6884 optionValue.value = pC->uiVideoMaxChunckSize; 6885 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 6886 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 6887 (M4OSA_DataOption) &optionValue); 6888 6889 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 6890 != err) ) /* this option may not be implemented by some writers */ 6891 { 6892 M4OSA_TRACE1_1( 6893 "M4MCS_intPrepareWriter:\ 6894 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 6895 err); 6896 return err; 6897 } 6898 } 6899 6900 /** 6901 * If there is an audio input, allocate and fill the audio stream structures for the writer */ 6902 if( pC->noaudio == M4OSA_FALSE ) 6903 { 6904 M4WRITER_StreamAudioInfos streamAudioInfo; 6905 6906 streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ 6907 streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ 6908 streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ 6909 6910 pC->WriterAudioStream.averageBitrate = 6911 0; /**< It is not used by the shell, the DSI is taken into account instead */ 6912 pC->WriterAudioStream.maxBitrate = 6913 0; /**< Not used by the shell/core writer */ 6914 6915 /** 6916 * Fill Audio stream description structure for the AddStream method */ 6917 switch( pC->AudioEncParams.Format ) 6918 { 6919 case M4ENCODER_kAMRNB: 6920 pC->WriterAudioStream.streamType = M4SYS_kAMR; 6921 break; 6922 6923 case M4ENCODER_kAAC: 6924 pC->WriterAudioStream.streamType = M4SYS_kAAC; 6925 pC->WriterAudioStream.averageBitrate = 6926 pC->AudioEncParams.Bitrate; 6927 pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate; 6928 break; 6929 6930 /*FlB 26.02.2009: add mp3 as output format*/ 6931 case M4ENCODER_kMP3: 6932 pC->WriterAudioStream.streamType = M4SYS_kMP3; 6933 break; 6934 6935 case M4ENCODER_kAudioNULL: 6936 switch( pC->InputFileProperties.AudioStreamType ) 6937 { 6938 case M4VIDEOEDITING_kAMR_NB: 6939 pC->WriterAudioStream.streamType = M4SYS_kAMR; 6940 break; 6941 /*FlB 26.02.2009: add mp3 as output format*/ 6942 case M4VIDEOEDITING_kMP3: 6943 pC->WriterAudioStream.streamType = M4SYS_kMP3; 6944 break; 6945 6946 case M4VIDEOEDITING_kAAC: 6947 case M4VIDEOEDITING_kAACplus: 6948 case M4VIDEOEDITING_keAACplus: 6949 pC->WriterAudioStream.streamType = M4SYS_kAAC; 6950 pC->WriterAudioStream.averageBitrate = 6951 pC->AudioEncParams.Bitrate; 6952 pC->WriterAudioStream.maxBitrate = 6953 pC->AudioEncParams.Bitrate; 6954 break; 6955 6956 case M4VIDEOEDITING_kEVRC: 6957 pC->WriterAudioStream.streamType = M4SYS_kEVRC; 6958 break; 6959 6960 case M4VIDEOEDITING_kNoneAudio: 6961 case M4VIDEOEDITING_kPCM: 6962 case M4VIDEOEDITING_kNullAudio: 6963 case M4VIDEOEDITING_kUnsupportedAudio: 6964 break; 6965 } 6966 break; 6967 6968 default: /**< It should never happen, already tested */ 6969 M4OSA_TRACE1_1( 6970 "M4MCS_intPrepareWriter: \ 6971 unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 6972 pC->AudioEncParams.Format); 6973 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 6974 } 6975 6976 /** 6977 * MCS produces only AMR-NB output */ 6978 pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; 6979 pC->WriterAudioStream.duration = 6980 0; /**< Not used by the shell/core writer */ 6981 pC->WriterAudioStream.profileLevel = 6982 0; /**< Not used by the shell/core writer */ 6983 pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency; 6984 6985 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 6986 { 6987 /* If we copy the stream from the input, we copy its DSI */ 6988 streamAudioInfo.Header.Size = pC->pReaderAudioStream-> 6989 m_basicProperties.m_decoderSpecificInfoSize; 6990 streamAudioInfo.Header.pBuf = 6991 (M4OSA_MemAddr8)pC->pReaderAudioStream-> 6992 m_basicProperties.m_pDecoderSpecificInfo; 6993 } 6994 else 6995 { 6996 if( pC->pAudioEncDSI.pInfo != M4OSA_NULL ) 6997 { 6998 /* Use the DSI given by the encoder open() */ 6999 streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize; 7000 streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo; 7001 } 7002 else 7003 { 7004 /* Writer will put a default Philips DSI */ 7005 streamAudioInfo.Header.Size = 0; 7006 streamAudioInfo.Header.pBuf = M4OSA_NULL; 7007 } 7008 } 7009 7010 /** 7011 * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos 7012 in the DSI pointer... */ 7013 pC->WriterAudioStream.decoderSpecificInfo = 7014 (M4OSA_MemAddr32) &streamAudioInfo; 7015 7016 /** 7017 * Add the audio stream to the writer */ 7018 err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext, 7019 &pC->WriterAudioStream); 7020 7021 if( M4NO_ERROR != err ) 7022 { 7023 M4OSA_TRACE1_1( 7024 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x", 7025 err); 7026 return err; 7027 } 7028 7029 /** 7030 * Link the AU and the stream */ 7031 pC->WriterAudioAU.stream = &(pC->WriterAudioStream); 7032 pC->WriterAudioAU.dataAddress = M4OSA_NULL; 7033 pC->WriterAudioAU.size = 0; 7034 pC->WriterAudioAU.CTS = 0; /** Reset time */ 7035 pC->WriterAudioAU.DTS = 0; 7036 pC->WriterAudioAU.attribute = 0; 7037 pC->WriterAudioAU.nbFrag = 0; /** No fragment */ 7038 pC->WriterAudioAU.frag = M4OSA_NULL; 7039 7040 /** 7041 * Set the writer audio max AU size */ 7042 /* As max bitrate is now 320kbps instead of 128kbps, max AU 7043 * size has to be increased adapt the max AU size according to the stream type and the 7044 * channels numbers*/ 7045 /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite) 7046 */ 7047 //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE; 7048 switch( pC->WriterAudioStream.streamType ) 7049 { 7050 case M4SYS_kAMR: 7051 pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES 7052 * (( pC->InputFileProperties.uiNbChannels 7053 * sizeof(short)) + 3); 7054 break; 7055 7056 case M4SYS_kMP3: 7057 pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES 7058 * (( pC->InputFileProperties.uiNbChannels 7059 * sizeof(short)) + 3); 7060 break; 7061 7062 case M4SYS_kAAC: 7063 pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES 7064 * (( pC->InputFileProperties.uiNbChannels 7065 * sizeof(short)) + 3); 7066 break; 7067 /*case M4SYS_kEVRC: 7068 pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES* 7069 ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3); 7070 break;*/ 7071 default: /**< It should never happen, already tested */ 7072 M4OSA_TRACE1_1( 7073 "M4MCS_intPrepareWriter: unknown format (0x%x),\ 7074 returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT", 7075 pC->WriterAudioStream.streamType); 7076 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT; 7077 } 7078 7079 optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID; 7080 optionValue.value = pC->uiAudioMaxAuSize; 7081 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7082 (M4OSA_UInt32)M4WRITER_kMaxAUSize, 7083 (M4OSA_DataOption) &optionValue); 7084 7085 if( M4NO_ERROR != err ) 7086 { 7087 M4OSA_TRACE1_1( 7088 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ 7089 M4WRITER_kMaxAUSize) returns 0x%x", 7090 err); 7091 return err; 7092 } 7093 7094 optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE; 7095 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7096 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 7097 (M4OSA_DataOption) &optionValue); 7098 7099 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 7100 != err) ) /* this option may not be implemented by some writers */ 7101 { 7102 M4OSA_TRACE1_1( 7103 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\ 7104 M4WRITER_kMaxChunckSize) returns 0x%x", 7105 err); 7106 return err; 7107 } 7108 } 7109 7110 /* 7111 * Set the limitation size of the writer */ 7112 TargetedFileSize = pC->uiMaxFileSize; 7113 /* add 1 kB margin */ 7114 if( TargetedFileSize > 8192 ) 7115 TargetedFileSize -= 1024; 7116 7117 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext, 7118 (M4OSA_UInt32)M4WRITER_kMaxFileSize, 7119 (M4OSA_DataOption) &TargetedFileSize); 7120 7121 if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 7122 != err) ) /* this option may not be implemented by some writers */ 7123 { 7124 M4OSA_TRACE1_1( 7125 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\ 7126 (M4WRITER_kMaxFileSize) returns 0x%x!", 7127 err); 7128 return err; 7129 } 7130 7131 /** 7132 * Close the stream registering in order to be ready to write data */ 7133 err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext); 7134 7135 if( M4NO_ERROR != err ) 7136 { 7137 M4OSA_TRACE1_1( 7138 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x", 7139 err); 7140 return err; 7141 } 7142 7143 /** 7144 * Return with no error */ 7145 M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR"); 7146 return M4NO_ERROR; 7147} 7148 7149/** 7150 ****************************************************************************** 7151 * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC); 7152 * @brief DO the audio begin cut. 7153 * @param pC (IN) MCS private context 7154 * @return M4NO_ERROR No error 7155 * @return Any error returned by an underlaying module 7156 ****************************************************************************** 7157 */ 7158static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC ) 7159{ 7160 M4OSA_ERR err; 7161 M4OSA_Int32 iCts; 7162 M4OSA_UInt32 uiFrameSize; 7163 7164 if( pC->noaudio ) 7165 return M4NO_ERROR; 7166 7167 /** 7168 * Check if an audio begin cut is needed */ 7169 if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) ) 7170 { 7171 /** 7172 * Return with no error */ 7173 M4OSA_TRACE3_0( 7174 "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)"); 7175 return M4NO_ERROR; 7176 } 7177 7178 /** 7179 * Jump at the begin cut time */ 7180 iCts = pC->uiBeginCutTime; 7181 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 7182 (M4_StreamHandler *)pC->pReaderAudioStream, &iCts); 7183 7184 if( M4NO_ERROR != err ) 7185 { 7186 M4OSA_TRACE1_1( 7187 "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!", 7188 err); 7189 return err; 7190 } 7191 7192 /** 7193 * Remember audio begin cut offset */ 7194 pC->iAudioCtsOffset = iCts; 7195 7196 /** 7197 * AMR-NB & EVRC: there may be many frames per AU. 7198 * In that case we need to slice the first AU to keep the 20 ms cut precision */ 7199 if( ( M4DA_StreamTypeAudioAmrNarrowBand 7200 == pC->pReaderAudioStream->m_basicProperties.m_streamType) 7201 || (M4DA_StreamTypeAudioEvrc 7202 == pC->pReaderAudioStream->m_basicProperties.m_streamType) ) 7203 { 7204 /** 7205 * If the next frame CTS is lower than the begin cut time, 7206 * we must read the AU and parse its frames to reach the 7207 * nearest to the begin cut */ 7208 if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime ) 7209 { 7210 /** 7211 * Read the first audio AU after the jump */ 7212 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7213 (M4_StreamHandler *)pC->pReaderAudioStream, 7214 &pC->ReaderAudioAU); 7215 7216 if( M4WAR_NO_MORE_AU == err ) 7217 { 7218 M4OSA_TRACE1_0( 7219 "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\ 7220 returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR"); 7221 return 7222 M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ 7223 } 7224 else if( M4NO_ERROR != err ) 7225 { 7226 M4OSA_TRACE1_1( 7227 "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\ 7228 returns 0x%x", 7229 err); 7230 return err; 7231 } 7232 7233 /** 7234 * While the next AU has a lower CTS than the begin cut time, we advance to 7235 the next frame */ 7236 while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime ) 7237 { 7238 /** 7239 * Get the size of the frame */ 7240 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) 7241 { 7242 case M4DA_StreamTypeAudioAmrNarrowBand: 7243 uiFrameSize = M4MCS_intGetFrameSize_AMRNB( 7244 pC->ReaderAudioAU.m_dataAddress); 7245 break; 7246 7247 case M4DA_StreamTypeAudioEvrc: 7248 uiFrameSize = M4MCS_intGetFrameSize_EVRC( 7249 pC->ReaderAudioAU.m_dataAddress); 7250 break; 7251 7252 default: 7253 uiFrameSize = 0; 7254 break; 7255 } 7256 7257 if( 0 == uiFrameSize ) 7258 { 7259 /** 7260 * Corrupted frame! We get out of this mess! 7261 * We don't want to crash here... */ 7262 M4OSA_TRACE1_0( 7263 "M4MCS_intPrepareAudioBeginCut(): \ 7264 M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR"); 7265 return 7266 M4NO_ERROR; /**< no fatal error here, we should be able to pursue */ 7267 } 7268 7269 /** 7270 * Go to the next frame */ 7271 pC->ReaderAudioAU.m_dataAddress += uiFrameSize; 7272 pC->ReaderAudioAU.m_size -= uiFrameSize; 7273 7274 /** 7275 * Get the CTS of the next frame */ 7276 iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */ 7277 pC->ReaderAudioAU.m_CTS = iCts; 7278 pC->ReaderAudioAU.m_DTS = iCts; 7279 } 7280 7281 /** 7282 * Update the audio begin cut offset */ 7283 pC->iAudioCtsOffset = iCts; 7284 } 7285 } 7286 7287 /** 7288 * Return with no error */ 7289 M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR"); 7290 return M4NO_ERROR; 7291} 7292 7293/** 7294 ****************************************************************************** 7295 * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress) 7296 ****************************************************************************** 7297 */ 7298static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC, 7299 M4OSA_UInt8 *pProgress ) 7300{ 7301 M4OSA_ERR err; 7302 M4OSA_UInt32 uiAudioStepCount = 0; 7303 7304 /* ---------- VIDEO TRANSCODING ---------- */ 7305 7306 if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED 7307 == pC->VideoState) ) /**< If the video encoding is going on */ 7308 { 7309 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 7310 { 7311 err = M4MCS_intVideoNullEncoding(pC); 7312 } 7313 else 7314 { 7315 err = M4MCS_intVideoTranscoding(pC); 7316 } 7317 7318 /** 7319 * No more space, quit properly */ 7320 if( M4WAR_WRITER_STOP_REQ == err ) 7321 { 7322 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts 7323 - pC->uiBeginCutTime) * 100) 7324 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7325 7326 pC->State = M4MCS_kState_FINISHED; 7327 7328 /* bad file produced on very short 3gp file */ 7329 if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 ) 7330 { 7331 /* Nothing has been encoded -> bad produced file -> error returned */ 7332 M4OSA_TRACE2_0( 7333 "M4MCS_intStepEncoding(): video transcoding returns\ 7334 M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); 7335 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; 7336 } 7337 else 7338 { 7339#ifndef M4MCS_AUDIOONLY 7340 /* clean AIR context needed to keep media aspect ratio*/ 7341 7342 if( M4OSA_NULL != pC->m_air_context ) 7343 { 7344 err = M4AIR_cleanUp(pC->m_air_context); 7345 7346 if( err != M4NO_ERROR ) 7347 { 7348 M4OSA_TRACE1_1( 7349 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7350 err); 7351 return err; 7352 } 7353 pC->m_air_context = M4OSA_NULL; 7354 } 7355 7356#endif /*M4MCS_AUDIOONLY*/ 7357 7358 M4OSA_TRACE2_0( 7359 "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE"); 7360 return M4MCS_ERR_NOMORE_SPACE; 7361 } 7362 } 7363 7364 /**< The input plane is null because the input image will be obtained by the 7365 VPP filter from the context */ 7366 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) ) 7367 { 7368 M4OSA_TRACE1_1( 7369 "M4MCS_intStepEncoding(): video transcoding returns 0x%x!", 7370 err); 7371 return err; 7372 } 7373 } 7374 7375 /* ---------- AUDIO TRANSCODING ---------- */ 7376 7377 if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED 7378 == pC->AudioState) ) /**< If there is an audio stream */ 7379 { 7380 while( 7381 /**< If the video encoding is running, encode audio until we reach video time */ 7382 ( ( pC->novideo == M4OSA_FALSE) 7383 && (M4MCS_kStreamState_STARTED == pC->VideoState) 7384 && (pC->ReaderAudioAU.m_CTS 7385 + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) || 7386 /**< If the video encoding is not running, perform 1 step of audio encoding */ 7387 (( M4MCS_kStreamState_STARTED == pC->AudioState) 7388 && (uiAudioStepCount < 1)) ) 7389 { 7390 uiAudioStepCount++; 7391 7392 /**< check if an adio effect has to be applied*/ 7393 err = M4MCS_intCheckAudioEffects(pC); 7394 7395 if( M4NO_ERROR != err ) 7396 { 7397 M4OSA_TRACE1_1( 7398 "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x", 7399 err); 7400 return err; 7401 } 7402 7403 if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 7404 { 7405 err = M4MCS_intAudioNullEncoding(pC); 7406 } 7407 else /**< Audio transcoding */ 7408 { 7409 err = M4MCS_intAudioTranscoding(pC); 7410 } 7411 7412 /** 7413 * No more space, quit properly */ 7414 if( M4WAR_WRITER_STOP_REQ == err ) 7415 { 7416 *pProgress = 7417 (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7418 - pC->uiBeginCutTime) * 100) 7419 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7420 7421 pC->State = M4MCS_kState_FINISHED; 7422 7423 /* bad file produced on very short 3gp file */ 7424 if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 ) 7425 { 7426 /* Nothing has been encoded -> bad produced file -> error returned */ 7427 M4OSA_TRACE2_0( 7428 "M4MCS_intStepEncoding():\ 7429 audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL"); 7430 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL; 7431 } 7432 else 7433 { 7434#ifndef M4MCS_AUDIOONLY 7435 /* clean AIR context needed to keep media aspect ratio*/ 7436 7437 if( M4OSA_NULL != pC->m_air_context ) 7438 { 7439 err = M4AIR_cleanUp(pC->m_air_context); 7440 7441 if( err != M4NO_ERROR ) 7442 { 7443 M4OSA_TRACE1_1( 7444 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7445 err); 7446 return err; 7447 } 7448 pC->m_air_context = M4OSA_NULL; 7449 } 7450 7451#endif /*M4MCS_AUDIOONLY*/ 7452 7453 M4OSA_TRACE2_0( 7454 "M4MCS_intStepEncoding(): \ 7455 audio transcoding returns M4MCS_ERR_NOMORE_SPACE"); 7456 return M4MCS_ERR_NOMORE_SPACE; 7457 } 7458 } 7459 7460 if( M4WAR_NO_MORE_AU == err ) 7461 { 7462 pC->AudioState = M4MCS_kStreamState_FINISHED; 7463 M4OSA_TRACE3_0( 7464 "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU"); 7465 break; 7466 } 7467 else if( M4NO_ERROR != err ) 7468 { 7469 M4OSA_TRACE1_1( 7470 "M4MCS_intStepEncoding(): audio transcoding returns 0x%x", 7471 err); 7472 return err; 7473 } 7474 7475 /** 7476 * Check for end cut */ 7477 /* We absolutely want to have less or same audio duration as video -> 7478 (2*pC->m_audioAUDuration) */ 7479 if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7480 + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime ) 7481 { 7482 pC->AudioState = M4MCS_kStreamState_FINISHED; 7483 break; 7484 } 7485 } 7486 } 7487 7488 /* ---------- PROGRESS MANAGEMENT ---------- */ 7489 7490 /** 7491 * Compute progress */ 7492 if( pC->novideo ) 7493 { 7494 if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime ) 7495 { 7496 *pProgress = 0; 7497 } 7498 else 7499 { 7500 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS 7501 - pC->uiBeginCutTime) * 100) 7502 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7503 } 7504 //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS); 7505 7506 } 7507 else 7508 { 7509 if( pC->dViDecCurrentCts < pC->uiBeginCutTime ) 7510 { 7511 *pProgress = 0; 7512 } 7513 else 7514 { 7515 *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts 7516 - pC->uiBeginCutTime) * 100) 7517 / (pC->uiEndCutTime - pC->uiBeginCutTime)); 7518 } 7519 //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts); 7520 } 7521 7522 /** 7523 * Sanity check */ 7524 if( *pProgress > 99 ) 7525 { 7526 *pProgress = 99; 7527 } 7528 7529 /** 7530 * Increment CTS for next step */ 7531 if( pC->novideo == M4OSA_FALSE ) 7532 { 7533 if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 7534 { 7535 pC->dViDecCurrentCts += 1; 7536 } 7537 else 7538 { 7539 pC->dViDecCurrentCts += pC->dCtsIncrement; 7540 } 7541 } 7542 7543 /** 7544 * The transcoding is finished when no stream is being encoded anymore */ 7545 if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState)) 7546 && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) ) 7547 { 7548 /* the AIR part can only be used when video codecs are compiled*/ 7549#ifndef M4MCS_AUDIOONLY 7550 /* clean AIR context needed to keep media aspect ratio*/ 7551 7552 if( M4OSA_NULL != pC->m_air_context ) 7553 { 7554 err = M4AIR_cleanUp(pC->m_air_context); 7555 7556 if( err != M4NO_ERROR ) 7557 { 7558 M4OSA_TRACE1_1( 7559 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x", 7560 err); 7561 return err; 7562 } 7563 pC->m_air_context = M4OSA_NULL; 7564 } 7565 7566#endif /*M4MCS_AUDIOONLY*/ 7567 /**/ 7568 7569 *pProgress = 100; 7570 pC->State = M4MCS_kState_FINISHED; 7571 M4OSA_TRACE2_0( 7572 "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE"); 7573 return M4MCS_WAR_TRANSCODING_DONE; 7574 } 7575 7576 /** 7577 * Return with no error */ 7578 M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR"); 7579 return M4NO_ERROR; 7580} 7581 7582/** 7583 ****************************************************************************** 7584 * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC) 7585 ****************************************************************************** 7586 */ 7587static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC ) 7588{ 7589 M4OSA_ERR err; 7590 M4OSA_Int32 iCts; 7591 7592 if( pC->novideo ) 7593 { 7594 pC->State = M4MCS_kState_BEGINVIDEODECODE; 7595 return M4NO_ERROR; 7596 } 7597 7598 /** 7599 * Jump to the previous RAP in the clip (first get the time, then jump) */ 7600 iCts = (M4OSA_Int32)pC->dViDecStartingCts; 7601 err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext, 7602 (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); 7603 7604 if( M4WAR_READER_INFORMATION_NOT_PRESENT == err ) 7605 { 7606 /* No RAP table, jump backward and predecode */ 7607 iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT; 7608 7609 if( iCts < 0 ) 7610 iCts = 0; 7611 } 7612 else if( M4NO_ERROR != err ) 7613 { 7614 M4OSA_TRACE1_1( 7615 "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!", 7616 err); 7617 return err; 7618 } 7619 7620 /* + CRLV6775 -H.264 Trimming */ 7621 7622 if( M4OSA_TRUE == pC->bH264Trim ) 7623 { 7624 7625 // Save jump time for safety, this fix should be generic 7626 7627 M4OSA_Int32 iCtsOri = iCts; 7628 7629 7630 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 7631 (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); 7632 7633 if( M4NO_ERROR != err ) 7634 { 7635 M4OSA_TRACE1_1( 7636 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", 7637 err); 7638 return err; 7639 } 7640 7641 if( pC->ReaderVideoAU1.m_structSize == 0 ) 7642 { 7643 /** 7644 * Initializes an access Unit */ 7645 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7646 (M4_StreamHandler *)pC->pReaderVideoStream, 7647 &pC->ReaderVideoAU1); 7648 7649 if( M4NO_ERROR != err ) 7650 { 7651 M4OSA_TRACE1_1( 7652 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 7653 err); 7654 return err; 7655 } 7656 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7657 (M4_StreamHandler *)pC->pReaderVideoStream, 7658 &pC->ReaderVideoAU1); 7659 7660 if( M4WAR_NO_MORE_AU == err ) 7661 { 7662 M4OSA_TRACE2_0( 7663 "M4MCS_intVideoNullEncoding(): \ 7664 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 7665 /* The audio transcoding is finished */ 7666 pC->VideoState = M4MCS_kStreamState_FINISHED; 7667 return err; 7668 } 7669 else if( M4NO_ERROR != err ) 7670 { 7671 M4OSA_TRACE1_1( 7672 "M4MCS_intVideoNullEncoding():\ 7673 m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", 7674 err); 7675 return err; 7676 } 7677 7678 pC->ReaderVideoAU1.m_structSize = 0; 7679 } 7680 7681 err = H264MCS_ProcessSPS_PPS(pC->m_pInstance, 7682 (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size); 7683 7684 if( M4NO_ERROR != err ) 7685 { 7686 M4OSA_TRACE1_1( 7687 "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!", 7688 err); 7689 return err; 7690 } 7691 7692 7693 // Restore jump time for safety, this fix should be generic 7694 7695 iCts = iCtsOri; 7696 7697 7698 } 7699 /* - CRLV6775 -H.264 Trimming */ 7700 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 7701 (M4_StreamHandler *)pC->pReaderVideoStream, &iCts); 7702 7703 if( M4NO_ERROR != err ) 7704 { 7705 M4OSA_TRACE1_1( 7706 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", err); 7707 return err; 7708 } 7709 7710 /** 7711 * Decode one step */ 7712 pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr); 7713 7714 /** 7715 * Be sure we don't decode too far */ 7716 if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) 7717 { 7718 pC->dViDecCurrentCts = pC->dViDecStartingCts; 7719 } 7720 7721 /** 7722 * Decode at least once with the bJump flag to true */ 7723 M4OSA_TRACE3_1( 7724 "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f", 7725 pC->dViDecCurrentCts); 7726 pC->isRenderDup = M4OSA_FALSE; 7727 err = 7728 pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts, 7729 M4OSA_TRUE); 7730 7731 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) 7732 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) 7733 { 7734 M4OSA_TRACE1_1( 7735 "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err); 7736 return err; 7737 } 7738 7739 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 7740 { 7741 M4OSA_TRACE2_0("Decoding output the same frame as before 1"); 7742 pC->isRenderDup = M4OSA_TRUE; 7743 } 7744 7745 /** 7746 * Increment decoding cts for the next step */ 7747 pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; 7748 7749 /** 7750 * Update state automaton */ 7751 if( pC->dViDecCurrentCts > pC->dViDecStartingCts ) 7752 { 7753 /** 7754 * Be sure we don't decode too far */ 7755 pC->dViDecCurrentCts = pC->dViDecStartingCts; 7756 pC->State = M4MCS_kState_PROCESSING; 7757 } 7758 else 7759 { 7760 pC->State = M4MCS_kState_BEGINVIDEODECODE; 7761 } 7762 7763 /** 7764 * Return with no error */ 7765 M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR"); 7766 return M4NO_ERROR; 7767} 7768 7769/** 7770 ****************************************************************************** 7771 * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC) 7772 ****************************************************************************** 7773 */ 7774static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC ) 7775{ 7776 M4OSA_ERR err; 7777 M4_MediaTime dDecTarget; 7778 7779 if( pC->novideo ) 7780 { 7781 pC->State = M4MCS_kState_PROCESSING; 7782 return M4NO_ERROR; 7783 } 7784 7785 /** 7786 * Decode */ 7787 dDecTarget = pC->dViDecCurrentCts; 7788 M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f", 7789 pC->dViDecCurrentCts); 7790 pC->isRenderDup = M4OSA_FALSE; 7791 err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget, 7792 M4OSA_FALSE); 7793 7794 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) 7795 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) 7796 { 7797 M4OSA_TRACE1_1( 7798 "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err); 7799 return err; 7800 } 7801 7802 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 7803 { 7804 M4OSA_TRACE2_0("Decoding output the same frame as before 2"); 7805 pC->isRenderDup = M4OSA_TRUE; 7806 } 7807 7808 /** 7809 * Increment decoding cts for the next step */ 7810 pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr; 7811 7812 /** 7813 * Update state automaton, if needed */ 7814 if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts) 7815 || (M4WAR_NO_MORE_AU == err) ) 7816 { 7817 /** 7818 * Be sure we don't decode too far */ 7819 pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts; 7820 pC->State = M4MCS_kState_PROCESSING; 7821 } 7822 7823 /** 7824 * Return with no error */ 7825 M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR"); 7826 return M4NO_ERROR; 7827} 7828 7829/*****************************/ 7830/* define AMR silence frames */ 7831/*****************************/ 7832 7833#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13 7834#define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160 7835 7836#ifdef M4VSS3GPP_SILENCE_FRAMES 7837 7838const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[ 7839 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] = 7840 { 7841 0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00 7842 }; 7843#else 7844 7845extern 7846const 7847M4OSA_UInt8 7848M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE]; 7849 7850#endif 7851 7852/*****************************/ 7853/* define AAC silence frames */ 7854/*****************************/ 7855 7856#define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE 4 7857 7858#ifdef M4VSS3GPP_SILENCE_FRAMES 7859 7860const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[ 7861 M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] = 7862 { 7863 0x00, 0xC8, 0x20, 0x07 7864 }; 7865#else 7866 7867extern const M4OSA_UInt8 7868M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE]; 7869 7870#endif 7871 7872#define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE 6 7873 7874#ifdef M4VSS3GPP_SILENCE_FRAMES 7875 7876const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[ 7877 M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] = 7878 { 7879 0x21, 0x10, 0x03, 0x20, 0x54, 0x1C 7880 }; 7881#else 7882 7883extern const 7884M4OSA_UInt8 7885M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE]; 7886 7887#endif 7888 7889/** 7890 ****************************************************************************** 7891 * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC) 7892 * @return M4NO_ERROR: No error 7893 ****************************************************************************** 7894 */ 7895 7896static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC ) 7897{ 7898 M4OSA_ERR err; 7899 7900 if( pC->noaudio ) 7901 return M4NO_ERROR; 7902 7903 /* Check if all audio frame has been written (happens at begin cut) */ 7904 if( pC->ReaderAudioAU.m_size == 0 ) 7905 { 7906 /** 7907 * Initializes a new AU if needed */ 7908 if( pC->ReaderAudioAU1.m_structSize == 0 ) 7909 { 7910 /** 7911 * Initializes an access Unit */ 7912 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7913 (M4_StreamHandler *)pC->pReaderAudioStream, 7914 &pC->ReaderAudioAU1); 7915 7916 if( M4NO_ERROR != err ) 7917 { 7918 M4OSA_TRACE1_1( 7919 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 7920 err); 7921 return err; 7922 } 7923 7924 pC->m_pDataAddress1 = 7925 (M4OSA_MemAddr8)M4OSA_malloc(pC->ReaderAudioAU1.m_maxsize, 7926 M4MCS, (M4OSA_Char *)"Temporary AU1 buffer"); 7927 7928 if( pC->m_pDataAddress1 == M4OSA_NULL ) 7929 { 7930 M4OSA_TRACE1_0( 7931 "M4MCS_intAudioNullEncoding(): allocation error"); 7932 return M4ERR_ALLOC; 7933 } 7934 7935 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 7936 (M4_StreamHandler *)pC->pReaderAudioStream, 7937 &pC->ReaderAudioAU1); 7938 7939 if( M4WAR_NO_MORE_AU == err ) 7940 { 7941 M4OSA_TRACE2_0( 7942 "M4MCS_intAudioNullEncoding():\ 7943 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 7944 /* The audio transcoding is finished */ 7945 pC->AudioState = M4MCS_kStreamState_FINISHED; 7946 return err; 7947 } 7948 else if( M4NO_ERROR != err ) 7949 { 7950 M4OSA_TRACE1_1( 7951 "M4MCS_intAudioNullEncoding(): \ 7952 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", 7953 err); 7954 return err; 7955 } 7956 /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying , 7957 constant memory reader case*/ 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 and 7965 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 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 7971 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); 7972 /* pC->m_pDataAddress1 and 7973 pC->m_pDataAddress2 must be reallocated at the same time */ 7974 /* Update stream properties */ 7975 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 7976 pC->ReaderAudioAU1.m_maxsize; 7977 } 7978 /**/ 7979 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataAddress1, 7980 (M4OSA_MemAddr8)pC->ReaderAudioAU1.m_dataAddress, 7981 pC->ReaderAudioAU1.m_size); 7982 } 7983 7984 if( pC->ReaderAudioAU2.m_structSize == 0 ) 7985 { 7986 /** 7987 * Initializes an access Unit */ 7988 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 7989 (M4_StreamHandler *)pC->pReaderAudioStream, 7990 &pC->ReaderAudioAU2); 7991 7992 if( M4NO_ERROR != err ) 7993 { 7994 M4OSA_TRACE1_1( 7995 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 7996 err); 7997 return err; 7998 } 7999 pC->m_pDataAddress2 = 8000 (M4OSA_MemAddr8)M4OSA_malloc(pC->ReaderAudioAU2.m_maxsize, 8001 M4MCS, (M4OSA_Char *)"Temporary AU buffer"); 8002 8003 if( pC->m_pDataAddress2 == M4OSA_NULL ) 8004 { 8005 M4OSA_TRACE1_0( 8006 "M4MCS_intAudioNullEncoding(): allocation error"); 8007 return M4ERR_ALLOC; 8008 } 8009 } 8010 /** 8011 * Read the next audio AU in the input file */ 8012 if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS ) 8013 { 8014 M4OSA_memcpy((M4OSA_MemAddr8) &pC->ReaderAudioAU, 8015 (M4OSA_MemAddr8) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit)); 8016 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8017 (M4_StreamHandler *)pC->pReaderAudioStream, 8018 &pC->ReaderAudioAU1); 8019 8020 if( pC->ReaderAudioAU1.m_maxsize 8021 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) 8022 { 8023 /* Constant memory reader case, we need to reallocate the temporary buffers */ 8024 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8025 *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize); 8026 /* pC->m_pDataAddress1 8027 * and pC->m_pDataAddress2 must be reallocated at the same time * 8028 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take 8029 * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > 8030 * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true * 8031 * and the size of the second buffer is never changed. 8032 */ 8033 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8034 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize); 8035 /* pC->m_pDataAddress1 and 8036 * pC->m_pDataAddress2 must be reallocated at the same time 8037 * Update stream properties 8038 */ 8039 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 8040 pC->ReaderAudioAU1.m_maxsize; 8041 } 8042 /**/ 8043 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataAddress1, 8044 (M4OSA_MemAddr8)pC->ReaderAudioAU1.m_dataAddress, 8045 pC->ReaderAudioAU1.m_size); 8046 pC->m_audioAUDuration = 8047 pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS; 8048 pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2; 8049 } 8050 else 8051 { 8052 M4OSA_memcpy((M4OSA_MemAddr8) &pC->ReaderAudioAU, 8053 (M4OSA_MemAddr8) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit)); 8054 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8055 (M4_StreamHandler *)pC->pReaderAudioStream, 8056 &pC->ReaderAudioAU2); 8057 /* Crash in MCS while Audio AU copying , 8058 * constant memory reader case 8059 */ 8060 if( pC->ReaderAudioAU2.m_maxsize 8061 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize ) 8062 { 8063 /* Constant memory reader case, we need to reallocate the temporary buffers */ 8064 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8065 *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize); 8066 /* pC->m_pDataAddress1 and 8067 * pC->m_pDataAddress2 must be reallocated at the same time 8068 * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum 8069 * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream-> 8070 * m_basicProperties.m_maxAUSize)" is never true 8071 * and the size of the second buffer is never changed. 8072 */ 8073 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 8074 *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize); 8075 /* [ END ] 20091008 JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and 8076 pC->m_pDataAddress2 must be reallocated at the same time */ 8077 /* Update stream properties */ 8078 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize = 8079 pC->ReaderAudioAU2.m_maxsize; 8080 } 8081 /**/ 8082 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataAddress2, 8083 (M4OSA_MemAddr8)pC->ReaderAudioAU2.m_dataAddress, 8084 pC->ReaderAudioAU2.m_size); 8085 pC->m_audioAUDuration = 8086 pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS; 8087 pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1; 8088 } 8089 8090 if( M4WAR_NO_MORE_AU == err ) 8091 { 8092 M4OSA_TRACE2_0( 8093 "M4MCS_intAudioNullEncoding(): \ 8094 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 8095 /* The audio transcoding is finished */ 8096 pC->AudioState = M4MCS_kStreamState_FINISHED; 8097 return err; 8098 } 8099 else if( M4NO_ERROR != err ) 8100 { 8101 M4OSA_TRACE1_1( 8102 "M4MCS_intAudioNullEncoding(): \ 8103 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", 8104 err); 8105 return err; 8106 } 8107 } 8108 8109 /** 8110 * Prepare the writer AU */ 8111 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 8112 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8113 8114 if( M4NO_ERROR != err ) 8115 { 8116 M4OSA_TRACE1_1( 8117 "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", 8118 err); 8119 return err; 8120 } 8121 8122 if( pC->uiAudioAUCount 8123 == 0 ) /* If it is the first AU, we set it to silence 8124 (else, errors 0x3841, 0x3847 in our AAC decoder) */ 8125 { 8126 if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC 8127 || pC->InputFileProperties.AudioStreamType 8128 == M4VIDEOEDITING_kAACplus 8129 || pC->InputFileProperties.AudioStreamType 8130 == M4VIDEOEDITING_keAACplus ) 8131 { 8132 if( pC->InputFileProperties.uiNbChannels == 1 ) 8133 { 8134 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; 8135 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress, 8136 (M4OSA_MemAddr8)M4VSS3GPP_AAC_AU_SILENCE_MONO, 8137 pC->WriterAudioAU.size); 8138 } 8139 else if( pC->InputFileProperties.uiNbChannels == 2 ) 8140 { 8141 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; 8142 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress, 8143 (M4OSA_MemAddr8)M4VSS3GPP_AAC_AU_SILENCE_STEREO, 8144 pC->WriterAudioAU.size); 8145 } 8146 else 8147 { 8148 /* Must never happen ...*/ 8149 M4OSA_TRACE1_0( 8150 "M4MCS_intAudioNullEncoding: Bad number of channels in audio input"); 8151 return M4MCS_ERR_INVALID_INPUT_FILE; 8152 } 8153 } 8154 else if( pC->InputFileProperties.AudioStreamType 8155 == M4VIDEOEDITING_kAMR_NB ) 8156 { 8157 pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; 8158 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress, 8159 (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048, 8160 pC->WriterAudioAU.size); 8161 /* Some remaining AMR AU needs to be copied */ 8162 if( pC->ReaderAudioAU.m_size != 0 ) 8163 { 8164 /* Update Writer AU */ 8165 pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size; 8166 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress 8167 + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE, 8168 (M4OSA_MemAddr8)pC->ReaderAudioAU.m_dataAddress, 8169 pC->ReaderAudioAU.m_size); 8170 } 8171 } 8172 else 8173 { 8174 /*MP3 case: copy the AU*/ 8175 M4OSA_TRACE3_1( 8176 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", 8177 pC->ReaderAudioAU.m_size); 8178 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress, 8179 (M4OSA_MemAddr8)pC->ReaderAudioAU.m_dataAddress, 8180 pC->ReaderAudioAU.m_size); 8181 pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; 8182 } 8183 } 8184 else 8185 { 8186 /** 8187 * Copy audio data from reader AU to writer AU */ 8188 M4OSA_TRACE3_1( 8189 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d", 8190 pC->ReaderAudioAU.m_size); 8191 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress, 8192 (M4OSA_MemAddr8)pC->ReaderAudioAU.m_dataAddress, 8193 pC->ReaderAudioAU.m_size); 8194 pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size; 8195 } 8196 8197 /** 8198 * Convert CTS unit from milliseconds to timescale */ 8199 pC->WriterAudioAU.CTS = 8200 (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset) 8201 * (pC->WriterAudioStream.timeScale / 1000.0))); 8202 8203 if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB 8204 && pC->uiAudioAUCount == 0 ) 8205 { 8206 pC->iAudioCtsOffset -= 8207 20; /* Duration of a silence AMR AU, to handle the duration of the added 8208 silence frame */ 8209 } 8210 pC->WriterAudioAU.nbFrag = 0; 8211 M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms", 8212 pC->WriterAudioAU.CTS); 8213 8214 /** 8215 * Write it to the output file */ 8216 pC->uiAudioAUCount++; 8217 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8218 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8219 8220 if( M4NO_ERROR != err ) 8221 { 8222 M4OSA_TRACE1_1( 8223 "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8224 err); 8225 return err; 8226 } 8227 8228 /* All the audio has been written */ 8229 pC->ReaderAudioAU.m_size = 0; 8230 8231 /** 8232 * Return with no error */ 8233 M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR"); 8234 return M4NO_ERROR; 8235} 8236 8237/** 8238 ****************************************************************************** 8239 * @brief Init Audio Transcoding 8240 * @return M4NO_ERROR: No error 8241 ****************************************************************************** 8242 */ 8243static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) 8244{ 8245 M4OSA_ERR err; /**< General error */ 8246 8247 M4OSA_UInt32 8248 uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */ 8249 M4OSA_UInt32 8250 uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */ 8251 8252 int ssrcErr; /**< Error while ssrc processing */ 8253 M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */ 8254 M4OSA_UInt32 8255 uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */ 8256 M4OSA_MemAddr8 8257 pSsrcInput; /**< Pointer to the good buffer location for ssrc input */ 8258 M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */ 8259 M4OSA_UInt32 8260 uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */ 8261 8262 M4OSA_UInt8 8263 needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */ 8264 M4OSA_UInt32 8265 uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo 8266 <-> mono conversion is applied */ 8267 M4OSA_MemAddr8 pChannelConvertorInput = 8268 M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */ 8269 M4OSA_UInt32 uiChannelConvertorNbSamples = 8270 0; /**< Nb of pcm samples to convert in channel convertor */ 8271 M4OSA_MemAddr8 pChannelConvertorOutput = 8272 M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */ 8273 8274 M4OSA_Time 8275 frameTimeDelta; /**< Duration of the encoded (then written) data */ 8276 M4OSA_UInt32 8277 uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */ 8278 M4OSA_UInt32 8279 uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */ 8280 M4OSA_MemAddr8 8281 pEncoderInput; /**< Pointer to the good buffer location for encoder input */ 8282 M4ENCODER_AudioBuffer pEncInBuffer; /**< Encoder input buffer for api */ 8283 M4ENCODER_AudioBuffer pEncOutBuffer; /**< Encoder output buffer for api */ 8284 8285 M4OSA_Int16 *tempBuffOut = M4OSA_NULL; 8286 /*FlB 2009.03.04: apply audio effects if an effect is active*/ 8287 M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber); 8288 8289 if( pC->noaudio ) 8290 return M4NO_ERROR; 8291 8292 /* _________________ */ 8293 /*| |*/ 8294 /*| READ AND DECODE |*/ 8295 /*|_________________|*/ 8296 8297 /* Check if we have to empty the decoder out buffer first */ 8298 if( M4OSA_NULL != pC->pPosInDecBufferOut ) 8299 { 8300 goto m4mcs_intaudiotranscoding_feed_resampler; 8301 } 8302 8303 /* Check if all audio frame has been decoded */ 8304 if( pC->ReaderAudioAU.m_size == 0 ) 8305 { 8306 /** 8307 * Read the next audio AU in the input file */ 8308 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8309 (M4_StreamHandler *)pC->pReaderAudioStream, &pC->ReaderAudioAU); 8310 8311#ifdef MCS_DUMP_PCM_TO_FILE 8312 8313 fwrite(pC->ReaderAudioAU.m_dataAddress, pC->ReaderAudioAU.m_size, 1, 8314 file_au_reader); 8315 fwrite("____", 4, 1, file_au_reader); 8316 8317#endif 8318 8319 if( M4WAR_NO_MORE_AU == err ) /**< The audio transcoding is finished */ 8320 { 8321 pC->AudioState = M4MCS_kStreamState_FINISHED; 8322 M4OSA_TRACE2_0( 8323 "M4MCS_intAudioTranscoding():\ 8324 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); 8325 return err; 8326 } 8327 else if( M4NO_ERROR != err ) 8328 { 8329 M4OSA_TRACE1_1( 8330 "M4MCS_intAudioTranscoding():\ 8331 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", 8332 err); 8333 return err; 8334 } 8335 } 8336 8337 /** 8338 * Decode the AU */ 8339 pC->AudioDecBufferIn.m_dataAddress = pC->ReaderAudioAU.m_dataAddress; 8340 pC->AudioDecBufferIn.m_bufferSize = pC->ReaderAudioAU.m_size; 8341 8342 err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, 8343 &pC->AudioDecBufferIn, &pC->AudioDecBufferOut, M4OSA_FALSE); 8344 8345 if( M4NO_ERROR != err ) 8346 { 8347 M4OSA_TRACE1_1( 8348 "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x", 8349 err); 8350 return err; 8351 } 8352 8353#ifdef MCS_DUMP_PCM_TO_FILE 8354 8355 fwrite(pC->AudioDecBufferOut.m_dataAddress, 8356 pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder); 8357 8358#endif 8359 8360 /* update the part of audio that has been decoded into the frame */ 8361 8362 pC->ReaderAudioAU.m_dataAddress += pC->AudioDecBufferIn.m_bufferSize; 8363 pC->ReaderAudioAU.m_size -= pC->AudioDecBufferIn.m_bufferSize; 8364 8365 /* Set the current position in the decoder out buffer */ 8366 pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress; 8367 8368 /* ________________ */ 8369 /*| |*/ 8370 /*| FEED RESAMPLER |*/ 8371 /*|________________|*/ 8372 8373m4mcs_intaudiotranscoding_feed_resampler: 8374 8375 /* Check if we have to empty the ssrc out buffer first */ 8376 if( M4OSA_NULL != pC->pPosInSsrcBufferOut ) 8377 { 8378 goto m4mcs_intaudiotranscoding_prepare_input_buffer; 8379 } 8380 8381 /* Compute number of bytes remaining in the decoder buffer */ 8382 uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short) 8383 * pC->pReaderAudioStream->m_nbChannels; 8384 uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress 8385 + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut; 8386 8387 /* Check if we can feed directly the Ssrc with the decoder out buffer */ 8388 if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn) 8389 && (uiBytesDec >= uiSsrcInSize) ) 8390 { 8391 pSsrcInput = pC->pPosInDecBufferOut; 8392 8393 /* update data consumed into decoder buffer after resampling */ 8394 if( uiBytesDec == uiSsrcInSize ) 8395 pC->pPosInDecBufferOut = M4OSA_NULL; 8396 else 8397 pC->pPosInDecBufferOut += uiSsrcInSize; 8398 8399 goto m4mcs_intaudiotranscoding_do_resampling; 8400 } 8401 8402 /** 8403 * Compute remaining space in Ssrc buffer in */ 8404 uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn; 8405 8406 /** 8407 * Nb of bytes copied is the minimum between nb of bytes remaining in 8408 * decoder out buffer and space remaining in ssrc in buffer */ 8409 uiDecoder2Ssrc_NbBytes = 8410 (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec; 8411 8412 /** 8413 * Copy from the decoder out buffer into the Ssrc in buffer */ 8414 M4OSA_memcpy(pC->pPosInSsrcBufferIn, pC->pPosInDecBufferOut, 8415 uiDecoder2Ssrc_NbBytes); 8416 8417 /** 8418 * Update the position in the decoder out buffer */ 8419 pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes; 8420 8421 /** 8422 * Update the position in the Ssrc in buffer */ 8423 pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes; 8424 8425 /** 8426 * Check if the decoder buffer out is empty */ 8427 if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress) 8428 == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize ) 8429 { 8430 pC->pPosInDecBufferOut = M4OSA_NULL; 8431 } 8432 8433 /* Check if the Ssrc in buffer is ready (= full) */ 8434 if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn) 8435 < (M4OSA_Int32)uiSsrcInSize ) 8436 { 8437 goto m4mcs_intaudiotranscoding_end; 8438 } 8439 8440 pSsrcInput = pC->pSsrcBufferIn; 8441 8442 /* update data consumed into ssrc buffer in after resampling (empty) */ 8443 pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn; 8444 8445 /* ___________________ */ 8446 /*| |*/ 8447 /*| DO THE RESAMPLING |*/ 8448 /*|___________________|*/ 8449 8450m4mcs_intaudiotranscoding_do_resampling: 8451 8452 /** 8453 * No need for memcopy, we can feed Ssrc directly with the data in the audio 8454 decoder out buffer*/ 8455 8456 ssrcErr = 0; 8457 8458 if( pC->pReaderAudioStream->m_nbChannels == 1 ) 8459 { 8460 tempBuffOut = 8461 (short *)M4OSA_malloc((pC->iSsrcNbSamplOut * sizeof(short) * 2 8462 * ((*pC).InputFileProperties).uiNbChannels), 8463 M4VSS3GPP,(M4OSA_Char *) "tempBuffOut"); 8464 M4OSA_memset((M4OSA_MemAddr8)tempBuffOut, (pC->iSsrcNbSamplOut * sizeof(short) * 2 8465 * ((*pC).InputFileProperties).uiNbChannels), 0); 8466 8467 LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput, 8468 pC->iSsrcNbSamplOut, (M4OSA_Int32)pC->pLVAudioResampler); 8469 } 8470 else 8471 { 8472 M4OSA_memset(pC->pSsrcBufferOut, (pC->iSsrcNbSamplOut * sizeof(short) 8473 * ((*pC).InputFileProperties).uiNbChannels), 0); 8474 8475 LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut, 8476 (short *)pSsrcInput, pC->iSsrcNbSamplOut, (M4OSA_Int32)pC->pLVAudioResampler); 8477 } 8478 8479 if( pC->pReaderAudioStream->m_nbChannels == 1 ) 8480 { 8481 From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut, 8482 (short)pC->iSsrcNbSamplOut); 8483 M4OSA_free((M4OSA_MemAddr32)tempBuffOut); 8484 } 8485 8486 8487 if( 0 != ssrcErr ) 8488 { 8489 M4OSA_TRACE1_1( 8490 "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \ 8491 returning M4MCS_ERR_AUDIO_CONVERSION_FAILED", 8492 ssrcErr); 8493 return M4MCS_ERR_AUDIO_CONVERSION_FAILED; 8494 } 8495 8496 pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut; 8497 8498 /* ______________________ */ 8499 /*| |*/ 8500 /*| PREPARE INPUT BUFFER |*/ 8501 /*|______________________|*/ 8502 8503m4mcs_intaudiotranscoding_prepare_input_buffer: 8504 8505 /* Set the flag for channel conversion requirement */ 8506 if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 8507 && (pC->pReaderAudioStream->m_nbChannels == 2) ) 8508 { 8509 needChannelConversion = 1; 8510 uiChannelConvertorCoeff = 4; 8511 } 8512 else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo) 8513 && (pC->pReaderAudioStream->m_nbChannels == 1) ) 8514 { 8515 needChannelConversion = 2; 8516 uiChannelConvertorCoeff = 1; 8517 } 8518 else 8519 { 8520 needChannelConversion = 0; 8521 uiChannelConvertorCoeff = 2; 8522 } 8523 8524 /* Compute number of bytes remaining in the Ssrc buffer */ 8525 uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short) 8526 * pC->pReaderAudioStream->m_nbChannels; 8527 uiBytesSsrc = 8528 ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut; 8529 8530 /* Check if the ssrc buffer is full */ 8531 if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut ) 8532 { 8533 uiSsrc2Encoder_NbBytes = 8534 pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2; 8535 8536 /* Check if we can feed directly the encoder with the ssrc out buffer */ 8537 if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL) 8538 && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) ) 8539 { 8540 /* update position in ssrc out buffer after encoding */ 8541 if( uiBytesSsrc == uiSsrc2Encoder_NbBytes ) 8542 pC->pPosInSsrcBufferOut = M4OSA_NULL; 8543 else 8544 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; 8545 8546 /* mark the encoder buffer ready (= full) */ 8547 pC->pPosInAudioEncoderBuffer = 8548 pC->pAudioEncoderBuffer + pC->audioEncoderGranularity; 8549 8550 if( needChannelConversion > 0 ) 8551 { 8552 /* channel convertor writes directly into encoder buffer */ 8553 pEncoderInput = pC->pAudioEncoderBuffer; 8554 8555 pChannelConvertorInput = pC->pSsrcBufferOut; 8556 pChannelConvertorOutput = pC->pAudioEncoderBuffer; 8557 uiChannelConvertorNbSamples = 8558 uiSsrc2Encoder_NbBytes / sizeof(short); 8559 8560 goto m4mcs_intaudiotranscoding_channel_convertor; 8561 } 8562 else 8563 { 8564 /* encode directly from ssrc out buffer */ 8565 pEncoderInput = pC->pSsrcBufferOut; 8566 8567 goto m4mcs_intaudiotranscoding_encode_and_write; 8568 } 8569 } 8570 } 8571 8572 /** 8573 * Compute remaining space in encoder buffer in */ 8574 if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL ) 8575 { 8576 pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer; 8577 } 8578 8579 uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity) 8580 - pC->pPosInAudioEncoderBuffer; 8581 pEncoderInput = pC->pAudioEncoderBuffer; 8582 8583 /** 8584 * Nb of bytes copied is the minimum between nb of bytes remaining in 8585 * decoder out buffer and space remaining in ssrc in buffer */ 8586 uiSsrc2Encoder_NbBytes = 8587 (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc) 8588 ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc; 8589 8590 if( needChannelConversion > 0 ) 8591 { 8592 /* channel convertor writes directly into encoder buffer */ 8593 pChannelConvertorInput = pC->pPosInSsrcBufferOut; 8594 pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer; 8595 uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short); 8596 } 8597 else 8598 { 8599 /* copy from the ssrc out buffer into the encoder in buffer */ 8600 M4OSA_memcpy(pC->pPosInAudioEncoderBuffer, pC->pPosInSsrcBufferOut, 8601 uiSsrc2Encoder_NbBytes); 8602 } 8603 8604 /* Update position in ssrc out buffer after encoding */ 8605 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes; 8606 8607 /* Update the position in the encoder in buffer */ 8608 pC->pPosInAudioEncoderBuffer += 8609 uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff; 8610 8611 /* Check if the ssrc buffer out is empty */ 8612 if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut) 8613 == (M4OSA_Int32)uiSsrcOutSize ) 8614 { 8615 pC->pPosInSsrcBufferOut = M4OSA_NULL; 8616 } 8617 8618 /* go to next statement */ 8619 if( needChannelConversion > 0 ) 8620 goto m4mcs_intaudiotranscoding_channel_convertor; 8621 else 8622 goto m4mcs_intaudiotranscoding_encode_and_write; 8623 8624 /* _________________ */ 8625 /*| |*/ 8626 /*| STEREO <-> MONO |*/ 8627 /*|_________________|*/ 8628 8629m4mcs_intaudiotranscoding_channel_convertor: 8630 8631 /* convert the input pcm stream to mono or to stereo */ 8632 switch( needChannelConversion ) 8633 { 8634 case 1: /* stereo to mono */ 8635 From2iToMono_16((short *)pChannelConvertorInput, 8636 (short *)pChannelConvertorOutput, 8637 (short)(uiChannelConvertorNbSamples / 2)); 8638 break; 8639 8640 case 2: /* mono to stereo */ 8641 MonoTo2I_16((short *)pChannelConvertorInput, 8642 (short *)pChannelConvertorOutput, 8643 (short)uiChannelConvertorNbSamples); 8644 break; 8645 } 8646 8647 /* __________________ */ 8648 /*| |*/ 8649 /*| ENCODE AND WRITE |*/ 8650 /*|__________________|*/ 8651 8652m4mcs_intaudiotranscoding_encode_and_write: 8653 8654 /* Check if the encoder in buffer is ready (= full) */ 8655 if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer) 8656 < (M4OSA_Int32)pC->audioEncoderGranularity ) 8657 { 8658 goto m4mcs_intaudiotranscoding_end; 8659 } 8660 8661 /* [Mono] or [Stereo interleaved] : all is in one buffer */ 8662 pEncInBuffer.pTableBuffer[0] = pEncoderInput; 8663 pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity; 8664 pEncInBuffer.pTableBuffer[1] = M4OSA_NULL; 8665 pEncInBuffer.pTableBufferSize[1] = 0; 8666 8667 /* Time in ms from data size, because it is PCM16 samples */ 8668 frameTimeDelta = 8669 ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2) 8670 / sizeof(short) / pC->pReaderAudioStream->m_nbChannels; 8671 8672 /** 8673 * Prepare the writer AU */ 8674 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 8675 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8676 8677 if( M4NO_ERROR != err ) 8678 { 8679 M4OSA_TRACE1_1( 8680 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x", 8681 err); 8682 return err; 8683 } 8684 8685 /*FlB 2009.03.04: apply audio effects if an effect is active*/ 8686 if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects ) 8687 { 8688 if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL ) 8689 { 8690 M4MCS_ExternalProgress pProgress; 8691 M4OSA_UInt64 tempProgress = 0; 8692 pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS; 8693 8694 pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000) 8695 / pC->WriterAudioStream.timeScale; 8696 tempProgress = ( (M4OSA_UInt64)pC->ReaderAudioAU.m_CTS 8697 - pC->pEffects[*pActiveEffectNumber].uiStartTime 8698 - pC->uiBeginCutTime) * 1000; 8699 pProgress.uiProgress = 8700 (M4OSA_UInt32)(tempProgress / (M4OSA_UInt64)pC->pEffects[ 8701 *pActiveEffectNumber].uiDuration); 8702 8703 err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct( 8704 pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt, 8705 (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0], 8706 pEncInBuffer.pTableBufferSize[0], &pProgress); 8707 8708 if( err != M4NO_ERROR ) 8709 { 8710 M4OSA_TRACE1_1( 8711 "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x", 8712 err); 8713 return err; 8714 } 8715 } 8716 } 8717 8718 /** 8719 * Prepare output buffer */ 8720 pEncOutBuffer.pTableBuffer[0] = 8721 (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress; 8722 pEncOutBuffer.pTableBufferSize[0] = 0; 8723 8724#ifdef MCS_DUMP_PCM_TO_FILE 8725 8726 fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1, 8727 file_pcm_encoder); 8728 8729#endif 8730 8731 if( M4OSA_FALSE == pC->b_isRawWriter ) 8732 { 8733 /* This allow to write PCM data to file and to encode AMR data, 8734 when output file is not RAW */ 8735 if( pC->pOutputPCMfile != M4OSA_NULL ) 8736 { 8737 pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile, 8738 pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]); 8739 } 8740 8741 /** 8742 * Encode the PCM audio */ 8743 err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt, 8744 &pEncInBuffer, &pEncOutBuffer); 8745 8746 if( M4NO_ERROR != err ) 8747 { 8748 M4OSA_TRACE1_1( 8749 "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x", 8750 err); 8751 return err; 8752 } 8753 8754 /* update data consumed into encoder buffer in after encoding (empty) */ 8755 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 8756 8757 /** 8758 * Set AU cts and size */ 8759 pC->WriterAudioAU.size = 8760 pEncOutBuffer. 8761 pTableBufferSize[0]; /**< Get the size of encoded data */ 8762 pC->WriterAudioAU.CTS += frameTimeDelta; 8763 8764 /** 8765 * Update duration of the encoded AU */ 8766 pC->m_audioAUDuration = 8767 ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale; 8768 8769 /** 8770 * Write the encoded AU to the output file */ 8771 pC->uiAudioAUCount++; 8772 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8773 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8774 8775 if( M4NO_ERROR != err ) 8776 { 8777 M4OSA_TRACE1_1( 8778 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8779 err); 8780 return err; 8781 } 8782 } 8783 else 8784 { 8785 /* update data consumed into encoder buffer in after encoding (empty) */ 8786 pC->pPosInAudioEncoderBuffer = M4OSA_NULL; 8787 8788 pC->WriterAudioAU.dataAddress = 8789 (M4OSA_MemAddr32) 8790 pEncoderInput; /* will be converted back to u8* in file write */ 8791 pC->WriterAudioAU.size = pC->audioEncoderGranularity; 8792 pC->uiAudioAUCount++; 8793 8794 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 8795 M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU); 8796 8797 if( M4NO_ERROR != err ) 8798 { 8799 M4OSA_TRACE1_1( 8800 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x", 8801 err); 8802 return err; 8803 } 8804 } 8805 8806 /* _______________ */ 8807 /*| |*/ 8808 /*| ONE PASS DONE |*/ 8809 /*|_______________|*/ 8810 8811m4mcs_intaudiotranscoding_end: 8812 8813 /** 8814 * Return with no error */ 8815 M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR"); 8816 return M4NO_ERROR; 8817} 8818 8819/** 8820 ****************************************************************************** 8821 * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize) 8822 * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU 8823 * because max AU size can be reevaluated during reading 8824 * @return M4NO_ERROR: No error 8825 ****************************************************************************** 8826 */ 8827static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr, 8828 M4OSA_UInt32 newSize ) 8829{ 8830 if( *addr != M4OSA_NULL ) 8831 { 8832 M4OSA_free(( M4OSA_MemAddr32) * addr); 8833 *addr = (M4OSA_MemAddr8)M4OSA_malloc(newSize, M4MCS, 8834 (M4OSA_Char *)"Reallocation of temporary AU buffer"); 8835 8836 if( *addr == M4OSA_NULL ) 8837 { 8838 return M4ERR_ALLOC; 8839 } 8840 } 8841 8842 return M4NO_ERROR; 8843} 8844 8845/** 8846 ****************************************************************************** 8847 * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC) 8848 * @author Alexis Vapillon (NXP Software Vision) 8849 * @return M4NO_ERROR: No error 8850 ****************************************************************************** 8851 */ 8852static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC ) 8853{ 8854 M4OSA_ERR err = M4NO_ERROR; 8855 /* Duration of the AU (find the next AU duration 8856 * to obtain a more precise video end cut) 8857 */ 8858 M4OSA_UInt32 videoAUDuration = 0; 8859 8860 M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL; 8861 M4OSA_Int32 lastdecodedCTS = 0; 8862 M4_AccessUnit lReaderVideoAU; /**< Read video access unit */ 8863 8864 if( pC->novideo ) 8865 return M4NO_ERROR; 8866 8867 /* H.264 Trimming */ 8868 if( ( ( pC->bH264Trim == M4OSA_TRUE) 8869 && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames) 8870 && (pC->uiBeginCutTime > 0)) 8871 || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) ) 8872 { 8873 err = M4MCS_intVideoTranscoding(pC); 8874 return err; 8875 } 8876 8877 8878 if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0)) 8879 { 8880 // StageFright encoder does prefetch, the one frame we requested will not be written until 8881 // the encoder is closed, so do it now rather than in MCS_close 8882 if( ( M4NO_ERROR != err) 8883 || (M4MCS_kEncoderRunning != pC->encoderState) ) 8884 { 8885 M4OSA_TRACE1_2( 8886 "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding " 8887 "returns 0x%X w/ encState=%d", err, pC->encoderState); 8888 8889 return err; 8890 } 8891 8892 /* Stop and close the encoder now to flush the frame (prefetch) */ 8893 if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL ) 8894 { 8895 err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt); 8896 8897 if( M4NO_ERROR != err ) 8898 { 8899 M4OSA_TRACE1_1( 8900 "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X", 8901 err); 8902 return err; 8903 } 8904 } 8905 pC->encoderState = M4MCS_kEncoderStopped; 8906 err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt); 8907 8908 if( M4NO_ERROR != err ) 8909 { 8910 M4OSA_TRACE1_1( 8911 "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X", 8912 err); 8913 return err; 8914 } 8915 pC->encoderState = M4MCS_kEncoderClosed; 8916 } 8917 8918 8919 if( ( pC->bH264Trim == M4OSA_TRUE) 8920 && (pC->bLastDecodedFrameCTS == M4OSA_FALSE) 8921 && (pC->uiBeginCutTime > 0) ) 8922 { 8923 8924 pC->bLastDecodedFrameCTS = M4OSA_TRUE; 8925 err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt, 8926 M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS); 8927 8928 if( M4NO_ERROR != err ) 8929 { 8930 M4OSA_TRACE1_1( 8931 "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!", 8932 err); 8933 return err; 8934 } 8935 8936 err = pC->m_pReader->m_pFctJump(pC->pReaderContext, 8937 (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS); 8938 8939 if( M4NO_ERROR != err ) 8940 { 8941 M4OSA_TRACE1_1( 8942 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!", 8943 err); 8944 return err; 8945 } 8946 8947 8948 /* Initializes an access Unit */ 8949 8950 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 8951 (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); 8952 8953 if( M4NO_ERROR != err ) 8954 { 8955 M4OSA_TRACE1_1( 8956 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 8957 err); 8958 return err; 8959 } 8960 8961 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 8962 (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU); 8963 8964 if( M4WAR_NO_MORE_AU == err ) 8965 { 8966 M4OSA_TRACE2_0( 8967 "M4MCS_intVideoNullEncoding():\ 8968 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 8969 /* The audio transcoding is finished */ 8970 pC->VideoState = M4MCS_kStreamState_FINISHED; 8971 return err; 8972 } 8973 else if( M4NO_ERROR != err ) 8974 { 8975 M4OSA_TRACE1_1( 8976 "M4MCS_intVideoNullEncoding():\ 8977 m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x", 8978 err); 8979 return err; 8980 } 8981 8982 M4OSA_TRACE1_1( 8983 "### [TS_CHECK] M4MCS_intVideoNullEncoding video AU CTS: %d ", 8984 lReaderVideoAU.m_CTS); 8985 8986 8987 } 8988 8989 8990 pC->bLastDecodedFrameCTS = M4OSA_TRUE; 8991 8992 /* - CRLV6775 -H.264 Trimming */ 8993 8994 /* commented,this part is done further on one of the temporary video AU (video AU1 or video AU2)*/ 8995#if 0 8996 /** 8997 * Read the next video AU in the input file */ 8998 8999 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9000 (M4_StreamHandler *)pC->pReaderVideoStream, &pC->ReaderVideoAU); 9001#endif 9002 9003 /* Find the next AU duration to obtain a more precise video end cut*/ 9004 /** 9005 * Initializes a new AU if needed */ 9006 9007 if( pC->ReaderVideoAU1.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->ReaderVideoAU1); 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 9023 pC->m_pDataVideoAddress1 = 9024 (M4OSA_MemAddr8)M4OSA_malloc(pC->ReaderVideoAU1.m_maxsize, M4MCS, 9025 (M4OSA_Char *)"Temporary video AU1 buffer"); 9026 9027 if( pC->m_pDataVideoAddress1 == M4OSA_NULL ) 9028 { 9029 M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); 9030 return M4ERR_ALLOC; 9031 } 9032 9033 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9034 (M4_StreamHandler *)pC->pReaderVideoStream, 9035 &pC->ReaderVideoAU1); 9036 9037 if( M4WAR_NO_MORE_AU == err ) 9038 { 9039 M4OSA_TRACE2_0( 9040 "M4MCS_intVideoNullEncoding():\ 9041 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 9042 /* The audio transcoding is finished */ 9043 pC->VideoState = M4MCS_kStreamState_FINISHED; 9044 return err; 9045 } 9046 else if( M4NO_ERROR != err ) 9047 { 9048 M4OSA_TRACE1_1( 9049 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\ 9050 returns 0x%x", err); 9051 return err; 9052 } 9053 9054 if( pC->ReaderVideoAU1.m_maxsize 9055 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9056 { 9057 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9058 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9059 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); 9060 /* pC->m_pDataVideoAddress1 9061 and pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9062 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9063 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9064 m_basicProperties.m_maxAUSize)" is never true */ 9065 /* and the size of the second buffer is never changed. */ 9066 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9067 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); 9068 /* pC->m_pDataVideoAddress1 and 9069 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9070 /* Update stream properties */ 9071 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9072 pC->ReaderVideoAU1.m_maxsize; 9073 } 9074 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataVideoAddress1, 9075 (M4OSA_MemAddr8)pC->ReaderVideoAU1.m_dataAddress, 9076 pC->ReaderVideoAU1.m_size); 9077 } 9078 9079 if( pC->ReaderVideoAU2.m_structSize == 0 ) 9080 { 9081 /** 9082 * Initializes an access Unit */ 9083 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, 9084 (M4_StreamHandler *)pC->pReaderVideoStream, 9085 &pC->ReaderVideoAU2); 9086 9087 if( M4NO_ERROR != err ) 9088 { 9089 M4OSA_TRACE1_1( 9090 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 9091 err); 9092 return err; 9093 } 9094 pC->m_pDataVideoAddress2 = 9095 (M4OSA_MemAddr8)M4OSA_malloc(pC->ReaderVideoAU2.m_maxsize, M4MCS, 9096 (M4OSA_Char *)"Temporary video AU buffer"); 9097 9098 if( pC->m_pDataVideoAddress2 == M4OSA_NULL ) 9099 { 9100 M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error"); 9101 return M4ERR_ALLOC; 9102 } 9103 } 9104 /** 9105 * Read the next video AU in the input file */ 9106 if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS ) 9107 { 9108 M4OSA_memcpy((M4OSA_MemAddr8) &pC->ReaderVideoAU, 9109 (M4OSA_MemAddr8) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit)); 9110 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9111 (M4_StreamHandler *)pC->pReaderVideoStream, 9112 &pC->ReaderVideoAU1); 9113 9114 if( pC->ReaderVideoAU1.m_maxsize 9115 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9116 { 9117 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9118 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9119 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize); 9120 /* pC->m_pDataVideoAddress1 and 9121 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9122 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9123 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9124 m_basicProperties.m_maxAUSize)" is never true */ 9125 /* and the size of the second buffer is never changed. */ 9126 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9127 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize); 9128 /* pC->m_pDataVideoAddress1 and 9129 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9130 /* Update stream properties */ 9131 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9132 pC->ReaderVideoAU1.m_maxsize; 9133 } 9134 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataVideoAddress1, 9135 (M4OSA_MemAddr8)pC->ReaderVideoAU1.m_dataAddress, 9136 pC->ReaderVideoAU1.m_size); 9137 videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS; 9138 pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2; 9139 } 9140 else 9141 { 9142 M4OSA_memcpy((M4OSA_MemAddr8) &pC->ReaderVideoAU, 9143 (M4OSA_MemAddr8) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit)); 9144 err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, 9145 (M4_StreamHandler *)pC->pReaderVideoStream, 9146 &pC->ReaderVideoAU2); 9147 9148 if( pC->ReaderVideoAU2.m_maxsize 9149 > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize ) 9150 { 9151 /* Constant memory reader case, we need to reallocate the temporary buffers */ 9152 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9153 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize); 9154 /* pC->m_pDataVideoAddress1 and 9155 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9156 /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value. 9157 Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream-> 9158 m_basicProperties.m_maxAUSize)" is never true */ 9159 /* and the size of the second buffer is never changed. */ 9160 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8 9161 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize); 9162 /* pC->m_pDataVideoAddress1 and 9163 pC->m_pDataVideoAddress2 must be reallocated at the same time */ 9164 /* Update stream properties */ 9165 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize = 9166 pC->ReaderVideoAU2.m_maxsize; 9167 } 9168 M4OSA_memcpy((M4OSA_MemAddr8)pC->m_pDataVideoAddress2, 9169 (M4OSA_MemAddr8)pC->ReaderVideoAU2.m_dataAddress, 9170 pC->ReaderVideoAU2.m_size); 9171 videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS; 9172 pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1; 9173 } 9174 9175 if( M4WAR_NO_MORE_AU == err ) 9176 { 9177 M4OSA_TRACE2_0( 9178 "M4MCS_intVideoNullEncoding():\ 9179 m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU"); 9180 /* The video transcoding is finished */ 9181 pC->VideoState = M4MCS_kStreamState_FINISHED; 9182 return err; 9183 } 9184 else if( M4NO_ERROR != err ) 9185 { 9186 M4OSA_TRACE1_1( 9187 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x", 9188 err); 9189 return err; 9190 } 9191 else 9192 { 9193 /** 9194 * Prepare the writer AU */ 9195 err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext, 9196 M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); 9197 9198 if( M4NO_ERROR != err ) 9199 { 9200 M4OSA_TRACE1_1( 9201 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x", 9202 err); 9203 return err; 9204 } 9205#ifdef TIMESCALE_BUG 9206 /* If we are in timescale modification mode or classic copy mode */ 9207 9208 if( pC->uiVideoTimescale != 0 ) 9209 { 9210 /** 9211 * Copy video data from reader AU to writer AU */ 9212 //M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress, 9213 //(M4OSA_MemAddr8)pC->ReaderVideoAU.m_dataAddress, pC->ReaderVideoAU.m_size); 9214 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size; 9215 9216 /* Call internal function to change AU timescale */ 9217 err = M4MCS_intChangeAUVideoTimescale(pC); 9218 9219 /** 9220 * Convert CTS unit from milliseconds to timescale */ 9221 pC->WriterVideoAU.CTS = 9222 (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts) 9223 * (pC->WriterVideoStream.timeScale / 1000.0))); 9224 pC->WriterVideoAU.nbFrag = 0; 9225 pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute; 9226 } 9227 else 9228 9229#endif 9230 9231 { 9232 /** 9233 * Copy video data from reader AU to writer AU */ 9234 M4OSA_TRACE3_1( 9235 "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d", 9236 pC->ReaderVideoAU.m_size); 9237 /* + CRLV6775 -H.264 Trimming */ 9238 if( M4OSA_TRUE == pC->bH264Trim ) 9239 { 9240 if( pC->H264MCSTempBufferSize 9241 < (pC->ReaderVideoAU.m_size + 2048) ) 9242 { 9243 pC->H264MCSTempBufferSize = 9244 (pC->ReaderVideoAU.m_size + 2048); 9245 9246 if( pC->H264MCSTempBuffer != M4OSA_NULL ) 9247 { 9248 M4OSA_free((M4OSA_MemAddr32)pC->H264MCSTempBuffer); 9249 } 9250 pC->H264MCSTempBuffer = 9251 (M4OSA_UInt8 *)M4OSA_malloc(pC->H264MCSTempBufferSize, 9252 M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer"); 9253 9254 if( pC->H264MCSTempBuffer == M4OSA_NULL ) 9255 { 9256 M4OSA_TRACE1_0( 9257 "M4MCS_intVideoNullEncoding(): allocation error"); 9258 return M4ERR_ALLOC; 9259 } 9260 } 9261 9262 pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize; 9263 9264 err = H264MCS_ProcessNALU(pC->m_pInstance, 9265 (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress, 9266 pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer, 9267 (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize); 9268 9269 if( pC->m_pInstance->is_done == 1 ) 9270 { 9271 M4MCS_convetFromByteStreamtoNALStream( 9272 (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress , 9273 pC->ReaderVideoAU.m_size); 9274 9275 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress, 9276 (M4OSA_MemAddr8)(pC->ReaderVideoAU.m_dataAddress + 4), 9277 pC->ReaderVideoAU.m_size - 4); 9278 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4; 9279 WritebufferAdd = 9280 (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; 9281 } 9282 else 9283 { 9284 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress, 9285 (M4OSA_MemAddr8)(pC->H264MCSTempBuffer + 4), 9286 pC->H264MCSTempBufferDataSize - 4); 9287 pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4; 9288 WritebufferAdd = 9289 (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress; 9290 } 9291 } 9292 /* H.264 Trimming */ 9293 else 9294 { 9295 M4OSA_memcpy((M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress, 9296 (M4OSA_MemAddr8)pC->ReaderVideoAU.m_dataAddress, 9297 pC->ReaderVideoAU.m_size); 9298 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size; 9299 } 9300 /** 9301 * Convert CTS unit from milliseconds to timescale */ 9302 pC->WriterVideoAU.CTS = 9303 (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts) 9304 * (pC->WriterVideoStream.timeScale / 1000.0))); 9305 pC->WriterVideoAU.nbFrag = 0; 9306 pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute; 9307 9308 M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms", 9309 pC->WriterVideoAU.CTS); 9310 } 9311 9312 /** 9313 * Write it to the output file */ 9314 pC->uiVideoAUCount++; 9315 err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext, 9316 M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU); 9317 9318 if( M4NO_ERROR != err ) 9319 { 9320 M4OSA_TRACE1_1( 9321 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x", 9322 err); 9323 return err; 9324 } 9325 /* + CRLV6775 -H.264 Trimming */ 9326 if( M4OSA_TRUE == pC->bH264Trim ) 9327 { 9328 if( pC->m_pInstance->is_done == 1 ) 9329 { 9330 M4OSA_memcpy((M4OSA_MemAddr8)(WritebufferAdd - 4), 9331 (M4OSA_MemAddr8)(pC->ReaderVideoAU.m_dataAddress), 4); 9332 } 9333 else 9334 { 9335 M4OSA_memcpy((M4OSA_MemAddr8)(WritebufferAdd - 4), 9336 (M4OSA_MemAddr8)(pC->H264MCSTempBuffer), 4); 9337 } 9338 } /* H.264 Trimming */ 9339 } 9340 /** 9341 * Check for end cut. */ 9342 /* Bug fix 11/12/2008: We absolutely want to have less or same video duration -> 9343 (2*videoAUDuration) to have a more precise end cut*/ 9344 if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime ) 9345 { 9346 pC->VideoState = M4MCS_kStreamState_FINISHED; 9347 } 9348 9349 /** 9350 * Return with no error */ 9351 M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR"); 9352 return M4NO_ERROR; 9353} 9354 9355/** 9356 ****************************************************************************** 9357 * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC) 9358 * @author Alexis Vapillon (NXP Software Vision) 9359 * @return M4NO_ERROR: No error 9360 ****************************************************************************** 9361 */ 9362static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC ) 9363{ 9364 M4OSA_ERR err = M4NO_ERROR; 9365 M4_MediaTime mtTranscodedTime = 0.0; 9366 M4ENCODER_FrameMode FrameMode; 9367 M4OSA_Int32 derive = 0; 9368 9369 /** 9370 * Get video CTS to decode */ 9371 mtTranscodedTime = pC->dViDecCurrentCts; 9372 FrameMode = M4ENCODER_kNormalFrame; 9373 9374 /** 9375 * Decode video */ 9376 M4OSA_TRACE3_1( 9377 "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)", 9378 mtTranscodedTime); 9379 pC->isRenderDup = M4OSA_FALSE; 9380 err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime, 9381 M4OSA_FALSE); 9382 9383 if( M4WAR_NO_MORE_AU == err ) 9384 { 9385 FrameMode = 9386 M4ENCODER_kLastFrame; /**< We will give this value to the encoder to 9387 ask for the end of the encoding */ 9388 pC->VideoState = M4MCS_kStreamState_FINISHED; 9389 } 9390 else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 9391 { 9392 M4OSA_TRACE2_0("Decoding output the same frame as before 3"); 9393 pC->isRenderDup = M4OSA_TRUE; 9394 } 9395 else if( M4NO_ERROR != err ) 9396 { 9397 M4OSA_TRACE1_1( 9398 "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!", 9399 err); 9400 return err; 9401 } 9402 9403 /** 9404 * Check for end cut. 9405 * We must check here if the end cut is reached, because in that case we must 9406 * call the last encode step (-> bLastFrame set to true) */ 9407 if( ( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5) >= (pC->uiEndCutTime 9408 + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) ) 9409 { 9410 FrameMode = 9411 M4ENCODER_kLastFrame; /**< We will give this value to the encoder to 9412 ask for the end of the encoding */ 9413 pC->VideoState = M4MCS_kStreamState_FINISHED; 9414 derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5) 9415 - (pC->uiEndCutTime 9416 + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime))); 9417 } 9418 9419 /* Update starting CTS to have a more precise value ( 9420 the begin cut is not a real CTS)*/ 9421 if( pC->uiVideoAUCount == 0 ) 9422 { 9423 pC->dViDecStartingCts = mtTranscodedTime; 9424 pC->dViDecCurrentCts = pC->dViDecStartingCts; 9425 } 9426 9427 /** 9428 * Encode video */ 9429 M4OSA_TRACE3_1( 9430 "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\ 9431 = %.2f",pC->ReaderVideoAU.m_CTS); 9432 pC->uiVideoAUCount++; 9433 /* update the given duration (the begin cut is not a real CTS)*/ 9434 err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL, 9435 (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)), 9436 FrameMode); 9437 9438 return err; 9439} 9440 9441/** 9442 ****************************************************************************** 9443 * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext) 9444 * @author Dounya Manai (NXP Software Vision) 9445 * @brief Retrieve the properties of the audio and video streams from the input file. 9446 * @param pContext (IN) MCS context 9447 * @return M4NO_ERROR: No error 9448 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (If Debug Level >= 2) 9449 ****************************************************************************** 9450 */ 9451static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC ) 9452{ 9453 M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo; 9454 M4READER_3GP_H263Properties H263prop; 9455 M4OSA_ERR err; 9456 M4OSA_UInt32 videoBitrate; 9457 M4DECODER_AVCProfileLevel AVCProfle; 9458#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 9459 9460 M4DECODER_VideoSize videoSize; 9461 9462#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 9463 9464 M4_AACType iAacType = 0; 9465 9466 /** 9467 * Check input parameters */ 9468 M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER, 9469 "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL"); 9470 9471 /** 9472 * Reset common characteristics */ 9473 pC->InputFileProperties.bAnalysed = M4OSA_FALSE; 9474 pC->InputFileProperties.FileType = 0; 9475 pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR; 9476 pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR; 9477 pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION; 9478 pC->InputFileProperties.uiClipDuration = 0; 9479 9480 M4OSA_memset((M4OSA_MemAddr8) &pC->InputFileProperties.ftyp, 9481 sizeof(M4VIDEOEDITING_FtypBox), 0); 9482 9483 /** 9484 * Reset video characteristics */ 9485 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; 9486 pC->InputFileProperties.uiClipVideoDuration = 0; 9487 pC->InputFileProperties.uiVideoBitrate = 0; 9488 pC->InputFileProperties.uiVideoMaxAuSize = 0; 9489 pC->InputFileProperties.uiVideoWidth = 0; 9490 pC->InputFileProperties.uiVideoHeight = 0; 9491 pC->InputFileProperties.uiVideoTimeScale = 0; 9492 pC->InputFileProperties.fAverageFrameRate = 0.0; 9493 pC->InputFileProperties.ProfileAndLevel = 9494 M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range; 9495 pC->InputFileProperties.uiH263level = 0; 9496 pC->InputFileProperties.uiVideoProfile = 0; 9497 pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE; 9498 pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE; 9499 pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE; 9500 9501 /** 9502 * Reset audio characteristics */ 9503 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; 9504 pC->InputFileProperties.uiClipAudioDuration = 0; 9505 pC->InputFileProperties.uiAudioBitrate = 0; 9506 pC->InputFileProperties.uiAudioMaxAuSize = 0; 9507 pC->InputFileProperties.uiNbChannels = 0; 9508 pC->InputFileProperties.uiSamplingFrequency = 0; 9509 pC->InputFileProperties.uiExtendedSamplingFrequency = 0; 9510 pC->InputFileProperties.uiDecodedPcmSize = 0; 9511 9512 /* Reset compatibility chart (not used in MCS) */ 9513 pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE; 9514 pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE; 9515 pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE; 9516 pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; 9517 9518 /** 9519 * Video stream properties */ 9520 if( M4OSA_NULL != pC->pReaderVideoStream ) 9521 { 9522 switch( pC->pReaderVideoStream->m_basicProperties.m_streamType ) 9523 { 9524 case M4DA_StreamTypeVideoMpeg4: 9525 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4; 9526 break; 9527 9528 case M4DA_StreamTypeVideoH263: 9529 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263; 9530 break; 9531 9532 case M4DA_StreamTypeVideoMpeg4Avc: 9533 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264; 9534 break; 9535 9536 case M4DA_StreamTypeUnknown: 9537 default: 9538 pC->InputFileProperties.VideoStreamType = 9539 M4VIDEOEDITING_kUnsupportedVideo; 9540 break; 9541 } 9542 9543 /* if bitrate not available retrieve an estimation of the overall bitrate */ 9544 pC->InputFileProperties.uiVideoBitrate = 9545 pC->pReaderVideoStream->m_basicProperties.m_averageBitRate; 9546 9547 if( 0 == pC->InputFileProperties.uiVideoBitrate ) 9548 { 9549 pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 9550 M4READER_kOptionID_Bitrate, &videoBitrate); 9551 9552 if( M4OSA_NULL != pC->pReaderAudioStream ) 9553 { 9554 /* we get the overall bitrate, substract the audio bitrate if any */ 9555 videoBitrate -= 9556 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; 9557 } 9558 pC->InputFileProperties.uiVideoBitrate = videoBitrate; 9559 } 9560 9561 /** 9562 * Retrieve the Profile & Level */ 9563 if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType) 9564 && (M4VIDEOEDITING_kH264 9565 != pC->InputFileProperties.VideoStreamType) ) 9566 { 9567#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 9568 /* Use the DSI parsing function from the external video shell decoder. 9569 See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the 9570 same issue. */ 9571 9572 err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream-> 9573 m_basicProperties.m_pDecoderSpecificInfo, 9574 pC->pReaderVideoStream-> 9575 m_basicProperties.m_decoderSpecificInfoSize, 9576 &DecConfInfo, &videoSize); 9577 9578 if( M4NO_ERROR != err ) 9579 { 9580 M4OSA_TRACE1_1( 9581 "M4MCS_intGetInputClipProperties():\ 9582 M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", 9583 err); 9584 return err; 9585 } 9586 9587 pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth; 9588 pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight; 9589 9590#else 9591 /*FB 2009-02-09: add a check on the video decoder context to 9592 avoid crash when the MCS is used only with audio codecs compilated*/ 9593 9594 if( pC->m_pVideoDecoder != M4OSA_NULL ) 9595 { 9596 if( M4OSA_NULL == pC->pViDecCtxt ) 9597 { 9598 err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt, 9599 &pC->pReaderVideoStream->m_basicProperties, 9600 pC->m_pReaderDataIt, &pC->ReaderVideoAU, 9601 M4OSA_NULL); 9602 9603 if( M4NO_ERROR != err ) 9604 { 9605 M4OSA_TRACE1_1( 9606 "M4MCS_intGetInputClipProperties:\ 9607 m_pVideoDecoder->m_pFctCreate returns 0x%x!", 9608 err); 9609 return err; 9610 } 9611 } 9612 9613 err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt, 9614 M4DECODER_MPEG4_kOptionID_DecoderConfigInfo, 9615 &DecConfInfo); 9616 9617 if( M4NO_ERROR != err ) 9618 { 9619 M4OSA_TRACE1_1( 9620 "M4MCS_intGetInputClipProperties:\ 9621 m_pVideoDecoder->m_pFctGetOption returns 0x%x!", 9622 err); 9623 return err; 9624 } 9625 } 9626 9627#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 9628 9629 pC->InputFileProperties.uiVideoProfile = DecConfInfo.uiProfile; 9630 pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale; 9631 pC->InputFileProperties.bMPEG4dataPartition = 9632 DecConfInfo.bDataPartition; 9633 pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC; 9634 pC->InputFileProperties.bMPEG4resynchMarker = 9635 DecConfInfo.uiUseOfResynchMarker; 9636 9637 /* Supported enum value for profile and level */ 9638 switch( pC->InputFileProperties.uiVideoProfile ) 9639 { 9640 case 0x08: 9641 pC->InputFileProperties.ProfileAndLevel = 9642 M4VIDEOEDITING_kMPEG4_SP_Level_0; 9643 break; 9644 9645 case 0x09: 9646 pC->InputFileProperties.ProfileAndLevel = 9647 M4VIDEOEDITING_kMPEG4_SP_Level_0b; 9648 break; 9649 9650 case 0x01: 9651 pC->InputFileProperties.ProfileAndLevel = 9652 M4VIDEOEDITING_kMPEG4_SP_Level_1; 9653 break; 9654 9655 case 0x02: 9656 pC->InputFileProperties.ProfileAndLevel = 9657 M4VIDEOEDITING_kMPEG4_SP_Level_2; 9658 break; 9659 9660 case 0x03: 9661 pC->InputFileProperties.ProfileAndLevel = 9662 M4VIDEOEDITING_kMPEG4_SP_Level_3; 9663 break; 9664 9665 case 0x04: 9666 pC->InputFileProperties.ProfileAndLevel = 9667 M4VIDEOEDITING_kMPEG4_SP_Level_4a; 9668 break; 9669 9670 case 0x05: 9671 pC->InputFileProperties.ProfileAndLevel = 9672 M4VIDEOEDITING_kMPEG4_SP_Level_5; 9673 break; 9674 } 9675 } 9676 else if( M4VIDEOEDITING_kH263 9677 == pC->InputFileProperties.VideoStreamType ) 9678 { 9679 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 9680 M4READER_3GP_kOptionID_H263Properties, &H263prop); 9681 9682 if( M4NO_ERROR != err ) 9683 { 9684 M4OSA_TRACE1_1( 9685 "M4MCS_intGetInputClipProperties: m_pReader->m_pFctGetOption returns 0x%x!", 9686 err); 9687 return err; 9688 } 9689 9690 pC->InputFileProperties.uiH263level = H263prop.uiLevel; 9691 pC->InputFileProperties.uiVideoProfile = H263prop.uiProfile; 9692 9693 /* Supported enum value for profile and level */ 9694 if( pC->InputFileProperties.uiVideoProfile == 0 ) 9695 { 9696 switch( pC->InputFileProperties.uiH263level ) 9697 { 9698 case 10: 9699 pC->InputFileProperties.ProfileAndLevel = 9700 M4VIDEOEDITING_kH263_Profile_0_Level_10; 9701 break; 9702 9703 case 20: 9704 pC->InputFileProperties.ProfileAndLevel = 9705 M4VIDEOEDITING_kH263_Profile_0_Level_20; 9706 break; 9707 9708 case 30: 9709 pC->InputFileProperties.ProfileAndLevel = 9710 M4VIDEOEDITING_kH263_Profile_0_Level_30; 9711 break; 9712 9713 case 40: 9714 pC->InputFileProperties.ProfileAndLevel = 9715 M4VIDEOEDITING_kH263_Profile_0_Level_40; 9716 break; 9717 9718 case 45: 9719 pC->InputFileProperties.ProfileAndLevel = 9720 M4VIDEOEDITING_kH263_Profile_0_Level_45; 9721 break; 9722 } 9723 } 9724 9725 /* For h263 set default timescale : 30000:1001 */ 9726 pC->InputFileProperties.uiVideoTimeScale = 30000; 9727 } 9728 else if( M4VIDEOEDITING_kH264 9729 == pC->InputFileProperties.VideoStreamType ) 9730 { 9731 AVCProfle = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 9732 pC->InputFileProperties.uiVideoTimeScale = 30000; 9733#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 9734 9735 err = M4DECODER_EXTERNAL_ParseAVCDSI(pC->pReaderVideoStream-> 9736 m_basicProperties.m_pDecoderSpecificInfo, 9737 pC->pReaderVideoStream-> 9738 m_basicProperties.m_decoderSpecificInfoSize, 9739 &AVCProfle); 9740 9741 if( M4NO_ERROR != err ) 9742 { 9743 M4OSA_TRACE1_1( 9744 "M4MCS_intGetInputClipProperties():\ 9745 M4DECODER_EXTERNAL_ParseAVCDSI returns 0x%08X", 9746 err); 9747 return err; 9748 } 9749 9750#else 9751 9752 if( pC->m_pVideoDecoder != M4OSA_NULL ) 9753 { 9754 if( M4OSA_NULL == pC->pViDecCtxt ) 9755 { 9756 err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt, 9757 &pC->pReaderVideoStream->m_basicProperties, 9758 pC->m_pReaderDataIt, &pC->ReaderVideoAU, 9759 M4OSA_NULL); 9760 9761 if( M4NO_ERROR != err ) 9762 { 9763 M4OSA_TRACE1_1( 9764 "M4MCS_intGetInputClipProperties:\ 9765 m_pVideoDecoder->m_pFctCreate returns 0x%x!", 9766 err); 9767 return err; 9768 } 9769 } 9770 err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt, 9771 M4DECODER_kOptionID_AVCProfileAndLevel, &AVCProfle); 9772 9773 if( M4NO_ERROR != err ) 9774 { 9775 M4OSA_TRACE1_1( 9776 "M4MCS_intGetInputClipProperties:\ 9777 m_pVideoDecoder->m_pFctGetOption returns 0x%x!", 9778 err); 9779 return err; 9780 } 9781 } 9782 9783#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 9784 9785 switch( AVCProfle ) 9786 { 9787 case M4DECODER_AVC_kProfile_0_Level_1: 9788 pC->InputFileProperties.ProfileAndLevel = 9789 M4VIDEOEDITING_kH264_Profile_0_Level_1; 9790 break; 9791 9792 case M4DECODER_AVC_kProfile_0_Level_1b: 9793 pC->InputFileProperties.ProfileAndLevel = 9794 M4VIDEOEDITING_kH264_Profile_0_Level_1b; 9795 break; 9796 9797 case M4DECODER_AVC_kProfile_0_Level_1_1: 9798 pC->InputFileProperties.ProfileAndLevel = 9799 M4VIDEOEDITING_kH264_Profile_0_Level_1_1; 9800 break; 9801 9802 case M4DECODER_AVC_kProfile_0_Level_1_2: 9803 pC->InputFileProperties.ProfileAndLevel = 9804 M4VIDEOEDITING_kH264_Profile_0_Level_1_2; 9805 break; 9806 9807 case M4DECODER_AVC_kProfile_0_Level_1_3: 9808 pC->InputFileProperties.ProfileAndLevel = 9809 M4VIDEOEDITING_kH264_Profile_0_Level_1_3; 9810 break; 9811 9812 case M4DECODER_AVC_kProfile_0_Level_2: 9813 pC->InputFileProperties.ProfileAndLevel = 9814 M4VIDEOEDITING_kH264_Profile_0_Level_2; 9815 break; 9816 9817 case M4DECODER_AVC_kProfile_0_Level_2_1: 9818 pC->InputFileProperties.ProfileAndLevel = 9819 M4VIDEOEDITING_kH264_Profile_0_Level_2_1; 9820 break; 9821 9822 case M4DECODER_AVC_kProfile_0_Level_2_2: 9823 pC->InputFileProperties.ProfileAndLevel = 9824 M4VIDEOEDITING_kH264_Profile_0_Level_2_2; 9825 break; 9826 9827 case M4DECODER_AVC_kProfile_0_Level_3: 9828 pC->InputFileProperties.ProfileAndLevel = 9829 M4VIDEOEDITING_kH264_Profile_0_Level_3; 9830 break; 9831 9832 case M4DECODER_AVC_kProfile_0_Level_3_1: 9833 pC->InputFileProperties.ProfileAndLevel = 9834 M4VIDEOEDITING_kH264_Profile_0_Level_3_1; 9835 break; 9836 9837 case M4DECODER_AVC_kProfile_0_Level_3_2: 9838 pC->InputFileProperties.ProfileAndLevel = 9839 M4VIDEOEDITING_kH264_Profile_0_Level_3_2; 9840 break; 9841 9842 case M4DECODER_AVC_kProfile_0_Level_4: 9843 pC->InputFileProperties.ProfileAndLevel = 9844 M4VIDEOEDITING_kH264_Profile_0_Level_4; 9845 break; 9846 9847 case M4DECODER_AVC_kProfile_0_Level_4_1: 9848 pC->InputFileProperties.ProfileAndLevel = 9849 M4VIDEOEDITING_kH264_Profile_0_Level_4_1; 9850 break; 9851 9852 case M4DECODER_AVC_kProfile_0_Level_4_2: 9853 pC->InputFileProperties.ProfileAndLevel = 9854 M4VIDEOEDITING_kH264_Profile_0_Level_4_2; 9855 break; 9856 9857 case M4DECODER_AVC_kProfile_0_Level_5: 9858 pC->InputFileProperties.ProfileAndLevel = 9859 M4VIDEOEDITING_kH264_Profile_0_Level_5; 9860 break; 9861 9862 case M4DECODER_AVC_kProfile_0_Level_5_1: 9863 pC->InputFileProperties.ProfileAndLevel = 9864 M4VIDEOEDITING_kH264_Profile_0_Level_5_1; 9865 break; 9866 9867 case M4DECODER_AVC_kProfile_and_Level_Out_Of_Range: 9868 default: 9869 pC->InputFileProperties.ProfileAndLevel = 9870 M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range; 9871 } 9872 } 9873 9874 /* Here because width x height is correct only after dsi parsing 9875 (done in create decoder) */ 9876 pC->InputFileProperties.uiVideoHeight = 9877 pC->pReaderVideoStream->m_videoHeight; 9878 pC->InputFileProperties.uiVideoWidth = 9879 pC->pReaderVideoStream->m_videoWidth; 9880 pC->InputFileProperties.uiClipVideoDuration = 9881 (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration; 9882 pC->InputFileProperties.fAverageFrameRate = 9883 pC->pReaderVideoStream->m_averageFrameRate; 9884 pC->InputFileProperties.uiVideoMaxAuSize = 9885 pC->pReaderVideoStream->m_basicProperties.m_maxAUSize; 9886 } 9887 else 9888 { 9889 if( M4OSA_TRUE == pC->bUnsupportedVideoFound ) 9890 { 9891 pC->InputFileProperties.VideoStreamType = 9892 M4VIDEOEDITING_kUnsupportedVideo; 9893 } 9894 else 9895 { 9896 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; 9897 } 9898 } 9899 9900 /** 9901 * Audio stream properties */ 9902 if( M4OSA_NULL != pC->pReaderAudioStream ) 9903 { 9904 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType ) 9905 { 9906 case M4DA_StreamTypeAudioAmrNarrowBand: 9907 pC->InputFileProperties.AudioStreamType = 9908 M4VIDEOEDITING_kAMR_NB; 9909 break; 9910 9911 case M4DA_StreamTypeAudioAac: 9912 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC; 9913 break; 9914 9915 case M4DA_StreamTypeAudioMp3: 9916 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3; 9917 break; 9918 9919 case M4DA_StreamTypeAudioEvrc: 9920 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC; 9921 break; 9922 9923 case M4DA_StreamTypeUnknown: 9924 default: 9925 pC->InputFileProperties.AudioStreamType = 9926 M4VIDEOEDITING_kUnsupportedAudio; 9927 break; 9928 } 9929 9930 if( ( M4OSA_NULL != pC->m_pAudioDecoder) 9931 && (M4OSA_NULL == pC->pAudioDecCtxt) ) 9932 { 9933 M4OSA_TRACE3_1( 9934 "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x", 9935 pC->m_pCurrentAudioDecoderUserData); 9936 /* Trick, I use pUserData to retrieve aac properties, waiting for some 9937 better implementation... */ 9938 if( M4DA_StreamTypeAudioAac 9939 == pC->pReaderAudioStream->m_basicProperties.m_streamType ) 9940 { 9941 if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) 9942 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 9943 &pC->pAudioDecCtxt, 9944 pC->pReaderAudioStream, &(pC->AacProperties)); 9945 else 9946 { 9947 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 9948 &pC->pAudioDecCtxt, pC->pReaderAudioStream, 9949 pC->m_pCurrentAudioDecoderUserData); 9950 9951 if( M4NO_ERROR == err ) 9952 { 9953 /* AAC properties*/ 9954 //get from Reader; temporary, till Audio decoder shell API available to 9955 //get the AAC properties 9956 pC->AacProperties.aNumChan = 9957 pC->pReaderAudioStream->m_nbChannels; 9958 pC->AacProperties.aSampFreq = 9959 pC->pReaderAudioStream->m_samplingFrequency; 9960 9961 err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec( 9962 pC->pAudioDecCtxt, M4AD_kOptionID_StreamType, 9963 (M4OSA_DataOption) &iAacType); 9964 9965 if( M4NO_ERROR != err ) 9966 { 9967 M4OSA_TRACE1_1( 9968 "M4MCS_intGetInputClipProperties:\ 9969 m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", 9970 err); 9971 iAacType = M4_kAAC; //set to default 9972 err = M4NO_ERROR; 9973 } 9974 else 9975 { 9976 M4OSA_TRACE3_1( 9977 "M4MCS_intGetInputClipProperties:\ 9978 m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d", 9979 iAacType); 9980 } 9981 9982 switch( iAacType ) 9983 { 9984 case M4_kAAC: 9985 pC->AacProperties.aSBRPresent = 0; 9986 pC->AacProperties.aPSPresent = 0; 9987 break; 9988 9989 case M4_kAACplus: 9990 pC->AacProperties.aSBRPresent = 1; 9991 pC->AacProperties.aPSPresent = 0; 9992 pC->AacProperties.aExtensionSampFreq = 9993 pC->pReaderAudioStream-> 9994 m_samplingFrequency; //TODO 9995 break; 9996 9997 case M4_keAACplus: 9998 pC->AacProperties.aSBRPresent = 1; 9999 pC->AacProperties.aPSPresent = 1; 10000 pC->AacProperties.aExtensionSampFreq = 10001 pC->pReaderAudioStream-> 10002 m_samplingFrequency; //TODO 10003 break; 10004 case M4_kUnknown: 10005 break; 10006 default: 10007 break; 10008 } 10009 M4OSA_TRACE3_2( 10010 "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d", 10011 pC->AacProperties.aNumChan, 10012 pC->AacProperties.aSampFreq); 10013 } 10014 } 10015 } 10016 else 10017 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( 10018 &pC->pAudioDecCtxt, pC->pReaderAudioStream, 10019 pC->m_pCurrentAudioDecoderUserData); 10020 10021 if( M4NO_ERROR != err ) 10022 { 10023 M4OSA_TRACE1_1( 10024 "M4MCS_intGetInputClipProperties:\ 10025 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 10026 err); 10027 return err; 10028 } 10029 } 10030 10031 //EVRC 10032 if( pC->pReaderAudioStream->m_basicProperties.m_streamType 10033 == M4DA_StreamTypeAudioEvrc ) 10034 { 10035 /* decoder not implemented yet, provide some default values for the null encoding */ 10036 pC->pReaderAudioStream->m_nbChannels = 1; 10037 pC->pReaderAudioStream->m_samplingFrequency = 8000; 10038 } 10039 10040 /** 10041 * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according 10042 the GetProperties function */ 10043 if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate ) 10044 { 10045 if( M4VIDEOEDITING_kAMR_NB 10046 == pC->InputFileProperties.AudioStreamType ) 10047 { 10048 /** 10049 * Better returning a guessed 12.2 kbps value than a sure-to-be-false 10050 0 kbps value! */ 10051 pC->InputFileProperties.uiAudioBitrate = 10052 M4VIDEOEDITING_k12_2_KBPS; 10053 } 10054 else if( M4VIDEOEDITING_kEVRC 10055 == pC->InputFileProperties.AudioStreamType ) 10056 { 10057 /** 10058 * Better returning a guessed 8.5 kbps value than a sure-to-be-false 10059 0 kbps value! */ 10060 pC->InputFileProperties.uiAudioBitrate = 10061 M4VIDEOEDITING_k9_2_KBPS; 10062 } 10063 else 10064 { 10065 M4OSA_UInt32 FileBitrate; 10066 10067 /* Can happen also for aac, in this case we calculate an approximative */ 10068 /* value from global bitrate and video bitrate */ 10069 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 10070 M4READER_kOptionID_Bitrate, 10071 (M4OSA_DataOption) &FileBitrate); 10072 10073 if( M4NO_ERROR != err ) 10074 { 10075 M4OSA_TRACE1_1( 10076 "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x", 10077 err); 10078 return err; 10079 } 10080 pC->InputFileProperties.uiAudioBitrate = 10081 FileBitrate 10082 - pC-> 10083 InputFileProperties. 10084 uiVideoBitrate /* normally setted to 0, if no video */; 10085 } 10086 } 10087 else 10088 { 10089 pC->InputFileProperties.uiAudioBitrate = 10090 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate; 10091 } 10092 10093 pC->InputFileProperties.uiNbChannels = 10094 pC->pReaderAudioStream->m_nbChannels; 10095 pC->InputFileProperties.uiSamplingFrequency = 10096 pC->pReaderAudioStream->m_samplingFrequency; 10097 pC->InputFileProperties.uiClipAudioDuration = 10098 (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration; 10099 pC->InputFileProperties.uiAudioMaxAuSize = 10100 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize; 10101 10102 /* Bug: with aac, value is 0 until decoder start() is called */ 10103 pC->InputFileProperties.uiDecodedPcmSize = 10104 pC->pReaderAudioStream->m_byteFrameLength 10105 * pC->pReaderAudioStream->m_byteSampleSize 10106 * pC->pReaderAudioStream->m_nbChannels; 10107 10108 /* New aac properties */ 10109 if( M4DA_StreamTypeAudioAac 10110 == pC->pReaderAudioStream->m_basicProperties.m_streamType ) 10111 { 10112 pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan; 10113 pC->InputFileProperties.uiSamplingFrequency = 10114 pC->AacProperties.aSampFreq; 10115 10116 if( pC->AacProperties.aSBRPresent ) 10117 { 10118 pC->InputFileProperties.AudioStreamType = 10119 M4VIDEOEDITING_kAACplus; 10120 pC->InputFileProperties.uiExtendedSamplingFrequency = 10121 pC->AacProperties.aExtensionSampFreq; 10122 } 10123 10124 if( pC->AacProperties.aPSPresent ) 10125 { 10126 pC->InputFileProperties.AudioStreamType = 10127 M4VIDEOEDITING_keAACplus; 10128 } 10129 } 10130 } 10131 else 10132 { 10133 if( M4OSA_TRUE == pC->bUnsupportedAudioFound ) 10134 { 10135 pC->InputFileProperties.AudioStreamType = 10136 M4VIDEOEDITING_kUnsupportedAudio; 10137 } 10138 else 10139 { 10140 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; 10141 } 10142 } 10143 10144 /* Get 'ftyp' atom */ 10145 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext, 10146 M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp); 10147 10148 if( M4NO_ERROR == err ) 10149 { 10150 M4OSA_UInt8 i; 10151 10152 for ( i = 0; i < pC->InputFileProperties.ftyp.nbCompatibleBrands; i++ ) 10153 if( M4VIDEOEDITING_BRAND_EMP 10154 == pC->InputFileProperties.ftyp.compatible_brands[i] ) 10155 pC->InputFileProperties.VideoStreamType = 10156 M4VIDEOEDITING_kMPEG4_EMP; 10157 } 10158 10159 /* Analysis is successful */ 10160 if( pC->InputFileProperties.uiClipVideoDuration 10161 > pC->InputFileProperties.uiClipAudioDuration ) 10162 pC->InputFileProperties.uiClipDuration = 10163 pC->InputFileProperties.uiClipVideoDuration; 10164 else 10165 pC->InputFileProperties.uiClipDuration = 10166 pC->InputFileProperties.uiClipAudioDuration; 10167 10168 pC->InputFileProperties.FileType = pC->InputFileType; 10169 pC->InputFileProperties.bAnalysed = M4OSA_TRUE; 10170 10171 return M4NO_ERROR; 10172} 10173 10174/** 10175 ****************************************************************************** 10176 * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame) 10177 * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer 10178 * @note 10179 * @param pCpAudioFrame (IN) AMRNB frame 10180 * @return M4NO_ERROR: No error 10181 ****************************************************************************** 10182 */ 10183static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame ) 10184{ 10185 M4OSA_UInt32 frameSize = 0; 10186 M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3; 10187 10188 switch( frameType ) 10189 { 10190 case 0: 10191 frameSize = 95; 10192 break; /* 4750 bps */ 10193 10194 case 1: 10195 frameSize = 103; 10196 break; /* 5150 bps */ 10197 10198 case 2: 10199 frameSize = 118; 10200 break; /* 5900 bps */ 10201 10202 case 3: 10203 frameSize = 134; 10204 break; /* 6700 bps */ 10205 10206 case 4: 10207 frameSize = 148; 10208 break; /* 7400 bps */ 10209 10210 case 5: 10211 frameSize = 159; 10212 break; /* 7950 bps */ 10213 10214 case 6: 10215 frameSize = 204; 10216 break; /* 10200 bps */ 10217 10218 case 7: 10219 frameSize = 244; 10220 break; /* 12000 bps */ 10221 10222 case 8: 10223 frameSize = 39; 10224 break; /* SID (Silence) */ 10225 10226 case 15: 10227 frameSize = 0; 10228 break; /* No data */ 10229 10230 default: 10231 M4OSA_TRACE3_0( 10232 "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0."); 10233 return 0; 10234 } 10235 10236 return (1 + (( frameSize + 7) / 8)); 10237} 10238 10239/** 10240 ****************************************************************************** 10241 * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame) 10242 * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer 10243 * @note 10244 * 0 1 2 3 10245 * +-+-+-+-+ 10246 * |fr type| RFC 3558 10247 * +-+-+-+-+ 10248 * 10249 * Frame Type: 4 bits 10250 * The frame type indicates the type of the corresponding codec data 10251 * frame in the RTP packet. 10252 * 10253 * For EVRC and SMV codecs, the frame type values and size of the 10254 * associated codec data frame are described in the table below: 10255 * 10256 * Value Rate Total codec data frame size (in octets) 10257 * --------------------------------------------------------- 10258 * 0 Blank 0 (0 bit) 10259 * 1 1/8 2 (16 bits) 10260 * 2 1/4 5 (40 bits; not valid for EVRC) 10261 * 3 1/2 10 (80 bits) 10262 * 4 1 22 (171 bits; 5 padded at end with zeros) 10263 * 5 Erasure 0 (SHOULD NOT be transmitted by sender) 10264 * 10265 * @param pCpAudioFrame (IN) EVRC frame 10266 * @return M4NO_ERROR: No error 10267 ****************************************************************************** 10268 */ 10269static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) 10270{ 10271 M4OSA_UInt32 frameSize = 0; 10272 M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F; 10273 10274 switch( frameType ) 10275 { 10276 case 0: 10277 frameSize = 0; 10278 break; /* blank */ 10279 10280 case 1: 10281 frameSize = 16; 10282 break; /* 1/8 */ 10283 10284 case 2: 10285 frameSize = 40; 10286 break; /* 1/4 */ 10287 10288 case 3: 10289 frameSize = 80; 10290 break; /* 1/2 */ 10291 10292 case 4: 10293 frameSize = 171; 10294 break; /* 1 */ 10295 10296 case 5: 10297 frameSize = 0; 10298 break; /* erasure */ 10299 10300 default: 10301 M4OSA_TRACE3_0( 10302 "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0."); 10303 return 0; 10304 } 10305 10306 return (1 + (( frameSize + 7) / 8)); 10307} 10308 10309/** 10310 ****************************************************************************** 10311 * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext) 10312 * @brief Check if max file size is greater enough to encode a file with the 10313 * current selected bitrates and duration. 10314 * @param pContext (IN) MCS context 10315 * @return M4NO_ERROR 10316 * @return M4MCS_ERR_MAXFILESIZE_TOO_SMALL 10317 ****************************************************************************** 10318 */ 10319static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext ) 10320{ 10321 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 10322 10323 M4OSA_UInt32 duration; 10324 M4OSA_UInt32 audiobitrate; 10325 M4OSA_UInt32 videobitrate; 10326 10327 /* free file size : OK */ 10328 if( pC->uiMaxFileSize == 0 ) 10329 return M4NO_ERROR; 10330 10331 /* duration */ 10332 if( pC->uiEndCutTime == 0 ) 10333 { 10334 duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime; 10335 } 10336 else 10337 { 10338 duration = pC->uiEndCutTime - pC->uiBeginCutTime; 10339 } 10340 10341 /* audio bitrate */ 10342 if( pC->noaudio ) 10343 { 10344 audiobitrate = 0; 10345 } 10346 else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL ) 10347 { 10348 audiobitrate = pC->InputFileProperties.uiAudioBitrate; 10349 } 10350 else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate ) 10351 { 10352 switch( pC->AudioEncParams.Format ) 10353 { 10354 case M4ENCODER_kAMRNB: 10355 audiobitrate = M4VIDEOEDITING_k12_2_KBPS; 10356 break; 10357 //EVRC 10358 // case M4ENCODER_kEVRC: 10359 // audiobitrate = M4VIDEOEDITING_k9_2_KBPS; 10360 // break; 10361 10362 default: /* AAC and MP3*/ 10363 audiobitrate = 10364 (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono) 10365 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS; 10366 break; 10367 } 10368 } 10369 else 10370 { 10371 audiobitrate = pC->uiAudioBitrate; 10372 } 10373 10374 /* video bitrate */ 10375 if( pC->novideo ) 10376 { 10377 videobitrate = 0; 10378 } 10379 else if( pC->EncodingVideoFormat == M4ENCODER_kNULL ) 10380 { 10381 videobitrate = pC->InputFileProperties.uiVideoBitrate; 10382 } 10383 else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate ) 10384 { 10385 videobitrate = M4VIDEOEDITING_k16_KBPS; 10386 } 10387 else 10388 { 10389 videobitrate = pC->uiVideoBitrate; 10390 } 10391 10392 /* max file size */ 10393 if( (M4OSA_UInt32)pC->uiMaxFileSize 10394 < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO 10395 * (audiobitrate + videobitrate) * (duration / 8000.0)) ) 10396 return M4MCS_ERR_MAXFILESIZE_TOO_SMALL; 10397 else 10398 return M4NO_ERROR; 10399} 10400 10401/** 10402 ****************************************************************************** 10403 * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode) 10404 * @brief Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate 10405 * @param freebitrate: unsigned int value 10406 * @param mode: -1:previous,0:current,1:next 10407 * @return bitrate value in enum list M4VIDEOEDITING_Bitrate 10408 ****************************************************************************** 10409 */ 10410static M4VIDEOEDITING_Bitrate 10411M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode ) 10412{ 10413 M4OSA_Int32 bitarray [] = 10414 { 10415 0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS, 10416 M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS, 10417 M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS, 10418 M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS, 10419 M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS, 10420 M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS, 10421 M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS, 10422 M4VIDEOEDITING_k5_MBPS, 10423 M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */ 10424 M4OSA_INT32_MAX 10425 }; 10426 10427 const M4OSA_UInt32 nbbitrates = 14; 10428 M4OSA_UInt32 i; 10429 10430 for ( i = 0; freebitrate >= bitarray[i]; i++ ); 10431 10432 switch( mode ) 10433 { 10434 case -1: /* previous */ 10435 if( i <= 2 ) 10436 return 0; 10437 else 10438 return bitarray[i - 2]; 10439 break; 10440 10441 case 0: /* current */ 10442 if( i <= 1 ) 10443 return 0; 10444 else 10445 return bitarray[i - 1]; 10446 break; 10447 10448 case 1: /* next */ 10449 if( i >= nbbitrates ) 10450 return M4OSA_INT32_MAX; 10451 else 10452 return bitarray[i]; 10453 break; 10454 } 10455 10456 return 0; 10457} 10458 10459/** 10460 ****************************************************************************** 10461 * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC); 10462 * @brief Free all resources allocated by M4MCS_open() 10463 * @param pContext (IN) MCS context 10464 * @return M4NO_ERROR: No error 10465 ****************************************************************************** 10466 */ 10467static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC ) 10468{ 10469 M4OSA_ERR err = M4NO_ERROR; 10470 10471 M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC); 10472 10473 /* ----- Free reader stuff, if needed ----- */ 10474 10475 if( M4OSA_NULL != pC-> 10476 pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */ 10477 { 10478 err = pC->m_pReader->m_pFctClose(pC->pReaderContext); 10479 10480 if( M4NO_ERROR != err ) 10481 { 10482 M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x", 10483 err); 10484 /**< don't return, we still have stuff to free */ 10485 } 10486 10487 err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext); 10488 pC->pReaderContext = M4OSA_NULL; 10489 10490 if( M4NO_ERROR != err ) 10491 { 10492 M4OSA_TRACE1_1( 10493 "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err); 10494 /**< don't return, we still have stuff to free */ 10495 } 10496 } 10497 10498 if( pC->m_pDataAddress1 != M4OSA_NULL ) 10499 { 10500 M4OSA_free((M4OSA_MemAddr32)pC->m_pDataAddress1); 10501 pC->m_pDataAddress1 = M4OSA_NULL; 10502 } 10503 10504 if( pC->m_pDataAddress2 != M4OSA_NULL ) 10505 { 10506 M4OSA_free((M4OSA_MemAddr32)pC->m_pDataAddress2); 10507 pC->m_pDataAddress2 = M4OSA_NULL; 10508 } 10509 /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/ 10510 if( pC->m_pDataVideoAddress1 != M4OSA_NULL ) 10511 { 10512 M4OSA_free((M4OSA_MemAddr32)pC->m_pDataVideoAddress1); 10513 pC->m_pDataVideoAddress1 = M4OSA_NULL; 10514 } 10515 10516 if( pC->m_pDataVideoAddress2 != M4OSA_NULL ) 10517 { 10518 M4OSA_free((M4OSA_MemAddr32)pC->m_pDataVideoAddress2); 10519 pC->m_pDataVideoAddress2 = M4OSA_NULL; 10520 } 10521 /**/ 10522 /* ----- Free video decoder stuff, if needed ----- */ 10523 10524 if( M4OSA_NULL != pC->pViDecCtxt ) 10525 { 10526 err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt); 10527 pC->pViDecCtxt = M4OSA_NULL; 10528 10529 if( M4NO_ERROR != err ) 10530 { 10531 M4OSA_TRACE1_1( 10532 "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x", 10533 err); 10534 /**< don't return, we still have stuff to free */ 10535 } 10536 } 10537 10538 /* ----- Free the audio decoder stuff ----- */ 10539 10540 if( M4OSA_NULL != pC->pAudioDecCtxt ) 10541 { 10542 err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt); 10543 pC->pAudioDecCtxt = M4OSA_NULL; 10544 10545 if( M4NO_ERROR != err ) 10546 { 10547 M4OSA_TRACE1_1( 10548 "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 10549 err); 10550 /**< don't return, we still have stuff to free */ 10551 } 10552 } 10553 10554 if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress ) 10555 { 10556 M4OSA_free((M4OSA_MemAddr32)pC->AudioDecBufferOut.m_dataAddress); 10557 pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 10558 } 10559 10560 return M4NO_ERROR; 10561} 10562 10563 10564/** 10565 10566 ****************************************************************************** 10567 * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, 10568 * M4OSA_Void* pFileOut, M4OSA_Void* pTempFile); 10569 * @brief Set the MCS input and output files. It is the same as M4MCS_open without 10570 * M4MCS_WITH_FAST_OPEN flag 10571It is used in VideoArtist 10572 * @note It opens the input file, but the output file is not created yet. 10573 * @param pContext (IN) MCS context 10574 * @param pFileIn (IN) Input file to transcode (The type of this parameter 10575 * (URL, pipe...) depends on the OSAL implementation). 10576 * @param mediaType (IN) Container type (.3gp,.amr, ...) of input file. 10577 * @param pFileOut (IN) Output file to create (The type of this parameter 10578 * (URL, pipe...) depends on the OSAL implementation). 10579 * @param pTempFile (IN) Temporary file for the constant memory writer to store 10580 * metadata ("moov.bin"). 10581 * @return M4NO_ERROR: No error 10582 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 10583 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 10584 * @return M4ERR_ALLOC: There is no more available memory 10585 * @return M4ERR_FILE_NOT_FOUND: The input file has not been found 10586 * @return M4MCS_ERR_INVALID_INPUT_FILE: The input file is not a valid file, or is corrupted 10587 * @return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM: The input file contains no 10588 * supported audio or video stream 10589 ****************************************************************************** 10590 */ 10591M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, 10592 M4VIDEOEDITING_FileType InputFileType, 10593 M4OSA_Void* pFileOut, M4OSA_Void* pTempFile) 10594{ 10595 M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext); 10596 M4OSA_ERR err; 10597 10598 M4READER_MediaFamily mediaFamily; 10599 M4_StreamHandler* pStreamHandler; 10600 10601 M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\ 10602 pFileOut=0x%x", pContext, pFileIn, pFileOut); 10603 10604 /** 10605 * Check input parameters */ 10606 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 10607 "M4MCS_open_normalMode: pContext is M4OSA_NULL"); 10608 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER, 10609 "M4MCS_open_normalMode: pFileIn is M4OSA_NULL"); 10610 10611 if ((InputFileType == M4VIDEOEDITING_kFileType_JPG) 10612 ||(InputFileType == M4VIDEOEDITING_kFileType_PNG) 10613 ||(InputFileType == M4VIDEOEDITING_kFileType_GIF) 10614 ||(InputFileType == M4VIDEOEDITING_kFileType_BMP)) 10615 { 10616 M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\ 10617 supported with this function"); 10618 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 10619 } 10620 10621 /** 10622 * Check state automaton */ 10623 if (M4MCS_kState_CREATED != pC->State) 10624 { 10625 M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE", 10626 pC->State); 10627 return M4ERR_STATE; 10628 } 10629 10630 /* Copy function input parameters into our context */ 10631 pC->pInputFile = pFileIn; 10632 pC->InputFileType = InputFileType; 10633 pC->pOutputFile = pFileOut; 10634 pC->pTemporaryFile = pTempFile; 10635 10636 /***********************************/ 10637 /* Open input file with the reader */ 10638 /***********************************/ 10639 10640 err = M4MCS_setCurrentReader(pContext, pC->InputFileType); 10641 M4ERR_CHECK_RETURN(err); 10642 10643 /** 10644 * Reset reader related variables */ 10645 pC->VideoState = M4MCS_kStreamState_NOSTREAM; 10646 pC->AudioState = M4MCS_kStreamState_NOSTREAM; 10647 pC->pReaderVideoStream = M4OSA_NULL; 10648 pC->pReaderAudioStream = M4OSA_NULL; 10649 10650 /*******************************************************/ 10651 /* Initializes the reader shell and open the data file */ 10652 /*******************************************************/ 10653 err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext); 10654 if (M4NO_ERROR != err) 10655 { 10656 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err); 10657 return err; 10658 } 10659 10660 /** 10661 * Link the reader interface to the reader context */ 10662 pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext; 10663 10664 /** 10665 * Set the reader shell file access functions */ 10666 err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext, 10667 M4READER_kOptionID_SetOsaFileReaderFctsPtr, 10668 (M4OSA_DataOption)pC->pOsaFileReadPtr); 10669 if (M4NO_ERROR != err) 10670 { 10671 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err); 10672 return err; 10673 } 10674 10675 /** 10676 * Open the input file */ 10677 err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile); 10678 if (M4NO_ERROR != err) 10679 { 10680 M4OSA_UInt32 uiDummy, uiCoreId; 10681 M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err); 10682 10683 /** 10684 * If the error is from the core reader, we change it to a public VXS error */ 10685 M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); 10686 if (M4MP4_READER == uiCoreId) 10687 { 10688 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE"); 10689 return M4MCS_ERR_INVALID_INPUT_FILE; 10690 } 10691 return err; 10692 } 10693 10694 /** 10695 * Get the streams from the input file */ 10696 while (M4NO_ERROR == err) 10697 { 10698 err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily, 10699 &pStreamHandler); 10700 10701 /** 10702 * In case we found a BIFS stream or something else...*/ 10703 if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) 10704 || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))) 10705 { 10706 err = M4NO_ERROR; 10707 continue; 10708 } 10709 10710 if (M4NO_ERROR == err) /**< One stream found */ 10711 { 10712 /** 10713 * Found the first video stream */ 10714 if ((M4READER_kMediaFamilyVideo == mediaFamily) \ 10715 && (M4OSA_NULL == pC->pReaderVideoStream)) 10716 { 10717 if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) || 10718 (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType) 10719#ifdef M4VSS_SUPPORT_VIDEO_AVC 10720 ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)) 10721#else 10722 ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType) 10723 &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL))) 10724#endif 10725 { 10726 M4OSA_TRACE3_0("M4MCS_open_normalMode():\ 10727 Found a H263 or MPEG-4 video stream in input 3gpp clip"); 10728 10729 /** 10730 * Keep pointer to the video stream */ 10731 pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler; 10732 pC->bUnsupportedVideoFound = M4OSA_FALSE; 10733 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 10734 10735 /** 10736 * Init our video stream state variable */ 10737 pC->VideoState = M4MCS_kStreamState_STARTED; 10738 10739 /** 10740 * Reset the stream reader */ 10741 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 10742 (M4_StreamHandler*)pC->pReaderVideoStream); 10743 if (M4NO_ERROR != err) 10744 { 10745 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10746 m_pReader->m_pFctReset(video) returns 0x%x", err); 10747 return err; 10748 } 10749 10750 /** 10751 * Initializes an access Unit */ 10752 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, 10753 &pC->ReaderVideoAU); 10754 if (M4NO_ERROR != err) 10755 { 10756 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10757 m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err); 10758 return err; 10759 } 10760 } 10761 else /**< Not H263 or MPEG-4 (H264, etc.) */ 10762 { 10763 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10764 Found an unsupported video stream (0x%x) in input 3gpp clip", 10765 pStreamHandler->m_streamType); 10766 10767 pC->bUnsupportedVideoFound = M4OSA_TRUE; 10768 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 10769 } 10770 } 10771 /** 10772 * Found the first audio stream */ 10773 else if ((M4READER_kMediaFamilyAudio == mediaFamily) 10774 && (M4OSA_NULL == pC->pReaderAudioStream)) 10775 { 10776 if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) || 10777 (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) || 10778 (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) || 10779 (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) ) 10780 { 10781 M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \ 10782 or MP3 audio stream in input clip"); 10783 10784 /** 10785 * Keep pointer to the audio stream */ 10786 pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler; 10787 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 10788 pC->bUnsupportedAudioFound = M4OSA_FALSE; 10789 10790 /** 10791 * Init our audio stream state variable */ 10792 pC->AudioState = M4MCS_kStreamState_STARTED; 10793 10794 /** 10795 * Reset the stream reader */ 10796 err = pC->m_pReader->m_pFctReset(pC->pReaderContext, 10797 (M4_StreamHandler*)pC->pReaderAudioStream); 10798 if (M4NO_ERROR != err) 10799 { 10800 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10801 m_pReader->m_pFctReset(audio) returns 0x%x", err); 10802 return err; 10803 } 10804 10805 /** 10806 * Initializes an access Unit */ 10807 err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler, 10808 &pC->ReaderAudioAU); 10809 if (M4NO_ERROR != err) 10810 { 10811 M4OSA_TRACE1_1("M4MCS_open_normalMode(): \ 10812 m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err); 10813 return err; 10814 } 10815 10816 /** 10817 * Output max AU size is equal to input max AU size (this value 10818 * will be changed if there is audio transcoding) */ 10819 pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize; 10820 10821 } 10822 else 10823 { 10824 /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */ 10825 M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\ 10826 (0x%x) in input 3gpp clip", pStreamHandler->m_streamType); 10827 10828 pC->bUnsupportedAudioFound = M4OSA_TRUE; 10829 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 10830 } 10831 } 10832 } 10833 } /**< end of while (M4NO_ERROR == err) */ 10834 10835 /** 10836 * Check we found at least one supported stream */ 10837 if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream)) 10838 { 10839 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \ 10840 M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM"); 10841 return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; 10842 } 10843 10844#ifndef M4VSS_ENABLE_EXTERNAL_DECODERS 10845 if(pC->VideoState == M4MCS_kStreamState_STARTED) 10846 { 10847 err = M4MCS_setCurrentVideoDecoder(pContext, 10848 pC->pReaderVideoStream->m_basicProperties.m_streamType); 10849 M4ERR_CHECK_RETURN(err); 10850 } 10851#endif 10852 10853 if(pC->AudioState == M4MCS_kStreamState_STARTED) 10854 { 10855 //EVRC 10856 if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType) 10857 /* decoder not supported yet, but allow to do null encoding */ 10858 { 10859 err = M4MCS_setCurrentAudioDecoder(pContext, 10860 pC->pReaderAudioStream->m_basicProperties.m_streamType); 10861 M4ERR_CHECK_RETURN(err); 10862 } 10863 } 10864 10865 /** 10866 * Get the audio and video stream properties */ 10867 err = M4MCS_intGetInputClipProperties(pC); 10868 if (M4NO_ERROR != err) 10869 { 10870 M4OSA_TRACE1_1("M4MCS_open_normalMode():\ 10871 M4MCS_intGetInputClipProperties returns 0x%x", err); 10872 return err; 10873 } 10874 10875 /** 10876 * Set the begin cut decoding increment according to the input frame rate */ 10877 if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */ 10878 { 10879 pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \ 10880 / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */ 10881 } 10882 else 10883 { 10884 pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/ 10885 } 10886 10887 /** 10888 * Update state automaton */ 10889 pC->State = M4MCS_kState_OPENED; 10890 10891 /** 10892 * Return with no error */ 10893 M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR"); 10894 return M4NO_ERROR; 10895} 10896 10897 10898M4OSA_ERR M4MCS_registerExternalVideoDecoder( M4MCS_Context pContext, 10899 M4VD_VideoType decoderType, 10900 M4VD_Interface *pDecoderInterface, 10901 M4OSA_Void *pUserData ) 10902{ 10903#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 10904 10905 M4OSA_ERR err = M4NO_ERROR; 10906 M4DECODER_VideoInterface *shellInterface; 10907 M4DECODER_VideoType nativeType; 10908 M4DECODER_EXTERNAL_UserDataType shellUserData; 10909 10910 switch( decoderType ) 10911 { 10912 case M4VD_kMpeg4VideoDec: 10913 case M4VD_kH263VideoDec: 10914 nativeType = M4DECODER_kVideoTypeMPEG4; 10915 break; 10916 10917 case M4VD_kH264VideoDec: 10918 nativeType = M4DECODER_kVideoTypeAVC; 10919 break; 10920 10921 default: 10922 M4OSA_TRACE1_1( 10923 "M4MCS_registerExternalVideoDecoder: unknown decoderType %d", 10924 decoderType); 10925 return M4ERR_PARAMETER; 10926 break; 10927 } 10928 10929 shellUserData = 10930 (M4DECODER_EXTERNAL_UserDataType)M4OSA_malloc(sizeof(*shellUserData), 10931 M4MCS, 10932 (M4OSA_Char *)"userData structure for the external shell decoder"); 10933 10934 if( M4OSA_NULL == shellUserData ) 10935 { 10936 M4OSA_TRACE1_0( 10937 "M4MCS_registerExternalVideoDecoder:\ 10938 failed to allocate userData structure for the external shell decoder"); 10939 return M4ERR_ALLOC; 10940 } 10941 10942 shellUserData->externalFuncs = pDecoderInterface; 10943 shellUserData->externalUserData = pUserData; 10944 10945 err = M4DECODER_EXTERNAL_getInterface(&shellInterface); 10946 10947 if( M4NO_ERROR != err ) 10948 { 10949 M4OSA_TRACE1_1( 10950 "M4MCS_registerExternalVideoDecoder:\ 10951 M4DECODER_EXTERNAL_getInterface failed with error 0x%08X", 10952 err); 10953 M4OSA_free((M4OSA_MemAddr32)shellUserData); 10954 return err; 10955 } 10956 10957 err = M4MCS_registerVideoDecoder(pContext, nativeType, shellInterface); 10958 10959 if( M4NO_ERROR != err ) 10960 { 10961 M4OSA_TRACE1_1( 10962 "M4MCS_registerExternalVideoDecoder:\ 10963 M4MCS_registerVideoDecoder failed with error 0x%08X", 10964 err); 10965 M4OSA_free((M4OSA_MemAddr32)shellInterface); 10966 M4OSA_free((M4OSA_MemAddr32)shellUserData); 10967 return err; 10968 } 10969 10970 ( (M4MCS_InternalContext 10971 *)pContext)->m_pVideoDecoderUserDataTable[nativeType] = shellUserData; 10972 10973 return M4NO_ERROR; 10974#else 10975 10976 return M4ERR_NOT_IMPLEMENTED; 10977 10978#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 10979 10980} 10981 10982M4OSA_ERR M4MCS_registerExternalVideoEncoder( M4MCS_Context pContext, 10983 M4VE_EncoderType encoderType, 10984 M4VE_Interface *pEncoderInterface, 10985 M4OSA_Void *pUserData ) 10986{ 10987#ifdef M4VSS_ENABLE_EXTERNAL_ENCODERS 10988 10989 M4OSA_ERR err = M4NO_ERROR; 10990 M4ENCODER_GlobalInterface *shellInterface; 10991 M4ENCODER_Format nativeType; 10992 10993 switch( encoderType ) 10994 { 10995 case M4VE_kH263VideoEnc: 10996 err = M4EGE_H263_getInterfaces(&nativeType, &shellInterface, 10997 M4ENCODER_OPEN_ADVANCED); 10998 10999 break; 11000 11001 case M4VE_kMpeg4VideoEnc: 11002 err = M4EGE_MPEG4_getInterfaces(&nativeType, &shellInterface, 11003 M4ENCODER_OPEN_ADVANCED); 11004 break; 11005 11006 case M4VE_kH264VideoEnc: 11007 M4OSA_TRACE1_0( 11008 "M4MCS_registerExternalVideoEncoder: H264 encoder type not implemented yet"); 11009 return M4ERR_NOT_IMPLEMENTED; 11010 break; 11011 11012 default: 11013 M4OSA_TRACE1_1( 11014 "M4MCS_registerExternalVideoEncoder: unknown encoderType %d", 11015 encoderType); 11016 return M4ERR_PARAMETER; 11017 break; 11018 } 11019 11020 if( M4NO_ERROR != err ) 11021 { 11022 M4OSA_TRACE1_1( 11023 "M4MCS_registerExternalVideoDecoder: M4EGE_getInterface failed with error 0x%08X", 11024 err); 11025 return err; 11026 } 11027 11028 err = M4MCS_registerVideoEncoder(pContext, nativeType, shellInterface); 11029 11030 if( M4NO_ERROR != err ) 11031 { 11032 M4OSA_TRACE1_1( 11033 "M4MCS_registerExternalVideoEncoder:\ 11034 M4MCS_registerVideoEncoder failed with error 0x%08X", 11035 err); 11036 M4OSA_free((M4OSA_MemAddr32)shellInterface); 11037 return err; 11038 } 11039 11040 ( (M4MCS_InternalContext 11041 *)pContext)->pVideoEncoderExternalAPITable[nativeType] 11042 = pEncoderInterface; 11043 ( (M4MCS_InternalContext 11044 *)pContext)->pVideoEncoderUserDataTable[nativeType] = pUserData; 11045 11046 return M4NO_ERROR; 11047 11048#else 11049 11050 return M4ERR_NOT_IMPLEMENTED; 11051 11052#endif 11053 11054} 11055 11056/** 11057 ************************************************************************ 11058 * M4OSA_ERR M4MCS_registerExternalAudioDecoder(M4MCS_Context pContext, 11059 * M4AD_Type decoderType, 11060 * M4AD_Interface *pDecoderInterface); 11061 * @brief This function will register a specific external audio decoder. 11062 * @note According to the decoderType, this function will store in the internal context the 11063 * decoder interface. 11064 * @param context (IN/OUT) MCS context. 11065 * @param decoderType (IN) Audio decoder type 11066 * @param pDecoderInterface (IN) Audio decoder interface. 11067 * @return M4NO_ERROR: No error 11068 * @return M4ERR_PARAMETER: A parameter is null, or the decoder type is invalid 11069 * (in DEBUG only) 11070 ************************************************************************ 11071 */ 11072M4OSA_ERR M4MCS_registerExternalAudioDecoder( M4MCS_Context pContext, 11073 M4AD_Type decoderType, 11074 M4AD_Interface *pDecoderInterface ) 11075{ 11076 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)pContext; 11077 11078 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 11079 "M4MCS_registerExternalAudioDecoder: invalid context pointer"); 11080 M4OSA_DEBUG_IF1((M4OSA_NULL == pDecoderInterface), M4ERR_PARAMETER, 11081 "M4MCS_registerExternalAudioDecoder: invalid pointer on decoder interface"); 11082 11083 if( M4MCS_kState_CREATED != pC->State ) 11084 { 11085 M4OSA_TRACE1_1( 11086 "M4MCS_registerExternalAudioDecoder(): Wrong State (%d), returning M4ERR_STATE", 11087 pC->State); 11088 return M4ERR_STATE; 11089 } 11090 11091 if( decoderType >= M4AD_kType_NB ) 11092 { 11093 M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, 11094 "M4MCS_registerExternalAudioDecoder: Invalid audio decoder type"); 11095 return M4ERR_PARAMETER; 11096 } 11097 11098 if( pC->m_pAudioDecoderFlagTable[decoderType] == M4OSA_TRUE 11099 && pC->m_pAudioDecoderItTable[decoderType] != M4OSA_NULL ) 11100 { 11101 M4OSA_TRACE1_1( 11102 "M4MCS_registerExternalAudioDecoder: error parameter: an external decoder of type\ 11103 %i is already registered", 11104 decoderType); 11105 return M4ERR_PARAMETER; 11106 } 11107 11108 if( pC->m_pAudioDecoderItTable[decoderType] != M4OSA_NULL ) 11109 { 11110 M4OSA_free((M4OSA_MemAddr32)pC->m_pAudioDecoderItTable[decoderType]); 11111 pC->m_pAudioDecoderItTable[decoderType] = M4OSA_NULL; 11112 } 11113 11114 pC->m_pAudioDecoderItTable[decoderType] = pDecoderInterface; 11115 pC->m_pAudioDecoderFlagTable[decoderType] = 11116 M4OSA_TRUE; /* external decoder */ 11117 11118 return M4NO_ERROR; 11119} 11120 11121/** 11122 ****************************************************************************** 11123 * M4OSA_ERR M4MCS_registerExternalAudioEncoder(M4MCS_Context pContext, 11124 * M4ENCODER_AudioFormat mediaType, 11125 * M4ENCODER_AudioGlobalInterface *pEncGlobalInterface) 11126 * @brief This function will register a specific external audio encoder. 11127 * @note According to the Mediatype, this function will store in the internal context the 11128 * encoder context. 11129 * @param pContext: (IN) Execution context. 11130 * @param mediaType: (IN) The media type. 11131 * @param pEncGlobalInterface: (OUT) the encoder interface functions. 11132 * @return M4NO_ERROR: there is no error 11133 * @return M4ERR_PARAMETER: pContext or pEncGlobalInterface is M4OSA_NULL (debug only) 11134 ****************************************************************************** 11135 */ 11136M4OSA_ERR M4MCS_registerExternalAudioEncoder( M4MCS_Context pContext, 11137 M4ENCODER_AudioFormat MediaType, 11138 M4ENCODER_AudioGlobalInterface *pEncGlobalInterface ) 11139{ 11140 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)pContext; 11141 11142 /** 11143 * Check input parameters */ 11144 M4OSA_DEBUG_IF2((pC == M4OSA_NULL), M4ERR_PARAMETER, 11145 "MCS: context is M4OSA_NULL in M4MCS_registerExternalAudioEncoder"); 11146 M4OSA_DEBUG_IF2((pEncGlobalInterface == M4OSA_NULL), M4ERR_PARAMETER, 11147 "pEncGlobalInterface is M4OSA_NULL in M4MCS_registerExternalAudioEncoder"); 11148 11149 M4OSA_TRACE3_2( 11150 "MCS: M4MCS_registerExternalAudioEncoder called with pContext=0x%x, \ 11151 pEncGlobalInterface=0x%x", 11152 pC, pEncGlobalInterface); 11153 11154 if( M4MCS_kState_CREATED != pC->State ) 11155 { 11156 M4OSA_TRACE1_1( 11157 "M4MCS_registerExternalAudioEncoder(): Wrong State (%d), returning M4ERR_STATE", 11158 pC->State); 11159 return M4ERR_STATE; 11160 } 11161 11162 if( MediaType >= M4ENCODER_kAudio_NB ) 11163 { 11164 M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, 11165 "M4MCS_registerExternalAudioEncoder(): Invalid audio encoder type"); 11166 return M4ERR_PARAMETER; 11167 } 11168 11169 if( pC->pAudioEncoderFlag[MediaType] == M4OSA_TRUE 11170 && pC->pAudioEncoderInterface[MediaType] != M4OSA_NULL ) 11171 { 11172 M4OSA_TRACE1_1( 11173 "M4MCS_registerExternalAudioEncoder: error parameter:\ 11174 an external encoder of type %i is already registered", 11175 MediaType); 11176 return M4ERR_PARAMETER; 11177 } 11178 11179 if( pC->pAudioEncoderInterface[MediaType] != M4OSA_NULL ) 11180 { 11181 M4OSA_free((M4OSA_MemAddr32)pC->pAudioEncoderInterface[MediaType]); 11182 pC->pAudioEncoderInterface[MediaType] = M4OSA_NULL; 11183 } 11184 11185 /* 11186 * Save encoder interface in context */ 11187 pC->pAudioEncoderInterface[MediaType] = pEncGlobalInterface; 11188 pC->pAudioEncoderFlag[MediaType] = M4OSA_TRUE; /* external encoder */ 11189 11190 return M4NO_ERROR; 11191} 11192 11193/** 11194 ****************************************************************************** 11195 * M4OSA_ERR M4MCS_getExifInfo(M4MCS_Context pContext); 11196 * @brief Retrieve the EXIF tags informations from a Still picture 11197 * @note This function will allocate and fill a Exif tag struct 11198 * exifTags structure must be allocated/deallocated by the user 11199 * exifTags members will point to internal SPE information, user should not try 11200 * to modify or deallocate them 11201 * @param pContext (IN) MCS context 11202 * @return M4NO_ERROR: No error 11203 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL 11204 ****************************************************************************** 11205 */ 11206M4OSA_ERR M4MCS_getExifInfo( M4MCS_Context pContext, M4MCS_ExifInfos *exifTags ) 11207{ 11208 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext); 11209 M4OSA_ERR err; 11210 11211 M4OSA_TRACE2_1("M4MCS_getExifInfo called with pContext=0x%x", pContext); 11212 11213 /** 11214 * Check input parameters */ 11215 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 11216 "M4MCS_getExifInfo: pContext is M4OSA_NULL"); 11217 11218#ifdef M4MCS_SUPPORT_STILL_PICTURE 11219 11220 if( pC->m_bIsStillPicture ) 11221 { 11222 /** 11223 * Call the corresponding still picture MCS function*/ 11224 return M4MCS_stillPicGetExifInfo(pC, exifTags); 11225 } 11226 11227#endif /*M4MCS_SUPPORT_STILL_PICTURE*/ 11228 11229 return M4ERR_NOT_IMPLEMENTED; 11230} 11231 11232/** 11233 ****************************************************************************** 11234 * M4OSA_ERR M4MCS_registerVideoDecoderExtended(M4MCS_Context context, 11235M4DECODER_VideoType decoderType, 11236M4DECODER_VideoInterface *pDecoderInterface, 11237M4OSA_Void* pUserData) 11238 * @brief Registers an external Video decoder 11239 * @note This is much different from the external video decoder to cope up with specific 11240 * requirement of OMX codec implementation. 11241So we use M4DECODER_VideoInterface instead of M4VD_Interface. 11242 * @param pContext (IN) MCS context 11243 * @param decoderType (IN) Type of decoder (MPEG4 ...) 11244 * @param pVidDecoderInterface (IN) Decoder interface of type 'M4DECODER_VideoInterface' 11245 * @param pUserData (IN) Pointer on a user data to give to external decoder 11246 * @return M4NO_ERROR: No error 11247 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 11248 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 11249 ****************************************************************************** 11250 */ 11251M4OSA_ERR M4MCS_registerVideoDecoderExtended( M4MCS_Context context, 11252 M4VD_VideoType decoderType, 11253 M4OSA_Context pVidDecoderInterface, 11254 M4OSA_Void *pUserData ) 11255{ 11256 M4OSA_ERR err = M4NO_ERROR; 11257 M4DECODER_VideoType nativeType; 11258 M4DECODER_EXTERNAL_UserDataType shellUserData; 11259 M4DECODER_VideoInterface *pDecoderInterface = 11260 (M4DECODER_VideoInterface *)pVidDecoderInterface; 11261 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)context; 11262 M4OSA_Bool bResetCurrentVideoDecoder = M4OSA_FALSE; 11263 M4_StreamType mediaType = M4DA_StreamTypeUnknown; 11264 11265 M4OSA_TRACE3_1( 11266 "M4MCS_registerVideoDecoderExtended invoked with context = 0x%x", 11267 context); 11268 11269 switch( decoderType ) 11270 { 11271 case M4VD_kMpeg4VideoDec: 11272 case M4VD_kH263VideoDec: 11273 nativeType = M4DECODER_kVideoTypeMPEG4; 11274 mediaType = M4DA_StreamTypeVideoMpeg4; 11275 break; 11276 11277 case M4VD_kH264VideoDec: 11278 nativeType = M4DECODER_kVideoTypeAVC; 11279 mediaType = M4DA_StreamTypeVideoMpeg4Avc; 11280 break; 11281 11282 default: 11283 M4OSA_TRACE1_1( 11284 "M4MCS_registerVideoDecoderExtended: unknown decoderType %d", 11285 decoderType); 11286 return M4ERR_PARAMETER; 11287 } 11288 11289 if( M4OSA_NULL != pC->m_pVideoDecoder ) 11290 { 11291 M4OSA_TRACE3_0( 11292 "M4MCS_registerVideoDecoderExtended: pC->m_pVideoDecoder already set to \ 11293 previous registered dec shell"); 11294 11295 if( ( ( ( pC->pReaderVideoStream->m_basicProperties.m_streamType 11296 == M4DA_StreamTypeVideoH263) 11297 || (pC->pReaderVideoStream->m_basicProperties.m_streamType 11298 == M4DA_StreamTypeVideoMpeg4)) 11299 && (mediaType == M4DA_StreamTypeVideoMpeg4)) 11300 || (( pC->pReaderVideoStream->m_basicProperties.m_streamType 11301 == M4DA_StreamTypeVideoMpeg4Avc) 11302 && (mediaType == M4DA_StreamTypeVideoMpeg4Avc)) ) 11303 bResetCurrentVideoDecoder = M4OSA_TRUE; 11304 } 11305 11306 err = M4MCS_registerVideoDecoder(context, nativeType, pDecoderInterface); 11307 11308 /** Provide the application user data back to the interface functions. ** 11309 * For now we donot provide 'M4DECODER_EXTERNAL_UserDataType' **/ 11310 ( (M4MCS_InternalContext 11311 *)context)->m_pVideoDecoderUserDataTable[nativeType] = pUserData; 11312 11313 if( ( M4NO_ERROR == err) && (M4OSA_TRUE == bResetCurrentVideoDecoder) ) 11314 { 11315 err = M4MCS_setCurrentVideoDecoder(context, mediaType); 11316 M4OSA_TRACE3_1( 11317 "M4MCS_registerVideoDecoderExtended: M4MCS_setCurrentVideoDecoder returned 0x%x", 11318 err); 11319 } 11320 M4OSA_TRACE1_1( 11321 "M4MCS_registerVideoDecoderExtended returning with error = 0x%x", err); 11322 return err; 11323} 11324 11325/** 11326 ****************************************************************************** 11327 * M4OSA_ERR M4MCS_registerVideoEncoderExtended() 11328 * @brief Registers an external Video encoder 11329 * @note This is much different from the external video encoder to cope up with specific 11330 * requirement of OMX codec implementation. 11331So we use M4ENCODER_GlobalInterface instead of M4VE_Interface. 11332 * @param pContext (IN) MCS context 11333 * @param encoderType (IN) Type of encoder (MPEG4 ...) 11334 * @param pEncoderInterface (IN) Encoder interface of type 'M4ENCODER_VideoInterface' 11335 * @param pUserData (IN) Pointer on a user data to give to external encoder 11336 * @return M4NO_ERROR: No error 11337 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 11338 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 11339 ****************************************************************************** 11340 */ 11341M4OSA_ERR M4MCS_registerVideoEncoderExtended( M4MCS_Context pContext, 11342 M4VE_EncoderType encoderType, 11343 M4OSA_Context pEncoderInterface, 11344 M4OSA_Void *pUserData ) 11345{ 11346 M4OSA_ERR err = M4NO_ERROR; 11347 M4ENCODER_Format nativeType; 11348 M4ENCODER_GlobalInterface *pEncShellInterface = 11349 (M4ENCODER_GlobalInterface *)pEncoderInterface; 11350 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)pContext; 11351 M4OSA_Bool bResetCurrentVideoEncoder = M4OSA_FALSE; 11352 M4VIDEOEDITING_VideoFormat mediaType = M4VIDEOEDITING_kNoneVideo; 11353 11354 M4OSA_TRACE3_1( 11355 "M4MCS_registerVideoEncoderExtended invoked with context = 0x%x", 11356 pContext); 11357 11358 switch( encoderType ) 11359 { 11360 case M4VE_kMpeg4VideoEnc: 11361 nativeType = M4ENCODER_kMPEG4; 11362 mediaType = M4VIDEOEDITING_kMPEG4; 11363 break; 11364 11365 case M4VE_kH263VideoEnc: 11366 nativeType = M4ENCODER_kH263; 11367 mediaType = M4VIDEOEDITING_kH263; 11368 break; 11369 11370 case M4VE_kH264VideoEnc: 11371 nativeType = M4ENCODER_kH264; 11372 mediaType = M4VIDEOEDITING_kH264; 11373 break; 11374 11375 default: 11376 M4OSA_TRACE1_1( 11377 "M4MCS_registerVideoEncoderExtended: unknown encoderType %d", 11378 encoderType); 11379 return M4ERR_PARAMETER; 11380 } 11381 11382 if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts ) 11383 { 11384 M4OSA_TRACE3_0( 11385 "M4MCS_registerVideoEncoderExtended:\ 11386 pC->pVideoEncoderGlobalFcts already set to previous registered Enc shell"); 11387 11388 if( pC->EncodingVideoFormat == nativeType ) 11389 bResetCurrentVideoEncoder = M4OSA_TRUE; 11390 } 11391 11392 err = M4MCS_registerVideoEncoder(pContext, nativeType, pEncShellInterface); 11393 11394 ( (M4MCS_InternalContext 11395 *)pContext)->pVideoEncoderExternalAPITable[nativeType] 11396 = pEncoderInterface; 11397 ( (M4MCS_InternalContext 11398 *)pContext)->pVideoEncoderUserDataTable[nativeType] = pUserData; 11399 11400 if( ( M4NO_ERROR == err) && (M4OSA_TRUE == bResetCurrentVideoEncoder) ) 11401 { 11402 err = M4MCS_setCurrentVideoEncoder(pContext, mediaType); 11403 M4OSA_TRACE3_1( 11404 "M4MCS_registerVideoEncoderExtended: M4MCS_setCurrentVideoEncoder returned 0x%x", 11405 err); 11406 } 11407 M4OSA_TRACE1_1( 11408 "M4MCS_registerVideoEncoderExtended returning with error = 0x%x", err); 11409 return err; 11410} 11411 11412/** 11413 ****************************************************************************** 11414 * M4OSA_ERR M4MCS_registerAudioEncoderExtended(M4MCS_Context pContext, 11415M4ENCODER_AudioFormat encoderType, 11416M4ENCODER_AudioGlobalInterface *pEncoderInterface, 11417M4OSA_Void* pUserData); 11418 * @brief Registers an external Audio Encoder 11419 * @note This is much different from the external audio encoder to cope up with specific 11420 * requirement of OMX codec implementation. 11421 * @param pContext (IN) MCS context 11422 * @param encoderType (IN) Type of encoder 11423 * @param pEncoderInterface (IN) Encoder interface to OMX shell function 11424 * @param pUserData (IN) Pointer on a user data to give to external encoder 11425 * (OMX Core Context) 11426 * @return M4NO_ERROR: No error 11427 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 11428 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 11429 ****************************************************************************** 11430 */ 11431M4OSA_ERR M4MCS_registerAudioEncoderExtended( M4MCS_Context pContext, 11432 M4ENCODER_AudioFormat encoderType, 11433 M4ENCODER_AudioGlobalInterface *pEncoderInterface, 11434 M4OSA_Void *pUserData ) 11435{ 11436 M4OSA_ERR err = M4NO_ERROR; 11437 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)pContext; 11438 M4OSA_Bool bResetCurrentAudioEncoder = M4OSA_FALSE; 11439 M4VIDEOEDITING_AudioFormat mediaType = M4VIDEOEDITING_kNoneAudio; 11440 11441 switch( encoderType ) 11442 { 11443 case M4ENCODER_kAMRNB: 11444 mediaType = M4VIDEOEDITING_kAMR_NB; 11445 break; 11446 11447 case M4ENCODER_kAAC: 11448 mediaType = M4VIDEOEDITING_kAAC; 11449 break; 11450 11451 case M4ENCODER_MP3: 11452 mediaType = M4VIDEOEDITING_kMP3; 11453 break; 11454 11455 default: 11456 M4OSA_TRACE1_1( 11457 "M4MCS_registerAudioEncoderExtended: unknown encoderType %d", 11458 encoderType); 11459 return M4ERR_PARAMETER; 11460 } 11461 11462 if( M4OSA_NULL != pC->pAudioEncoderGlobalFcts ) 11463 { 11464 M4OSA_TRACE3_0( 11465 "M4MCS_registerAudioEncoderExtended: pC->pAudioEncoderGlobalFcts already set to \ 11466 previous registered Enc shell"); 11467 11468 if( pC->AudioEncParams.Format == encoderType ) 11469 bResetCurrentAudioEncoder = M4OSA_TRUE; 11470 } 11471 11472 err = M4MCS_registerAudioEncoder(pContext, encoderType, pEncoderInterface); 11473 11474 if( M4NO_ERROR != err ) 11475 { 11476 M4OSA_TRACE1_1( 11477 "M4MCS_registerAudioEncoderExtended: \ 11478 M4MCS_registerAudioEncoder failed with error 0x%08X", 11479 err); 11480 M4OSA_free((M4OSA_MemAddr32)pEncoderInterface); 11481 return err; 11482 } 11483 11484 ( (M4MCS_InternalContext 11485 *)pContext)->pAudioEncoderInterface[encoderType] = pEncoderInterface; 11486 ( (M4MCS_InternalContext 11487 *)pContext)->pAudioEncoderUserDataTable[encoderType] = pUserData; 11488 11489 if( ( M4NO_ERROR == err) && (M4OSA_TRUE == bResetCurrentAudioEncoder) ) 11490 { 11491 err = M4MCS_setCurrentAudioEncoder(pContext, mediaType); 11492 M4OSA_TRACE3_1( 11493 "M4MCS_registerAudioEncoderExtended: M4MCS_setCurrentAudioEncoder returned 0x%x", 11494 err); 11495 } 11496 return err; 11497} 11498 11499/** 11500 ****************************************************************************** 11501 * M4OSA_ERR M4MCS_registerAudioDecoderExtended(M4MCS_Context pContext, 11502M4AD_Type decoderType, 11503M4AD_Interface *pDecoderInterface, 11504M4OSA_Void* pUserData); 11505 * @brief Registers an external Audio Decoder 11506 * @note This is much different from the external audio decoder to cope up with specific 11507 * requirement of OMX codec implementation. 11508 * @param pContext (IN) MCS context 11509 * @param decoderType (IN) Type of decoder 11510 * @param pDecoderInterface (IN) Decoder interface to OMX shell function 11511 * @param pUserData (IN) Pointer on a user data to give to external decoder 11512 * (OMX Core Context) 11513 * @return M4NO_ERROR: No error 11514 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 11515 * @return M4ERR_STATE: MCS is not in an appropriate state for this function to be called 11516 ****************************************************************************** 11517 */ 11518M4OSA_ERR M4MCS_registerAudioDecoderExtended( M4MCS_Context pContext, 11519 M4AD_Type decoderType, 11520 M4AD_Interface *pDecoderInterface, 11521 M4OSA_Void *pUserData ) 11522{ 11523 M4OSA_ERR err = M4NO_ERROR; 11524 M4MCS_InternalContext *pC = (M4MCS_InternalContext *)pContext; 11525 M4OSA_Bool bResetCurrentAudioDecoder = M4OSA_FALSE; 11526 M4_StreamType mediaType = M4DA_StreamTypeUnknown; 11527 11528 switch( decoderType ) 11529 { 11530 case M4AD_kTypeAMRNB: 11531 mediaType = M4DA_StreamTypeAudioAmrNarrowBand; 11532 break; 11533 11534 case M4AD_kTypeAAC: 11535 mediaType = M4DA_StreamTypeAudioAac; 11536 break; 11537 11538 case M4AD_kTypeMP3: 11539 mediaType = M4DA_StreamTypeAudioMp3; 11540 break; 11541 11542 default: 11543 M4OSA_TRACE1_1( 11544 "M4MCS_registerAudioDecoderExtended: unknown decoder type %d", 11545 decoderType); 11546 return M4ERR_PARAMETER; 11547 } 11548 11549 if( M4OSA_NULL != pC->m_pAudioDecoder ) 11550 { 11551 M4OSA_TRACE3_0( 11552 "M4MCS_registerAudioDecoderExtended:\ 11553 pC->m_pAudioDecoder already set to previous registered Dec shell"); 11554 11555 if( pC->pReaderAudioStream->m_basicProperties.m_streamType 11556 == mediaType ) 11557 bResetCurrentAudioDecoder = M4OSA_TRUE; 11558 11559 /* Audio decoder may be created for getting input Clip properties. 11560 In that case, previous audio dec context needs to be destroyed* 11561 * before registering new decoder shell */ 11562 if( M4OSA_NULL != pC->pAudioDecCtxt ) 11563 { 11564 err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt); 11565 pC->pAudioDecCtxt = M4OSA_NULL; 11566 11567 if( M4NO_ERROR != err ) 11568 { 11569 M4OSA_TRACE1_1( 11570 "M4MCS_registerAudioDecoderExtended:\ 11571 m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 11572 err); 11573 } 11574 } 11575 } 11576 11577 err = M4MCS_registerAudioDecoder(pContext, decoderType, pDecoderInterface); 11578 11579 if( M4NO_ERROR != err ) 11580 { 11581 M4OSA_TRACE1_1( 11582 "M4MCS_registerAudioDecoderExtended:\ 11583 M4MCS_registerAudioDecoder failed with error 0x%08X", 11584 err); 11585 M4OSA_free((M4OSA_MemAddr32)pDecoderInterface); 11586 return err; 11587 } 11588 11589 ( (M4MCS_InternalContext 11590 *)pContext)->m_pAudioDecoderItTable[decoderType] = pDecoderInterface; 11591 ( (M4MCS_InternalContext 11592 *)pContext)->m_pAudioDecoderUserDataTable[decoderType] = pUserData; 11593 11594 ( (M4MCS_InternalContext *)pContext)->bExtOMXAudDecoder = M4OSA_TRUE; 11595 11596 if( ( M4NO_ERROR == err) && (M4OSA_TRUE == bResetCurrentAudioDecoder) ) 11597 { 11598 err = M4MCS_setCurrentAudioDecoder(pContext, mediaType); 11599 M4OSA_TRACE3_1( 11600 "M4MCS_registerAudioDecoderExtended: M4MCS_setCurrentAudioDecoder returned 0x%x", 11601 err); 11602 } 11603 return err; 11604} 11605