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