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