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 * @file M4VSS3GPP_Clip.c
19 * @brief Implementation of functions related to input clip management.
20 * @note All functions in this file are static, i.e. non public
21 ******************************************************************************
22 */
23
24 /****************/
25 /*** Includes ***/
26 /****************/
27
28 #include "NXPSW_CompilerSwitches.h"
29 /**
30 * Our headers */
31 #include "M4VSS3GPP_API.h"
32 #include "M4VSS3GPP_ErrorCodes.h"
33 #include "M4VSS3GPP_InternalTypes.h"
34 #include "M4VSS3GPP_InternalFunctions.h"
35 #include "M4VSS3GPP_InternalConfig.h"
36
37 /**
38 * OSAL headers */
39 #include "M4OSA_Memory.h" /* OSAL memory management */
40 #include "M4OSA_Debug.h" /* OSAL debug management */
41
42
43 /**
44 * Common headers (for aac) */
45 #include "M4_Common.h"
46
47 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
48 #include "M4VD_EXTERNAL_Interface.h"
49
50 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
51
52 /* Osal header fileno */
53 #include "M4OSA_CharStar.h"
54
55 /**
56 ******************************************************************************
57 * define Static function prototypes
58 ******************************************************************************
59 */
60
61 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder(
62 M4VSS3GPP_ClipContext *pClipCtxt );
63
64 static M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties(
65 M4VSS3GPP_ClipContext *pClipCtxt);
66
67 /**
68 ******************************************************************************
69 * M4OSA_ERR M4VSS3GPP_intClipOpen()
70 * @brief Open a clip. Creates a clip context.
71 * @note
72 * @param hClipCtxt (OUT) Return the internal clip context
73 * @param pClipSettings (IN) Edit settings of this clip. The module will keep a
74 * reference to this pointer
75 * @param pFileReadPtrFct (IN) Pointer to OSAL file reader functions
76 * @param bSkipAudioTrack (IN) If true, do not open the audio
77 * @param bFastOpenMode (IN) If true, use the fast mode of the 3gpp reader
78 * (only the first AU is read)
79 * @return M4NO_ERROR: No error
80 * @return M4ERR_ALLOC: There is no more available memory
81 ******************************************************************************
82 */
83
M4VSS3GPP_intClipInit(M4VSS3GPP_ClipContext ** hClipCtxt,M4OSA_FileReadPointer * pFileReadPtrFct)84 M4OSA_ERR M4VSS3GPP_intClipInit( M4VSS3GPP_ClipContext ** hClipCtxt,
85 M4OSA_FileReadPointer *pFileReadPtrFct )
86 {
87 M4VSS3GPP_ClipContext *pClipCtxt;
88 M4OSA_ERR err;
89
90 M4OSA_DEBUG_IF2((M4OSA_NULL == hClipCtxt), M4ERR_PARAMETER,
91 "M4VSS3GPP_intClipInit: hClipCtxt is M4OSA_NULL");
92 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER,
93 "M4VSS3GPP_intClipInit: pFileReadPtrFct is M4OSA_NULL");
94
95 /**
96 * Allocate the clip context */
97 *hClipCtxt =
98 (M4VSS3GPP_ClipContext *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipContext),
99 M4VSS3GPP, (M4OSA_Char *)"M4VSS3GPP_ClipContext");
100
101 if( M4OSA_NULL == *hClipCtxt )
102 {
103 M4OSA_TRACE1_0(
104 "M4VSS3GPP_intClipInit(): unable to allocate M4VSS3GPP_ClipContext,\
105 returning M4ERR_ALLOC");
106 return M4ERR_ALLOC;
107 }
108 M4OSA_TRACE3_1("M4VSS3GPP_intClipInit(): clipCtxt=0x%x", *hClipCtxt);
109
110
111 /**
112 * Use this shortcut to simplify the code */
113 pClipCtxt = *hClipCtxt;
114
115 /* Inialization of context Variables */
116 memset((void *)pClipCtxt, 0,sizeof(M4VSS3GPP_ClipContext));
117
118 pClipCtxt->pSettings = M4OSA_NULL;
119
120 /**
121 * Init the clip context */
122 pClipCtxt->iVoffset = 0;
123 pClipCtxt->iAoffset = 0;
124 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_READ;
125 pClipCtxt->Astatus = M4VSS3GPP_kClipStatus_READ;
126
127 pClipCtxt->pReaderContext = M4OSA_NULL;
128 pClipCtxt->pVideoStream = M4OSA_NULL;
129 pClipCtxt->pAudioStream = M4OSA_NULL;
130 pClipCtxt->VideoAU.m_dataAddress = M4OSA_NULL;
131 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
132
133 pClipCtxt->pViDecCtxt = M4OSA_NULL;
134 pClipCtxt->iVideoDecCts = 0;
135 pClipCtxt->iVideoRenderCts = 0;
136 pClipCtxt->lastDecodedPlane = M4OSA_NULL;
137 pClipCtxt->iActualVideoBeginCut = 0;
138 pClipCtxt->iActualAudioBeginCut = 0;
139 pClipCtxt->bVideoAuAvailable = M4OSA_FALSE;
140 pClipCtxt->bFirstAuWritten = M4OSA_FALSE;
141
142 pClipCtxt->bMpeg4GovState = M4OSA_FALSE;
143
144 pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE;
145 pClipCtxt->pAudioFramePtr = M4OSA_NULL;
146 pClipCtxt->iAudioFrameCts = 0;
147 pClipCtxt->pAudioDecCtxt = 0;
148 pClipCtxt->AudioDecBufferOut.m_bufferSize = 0;
149 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
150
151 pClipCtxt->pFileReadPtrFct = pFileReadPtrFct;
152 pClipCtxt->pPlaneYuv = M4OSA_NULL;
153 pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL;
154 pClipCtxt->m_pPreResizeFrame = M4OSA_NULL;
155 pClipCtxt->bGetYuvDataFromDecoder = M4OSA_TRUE;
156
157 /*
158 * Reset pointers for media and codecs interfaces */
159 err = M4VSS3GPP_clearInterfaceTables(&pClipCtxt->ShellAPI);
160 M4ERR_CHECK_RETURN(err);
161
162 /*
163 * Call the media and codecs subscription module */
164 err = M4VSS3GPP_subscribeMediaAndCodec(&pClipCtxt->ShellAPI);
165 M4ERR_CHECK_RETURN(err);
166
167 return M4NO_ERROR;
168 }
169
170 /* Note: if the clip is opened in fast mode, it can only be used for analysis and nothing else. */
M4VSS3GPP_intClipOpen(M4VSS3GPP_ClipContext * pClipCtxt,M4VSS3GPP_ClipSettings * pClipSettings,M4OSA_Bool bSkipAudioTrack,M4OSA_Bool bFastOpenMode,M4OSA_Bool bAvoidOpeningVideoDec)171 M4OSA_ERR M4VSS3GPP_intClipOpen( M4VSS3GPP_ClipContext *pClipCtxt,
172 M4VSS3GPP_ClipSettings *pClipSettings, M4OSA_Bool bSkipAudioTrack,
173 M4OSA_Bool bFastOpenMode, M4OSA_Bool bAvoidOpeningVideoDec )
174 {
175 M4OSA_ERR err;
176 M4READER_MediaFamily mediaFamily;
177 M4_StreamHandler *pStreamHandler;
178 M4_StreamHandler dummyStreamHandler;
179 M4OSA_Int32 iDuration;
180 M4OSA_Void *decoderUserData;
181 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
182
183 M4DECODER_MPEG4_DecoderConfigInfo dummy;
184 M4DECODER_VideoSize videoSizeFromDSI;
185 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
186
187 M4DECODER_OutputFilter FilterOption;
188 M4OSA_Char pTempFile[100];
189
190 /**
191 * Check input parameters */
192 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
193 "M4VSS3GPP_intClipOpen: pClipCtxt is M4OSA_NULL");
194 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER,
195 "M4VSS3GPP_intClipOpen: pClipSettings is M4OSA_NULL");
196
197 M4OSA_TRACE3_2(
198 "M4VSS3GPP_intClipOpen: called with pClipCtxt: 0x%x, bAvoidOpeningVideoDec=0x%x",
199 pClipCtxt, bAvoidOpeningVideoDec);
200 /**
201 * Keep a pointer to the clip settings. Remember that we don't possess it! */
202 pClipCtxt->pSettings = pClipSettings;
203 if(M4VIDEOEDITING_kFileType_ARGB8888 == pClipCtxt->pSettings->FileType) {
204 M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen: Image stream; set current vid dec");
205 err = M4VSS3GPP_setCurrentVideoDecoder(
206 &pClipCtxt->ShellAPI, M4DA_StreamTypeVideoARGB8888);
207 M4ERR_CHECK_RETURN(err);
208
209 decoderUserData = M4OSA_NULL;
210
211 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate(
212 &pClipCtxt->pViDecCtxt,
213 &dummyStreamHandler,
214 pClipCtxt->ShellAPI.m_pReader,
215 pClipCtxt->ShellAPI.m_pReaderDataIt,
216 &pClipCtxt->VideoAU,
217 decoderUserData);
218
219 if (M4NO_ERROR != err) {
220 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: \
221 m_pVideoDecoder->m_pFctCreate returns 0x%x", err);
222 return err;
223 }
224 M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: \
225 Vid dec started; pViDecCtxt=0x%x", pClipCtxt->pViDecCtxt);
226
227 return M4NO_ERROR;
228 }
229
230 /**
231 * Get the correct reader interface */
232 err = M4VSS3GPP_setCurrentReader(&pClipCtxt->ShellAPI,
233 pClipCtxt->pSettings->FileType);
234 M4ERR_CHECK_RETURN(err);
235
236 /**
237 * Init the 3GPP or MP3 reader */
238 err =
239 pClipCtxt->ShellAPI.m_pReader->m_pFctCreate(&pClipCtxt->pReaderContext);
240
241 if( M4NO_ERROR != err )
242 {
243 M4OSA_TRACE1_1(
244 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctCreate returns 0x%x",
245 err);
246 return err;
247 }
248
249 /**
250 * Link the reader interface to the reader context (used by the decoder to know the reader) */
251 pClipCtxt->ShellAPI.m_pReaderDataIt->m_readerContext =
252 pClipCtxt->pReaderContext;
253
254 /**
255 * Set the OSAL read function set */
256 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
257 pClipCtxt->pReaderContext,
258 M4READER_kOptionID_SetOsaFileReaderFctsPtr,
259 (M4OSA_DataOption)(pClipCtxt->pFileReadPtrFct));
260
261 if( M4NO_ERROR != err )
262 {
263 M4OSA_TRACE1_1(
264 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption returns 0x%x",
265 err);
266 return err;
267 }
268
269 /**
270 * Set the fast open mode if asked (3GPP only) */
271 if( M4VIDEOEDITING_kFileType_3GPP == pClipCtxt->pSettings->FileType )
272 {
273 if( M4OSA_TRUE == bFastOpenMode )
274 {
275 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
276 pClipCtxt->pReaderContext,
277 M4READER_3GP_kOptionID_FastOpenMode, M4OSA_NULL);
278
279 if( M4NO_ERROR != err )
280 {
281 M4OSA_TRACE1_1(
282 "M4VSS3GPP_intClipOpen():\
283 m_pReader->m_pFctSetOption(FastOpenMode) returns 0x%x",
284 err);
285 return err;
286 }
287 }
288
289 /**
290 * Set the skip audio option if asked */
291 if( M4OSA_TRUE == bSkipAudioTrack )
292 {
293 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
294 pClipCtxt->pReaderContext,
295 M4READER_3GP_kOptionID_VideoOnly, M4OSA_NULL);
296
297 if( M4NO_ERROR != err )
298 {
299 M4OSA_TRACE1_1(
300 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption(VideoOnly) returns 0x%x",
301 err);
302 return err;
303 }
304 }
305 }
306 if(pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM)
307 {
308
309
310
311
312 M4OSA_chrNCopy(pTempFile,pClipSettings->pFile,strlen(pClipSettings->pFile));
313
314
315 switch (pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency)
316 {
317 case 8000:
318 strncat((char *)pTempFile,(const char *)"_8000",6);
319 break;
320 case 11025:
321 strncat((char *)pTempFile,(const char *)"_11025",6);
322 break;
323 case 12000:
324 strncat((char *)pTempFile,(const char *)"_12000",6);
325 break;
326 case 16000:
327 strncat((char *)pTempFile,(const char *)"_16000",6);
328 break;
329 case 22050:
330 strncat((char *)pTempFile,(const char *)"_22050",6);
331 break;
332 case 24000:
333 strncat((char *)pTempFile,(const char *)"_24000",6);
334 break;
335 case 32000:
336 strncat((char *)pTempFile,(const char *)"_32000",6);
337 break;
338 case 44100:
339 strncat((char *)pTempFile,(const char *)"_44100",6);
340 break;
341 case 48000:
342 strncat((char *)pTempFile,(const char *)"_48000",6);
343 break;
344 default:
345 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG tracksampling \
346 frequency (%d Hz), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"\
347 ,pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency );
348 return M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY;
349 }
350
351
352
353 //M4OSA_chrNCat(pTempFile,
354 // itoa(pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency),5);
355 switch(pClipCtxt->pSettings->ClipProperties.uiNbChannels)
356 {
357 case 1:
358 strncat((char *)pTempFile,(const char *)"_1.pcm",6);
359 break;
360 case 2:
361 strncat((char *)pTempFile,(const char *)"_2.pcm",6);
362 break;
363 default:
364 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG track no.\
365 of channels (%d ), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS",\
366 pClipCtxt->pSettings->ClipProperties.uiNbChannels);
367 return M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS;
368 }
369 //M4OSA_chrNCat(pTempFile,itoa(pClipCtxt->pSettings->ClipProperties.uiNbChannels),1);
370
371 err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext, pTempFile);
372
373 }
374 else
375 {
376 /**
377 * Open the 3GPP/MP3 clip file */
378 err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext,
379 pClipSettings->pFile);
380 }
381 if( M4NO_ERROR != err )
382 {
383 M4OSA_UInt32 uiDummy, uiCoreId;
384 M4OSA_TRACE1_1(
385 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctOpen returns 0x%x", err);
386
387 /**
388 * If the error is from the core reader, we change it to a public VSS3GPP error */
389 M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
390
391 if( M4MP4_READER == uiCoreId )
392 {
393 M4OSA_TRACE1_0(
394 "M4VSS3GPP_intClipOpen(): returning M4VSS3GPP_ERR_INVALID_3GPP_FILE");
395 return M4VSS3GPP_ERR_INVALID_3GPP_FILE;
396 }
397 return err;
398 }
399
400 /**
401 * Get the audio and video streams */
402 while( err == M4NO_ERROR )
403 {
404 err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetNextStream(
405 pClipCtxt->pReaderContext, &mediaFamily, &pStreamHandler);
406
407 /*in case we found a BIFS stream or something else...*/
408 if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
409 || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) )
410 {
411 err = M4NO_ERROR;
412 continue;
413 }
414
415 if( M4NO_ERROR == err ) /**< One stream found */
416 {
417 /**
418 * Found a video stream */
419 if( ( mediaFamily == M4READER_kMediaFamilyVideo)
420 && (M4OSA_NULL == pClipCtxt->pVideoStream) )
421 {
422 if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType)
423 || (M4DA_StreamTypeVideoMpeg4
424 == pStreamHandler->m_streamType)
425 || (M4DA_StreamTypeVideoMpeg4Avc
426 == pStreamHandler->m_streamType) )
427 {
428 M4OSA_TRACE3_1(
429 "M4VSS3GPP_intClipOpen():\
430 Found a H263 or MPEG-4 or H264 video stream in input 3gpp clip; %d",
431 pStreamHandler->m_streamType);
432
433 /**
434 * Keep pointer to the video stream */
435 pClipCtxt->pVideoStream =
436 (M4_VideoStreamHandler *)pStreamHandler;
437 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
438
439 /**
440 * Reset the stream reader */
441 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
442 pClipCtxt->pReaderContext,
443 (M4_StreamHandler *)pClipCtxt->pVideoStream);
444
445 if( M4NO_ERROR != err )
446 {
447 M4OSA_TRACE1_1(
448 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(video) returns 0x%x",
449 err);
450 return err;
451 }
452
453 /**
454 * Initializes an access Unit */
455 err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct(
456 pClipCtxt->pReaderContext,
457 (M4_StreamHandler *)pClipCtxt->pVideoStream,
458 &pClipCtxt->VideoAU);
459
460 if( M4NO_ERROR != err )
461 {
462 M4OSA_TRACE1_1(
463 "M4VSS3GPP_intClipOpen():\
464 m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
465 err);
466 return err;
467 }
468 }
469 else /**< Not H263 or MPEG-4 (H264, etc.) */
470 {
471 M4OSA_TRACE1_1(
472 "M4VSS_editClipOpen():\
473 Found an unsupported video stream (0x%x) in input 3gpp clip",
474 pStreamHandler->m_streamType);
475
476 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
477 }
478 }
479 /**
480 * Found an audio stream */
481 else if( ( mediaFamily == M4READER_kMediaFamilyAudio)
482 && (M4OSA_NULL == pClipCtxt->pAudioStream) )
483 {
484 if( ( M4DA_StreamTypeAudioAmrNarrowBand
485 == pStreamHandler->m_streamType)
486 || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType)
487 || (M4DA_StreamTypeAudioMp3
488 == pStreamHandler->m_streamType)
489 || (M4DA_StreamTypeAudioEvrc
490 == pStreamHandler->m_streamType)
491 || (M4DA_StreamTypeAudioPcm
492 == pStreamHandler->m_streamType) )
493 {
494 M4OSA_TRACE3_1(
495 "M4VSS3GPP_intClipOpen(): \
496 Found an AMR-NB or AAC or MP3 audio stream in input clip; %d",
497 pStreamHandler->m_streamType);
498
499 /**
500 * Keep pointer to the audio stream */
501 pClipCtxt->pAudioStream =
502 (M4_AudioStreamHandler *)pStreamHandler;
503 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
504
505 /**
506 * Reset the stream reader */
507 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
508 pClipCtxt->pReaderContext,
509 (M4_StreamHandler *)pClipCtxt->pAudioStream);
510
511 if( M4NO_ERROR != err )
512 {
513 M4OSA_TRACE1_1(
514 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(audio) returns 0x%x",
515 err);
516 return err;
517 }
518
519 /**
520 * Initializes an access Unit */
521 err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct(
522 pClipCtxt->pReaderContext,
523 (M4_StreamHandler *)pClipCtxt->pAudioStream,
524 &pClipCtxt->AudioAU);
525
526 if( M4NO_ERROR != err )
527 {
528 M4OSA_TRACE1_1(
529 "M4VSS3GPP_intClipOpen():\
530 m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
531 err);
532 return err;
533 }
534 }
535 else /**< Not AMR-NB or AAC (AMR-WB...) */
536 {
537 M4OSA_TRACE1_1(
538 "M4VSS3GPP_intClipOpen():\
539 Found an unsupported audio stream (0x%x) in input 3gpp/mp3 clip",
540 pStreamHandler->m_streamType);
541
542 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
543 }
544 }
545 }
546 else if( M4OSA_ERR_IS_ERROR(err) )
547 {
548 M4OSA_TRACE1_1(
549 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctGetNextStream() returns 0x%x!",
550 err);
551 return err;
552 }
553 }
554
555 /**
556 * Init Video decoder */
557 if( M4OSA_NULL != pClipCtxt->pVideoStream )
558 {
559 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
560 /* If external decoders are possible, it's best to avoid opening the decoder if the clip is only
561 going to be used for analysis, as we're not going to use it for the analysis in the case of a
562 possible external decoder anyway, and either there could be no decoder at this point or the HW
563 decoder could be present, which we want to avoid opening for that. See comments in
564 intBuildAnalysis for more details. */
565
566 /* CHANGEME Temporarily only do this for MPEG4, since for now only MPEG4 external decoders are
567 supported, and the following wouldn't work for H263 so a release where external decoders are
568 possible, but not used, wouldn't work with H263 stuff. */
569
570 if( bAvoidOpeningVideoDec && M4DA_StreamTypeVideoMpeg4
571 == pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
572 {
573 /* Oops! The mere act of opening the decoder also results in the image size being
574 filled in the video stream! Compensate for this by using ParseVideoDSI to fill
575 this info. */
576 M4OSA_TRACE3_0(
577 "M4VSS3GPP_intClipOpen: Mpeg4 stream; vid dec not started");
578 err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream->
579 m_basicProperties.m_pDecoderSpecificInfo,
580 pClipCtxt->pVideoStream->
581 m_basicProperties.m_decoderSpecificInfoSize,
582 &dummy, &videoSizeFromDSI);
583
584 pClipCtxt->pVideoStream->m_videoWidth = videoSizeFromDSI.m_uiWidth;
585 pClipCtxt->pVideoStream->m_videoHeight =
586 videoSizeFromDSI.m_uiHeight;
587 }
588 else
589 {
590
591 #endif
592
593 M4OSA_TRACE3_0(
594 "M4VSS3GPP_intClipOpen: Mp4/H263/H264 stream; set current vid dec");
595 err = M4VSS3GPP_setCurrentVideoDecoder(&pClipCtxt->ShellAPI,
596 pClipCtxt->pVideoStream->m_basicProperties.m_streamType);
597 M4ERR_CHECK_RETURN(err);
598
599 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
600
601 decoderUserData =
602 pClipCtxt->ShellAPI.m_pCurrentVideoDecoderUserData;
603
604 #else
605
606 decoderUserData = M4OSA_NULL;
607
608 #endif
609
610 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate(
611 &pClipCtxt->pViDecCtxt,
612 &pClipCtxt->pVideoStream->m_basicProperties,
613 pClipCtxt->ShellAPI.m_pReader,
614 pClipCtxt->ShellAPI.m_pReaderDataIt,
615 &pClipCtxt->VideoAU, decoderUserData);
616
617 if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err)
618 || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) )
619 {
620 /**
621 * Our decoder is not compatible with H263 profile other than 0.
622 * So it returns this internal error code.
623 * We translate it to our own error code */
624 return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED;
625 }
626 else if( M4NO_ERROR != err )
627 {
628 M4OSA_TRACE1_1(
629 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctCreate returns 0x%x",
630 err);
631 return err;
632 }
633 M4OSA_TRACE3_1(
634 "M4VSS3GPP_intClipOpen: Vid dec started; pViDecCtxt=0x%x",
635 pClipCtxt->pViDecCtxt);
636
637 if( M4DA_StreamTypeVideoMpeg4Avc
638 == pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
639 {
640 FilterOption.m_pFilterFunction =
641 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420;
642 FilterOption.m_pFilterUserData = M4OSA_NULL;
643 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
644 pClipCtxt->pViDecCtxt, M4DECODER_kOptionID_OutputFilter,
645 (M4OSA_DataOption) &FilterOption);
646
647 if( M4NO_ERROR != err )
648 {
649 M4OSA_TRACE1_1(
650 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption returns 0x%x",
651 err);
652 return err;
653 }
654 else
655 {
656 M4OSA_TRACE3_0(
657 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption\
658 M4DECODER_kOptionID_OutputFilter OK");
659 }
660 }
661 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
662
663 }
664
665 #endif
666
667 }
668
669 /**
670 * Init Audio decoder */
671 if( M4OSA_NULL != pClipCtxt->pAudioStream )
672 {
673 err = M4VSS3GPP_intClipPrepareAudioDecoder(pClipCtxt);
674 M4ERR_CHECK_RETURN(err);
675 M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: Audio dec started; context=0x%x",
676 pClipCtxt->pAudioDecCtxt);
677 }
678 else
679 {
680 pClipCtxt->AudioAU.m_streamID = 0;
681 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
682 pClipCtxt->AudioAU.m_size = 0;
683 pClipCtxt->AudioAU.m_CTS = 0;
684 pClipCtxt->AudioAU.m_DTS = 0;
685 pClipCtxt->AudioAU.m_attribute = 0;
686 pClipCtxt->AudioAU.m_maxsize = 0;
687 pClipCtxt->AudioAU.m_structSize = sizeof(pClipCtxt->AudioAU);
688 }
689
690 /**
691 * Get the duration of the longest stream */
692 if( M4OSA_TRUE == pClipCtxt->pSettings->ClipProperties.bAnalysed )
693 {
694 /* If already calculated set it to previous value */
695 /* Because fast open and full open can return a different value,
696 it can mismatch user settings */
697 /* Video track is more important than audio track (if video track is shorter than
698 audio track, it can led to cut larger than expected) */
699 iDuration = pClipCtxt->pSettings->ClipProperties.uiClipVideoDuration;
700
701 if( iDuration == 0 )
702 {
703 iDuration = pClipCtxt->pSettings->ClipProperties.uiClipDuration;
704 }
705 }
706 else
707 {
708 /* Else compute it from streams */
709 iDuration = 0;
710
711 if( M4OSA_NULL != pClipCtxt->pVideoStream )
712 {
713 iDuration = (M4OSA_Int32)(
714 pClipCtxt->pVideoStream->m_basicProperties.m_duration);
715 }
716
717 if( ( M4OSA_NULL != pClipCtxt->pAudioStream) && ((M4OSA_Int32)(
718 pClipCtxt->pAudioStream->m_basicProperties.m_duration)
719 > iDuration) && iDuration == 0 )
720 {
721 iDuration = (M4OSA_Int32)(
722 pClipCtxt->pAudioStream->m_basicProperties.m_duration);
723 }
724 }
725
726 /**
727 * If end time is not used, we set it to the video track duration */
728 if( 0 == pClipCtxt->pSettings->uiEndCutTime )
729 {
730 pClipCtxt->pSettings->uiEndCutTime = (M4OSA_UInt32)iDuration;
731 }
732
733 pClipCtxt->iEndTime = (M4OSA_Int32)pClipCtxt->pSettings->uiEndCutTime;
734
735 /**
736 * Return with no error */
737 M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen(): returning M4NO_ERROR");
738 return M4NO_ERROR;
739 }
740
741 /**
742 ******************************************************************************
743 * M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack()
744 * @brief Delete the audio track. Clip will be like if it had no audio track
745 * @note
746 * @param pClipCtxt (IN) Internal clip context
747 ******************************************************************************
748 */
M4VSS3GPP_intClipDeleteAudioTrack(M4VSS3GPP_ClipContext * pClipCtxt)749 M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack( M4VSS3GPP_ClipContext *pClipCtxt )
750 {
751 /**
752 * But we don't have to free the audio stream. It will be freed by the reader when closing it*/
753 pClipCtxt->pAudioStream = M4OSA_NULL;
754
755 /**
756 * We will return a constant silence AMR AU.
757 * We set it here once, instead of at each read audio step. */
758 pClipCtxt->pAudioFramePtr = (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
759 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
760
761 /**
762 * Free the decoded audio buffer (it needs to be re-allocated to store silence
763 frame eventually)*/
764 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
765 {
766 free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
767 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
768 }
769
770 return;
771 }
772
773 /**
774 ******************************************************************************
775 * M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCurrentTime()
776 * @brief Jump to the previous RAP and decode up to the current video time
777 * @param pClipCtxt (IN) Internal clip context
778 * @param iCts (IN) Target CTS
779 ******************************************************************************
780 */
M4VSS3GPP_intClipDecodeVideoUpToCts(M4VSS3GPP_ClipContext * pClipCtxt,M4OSA_Int32 iCts)781 M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCts( M4VSS3GPP_ClipContext *pClipCtxt,
782 M4OSA_Int32 iCts )
783 {
784 M4OSA_Int32 iRapCts, iClipCts;
785 M4_MediaTime dDecodeTime;
786 M4OSA_Bool bClipJump = M4OSA_FALSE;
787 M4OSA_ERR err;
788
789 /**
790 * Compute the time in the clip base */
791 iClipCts = iCts - pClipCtxt->iVoffset;
792
793 /**
794 * If we were reading the clip, we must jump to the previous RAP
795 * to decode from that point. */
796 if( M4VSS3GPP_kClipStatus_READ == pClipCtxt->Vstatus )
797 {
798 /**
799 * The decoder must be told to jump */
800 bClipJump = M4OSA_TRUE;
801 pClipCtxt->iVideoDecCts = iClipCts;
802
803 /**
804 * Remember the clip reading state */
805 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE_UP_TO;
806 }
807
808 /**
809 * If we are in decodeUpTo() process, check if we need to do
810 one more step or if decoding is finished */
811 if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pClipCtxt->Vstatus )
812 {
813 /* Do a step of 500 ms decoding */
814 pClipCtxt->iVideoDecCts += 500;
815
816 if( pClipCtxt->iVideoDecCts > iClipCts )
817 {
818 /* Target time reached, we switch back to DECODE mode */
819 pClipCtxt->iVideoDecCts = iClipCts;
820 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE;
821 }
822
823 M4OSA_TRACE2_1("c ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts);
824 }
825 else
826 {
827 /* Just decode at current clip cts */
828 pClipCtxt->iVideoDecCts = iClipCts;
829
830 M4OSA_TRACE2_1("d ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts);
831 }
832
833 /**
834 * Decode up to the target */
835 M4OSA_TRACE3_2(
836 "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f, pClipCtxt=0x%x",
837 dDecodeTime, pClipCtxt);
838
839 dDecodeTime = (M4OSA_Double)pClipCtxt->iVideoDecCts;
840 pClipCtxt->isRenderDup = M4OSA_FALSE;
841 err =
842 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDecode(pClipCtxt->pViDecCtxt,
843 &dDecodeTime, bClipJump, 0);
844
845 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
846 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
847 {
848 M4OSA_TRACE1_1(
849 "M4VSS3GPP_intClipDecodeVideoUpToCts: m_pFctDecode returns 0x%x!",
850 err);
851 return err;
852 }
853
854 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
855 {
856 pClipCtxt->isRenderDup = M4OSA_TRUE;
857 }
858
859 /**
860 * Return */
861 M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeVideoUpToCts: returning M4NO_ERROR");
862 return M4NO_ERROR;
863 }
864
865 /**
866 ******************************************************************************
867 * M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame()
868 * @brief Read one AU frame in the clip
869 * @note
870 * @param pClipCtxt (IN) Internal clip context
871 * @return M4NO_ERROR: No error
872 ******************************************************************************
873 */
M4VSS3GPP_intClipReadNextAudioFrame(M4VSS3GPP_ClipContext * pClipCtxt)874 M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame(
875 M4VSS3GPP_ClipContext *pClipCtxt )
876 {
877 M4OSA_ERR err;
878
879 /* ------------------------------ */
880 /* ---------- NO AUDIO ---------- */
881 /* ------------------------------ */
882
883 if( M4OSA_NULL == pClipCtxt->pAudioStream )
884 {
885 /* If there is no audio track, we return silence AUs */
886 pClipCtxt->pAudioFramePtr =
887 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
888 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
889 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
890
891 M4OSA_TRACE2_0("b #### blank track");
892 }
893
894 /* ---------------------------------- */
895 /* ---------- AMR-NB, EVRC ---------- */
896 /* ---------------------------------- */
897
898 else if( ( M4VIDEOEDITING_kAMR_NB
899 == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
900 || (M4VIDEOEDITING_kEVRC
901 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
902 {
903 if( M4OSA_FALSE == pClipCtxt->bAudioFrameAvailable )
904 {
905 /**
906 * No AU available, so we must must read one from the original track reader */
907 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
908 pClipCtxt->pReaderContext,
909 (M4_StreamHandler *)pClipCtxt->pAudioStream,
910 &pClipCtxt->AudioAU);
911
912 if( M4NO_ERROR == err )
913 {
914 /**
915 * Set the current AMR frame position at the beginning of the read AU */
916 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
917
918 /**
919 * Set the AMR frame CTS */
920 pClipCtxt->iAudioFrameCts =
921 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS
922 * pClipCtxt->scale_audio + 0.5);
923 }
924 else if( ( M4WAR_NO_MORE_AU == err) && (M4VIDEOEDITING_kAMR_NB
925 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
926 {
927 /**
928 * If there is less audio than the stream duration indicated,
929 * we return silence at the end of the stream. */
930 pClipCtxt->pAudioFramePtr =
931 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
932 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
933 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
934
935 M4OSA_TRACE2_0("a #### silence AU");
936
937 /**
938 * Return with M4WAR_NO_MORE_AU */
939 M4OSA_TRACE3_0(
940 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: \
941 returning M4WAR_NO_MORE_AU (silence)");
942 return M4WAR_NO_MORE_AU;
943 }
944 else /**< fatal error (or no silence in EVRC) */
945 {
946 M4OSA_TRACE3_1(
947 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: m_pFctGetNextAu() returns 0x%x",
948 err);
949 return err;
950 }
951 }
952 else /* bAudioFrameAvailable */
953 {
954 /**
955 * Go to the next AMR frame in the AU */
956 pClipCtxt->pAudioFramePtr += pClipCtxt->uiAudioFrameSize;
957
958 /**
959 * Increment CTS: one AMR frame is 20 ms long */
960 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
961 }
962
963 /**
964 * Get the size of the pointed AMR frame */
965 switch( pClipCtxt->pSettings->ClipProperties.AudioStreamType )
966 {
967 case M4VIDEOEDITING_kAMR_NB:
968 pClipCtxt->uiAudioFrameSize =
969 (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_AMRNB(
970 pClipCtxt->pAudioFramePtr);
971 break;
972
973 case M4VIDEOEDITING_kEVRC:
974 pClipCtxt->uiAudioFrameSize =
975 (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_EVRC(
976 pClipCtxt->pAudioFramePtr);
977 break;
978 default:
979 break;
980 }
981
982 if( 0 == pClipCtxt->uiAudioFrameSize )
983 {
984 M4OSA_TRACE3_0(
985 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size == 0,\
986 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU");
987 return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU;
988 }
989 else if( pClipCtxt->uiAudioFrameSize > pClipCtxt->AudioAU.m_size )
990 {
991 M4OSA_TRACE3_0(
992 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size greater than AU size!,\
993 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU");
994 return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU;
995 }
996
997 /**
998 * Check if the end of the current AU has been reached or not */
999 if( ( pClipCtxt->pAudioFramePtr + pClipCtxt->uiAudioFrameSize)
1000 < (pClipCtxt->AudioAU.m_dataAddress + pClipCtxt->AudioAU.m_size) )
1001 {
1002 pClipCtxt->bAudioFrameAvailable = M4OSA_TRUE;
1003 }
1004 else
1005 {
1006 pClipCtxt->bAudioFrameAvailable =
1007 M4OSA_FALSE; /**< will be used for next call */
1008 }
1009 }
1010
1011 /* ------------------------- */
1012 /* ---------- AAC ---------- */
1013 /* ------------------------- */
1014
1015 else if( ( M4VIDEOEDITING_kAAC
1016 == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
1017 || (M4VIDEOEDITING_kAACplus
1018 == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
1019 || (M4VIDEOEDITING_keAACplus
1020 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
1021 {
1022 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
1023 pClipCtxt->pReaderContext,
1024 (M4_StreamHandler *)pClipCtxt->pAudioStream,
1025 &pClipCtxt->AudioAU);
1026
1027 if( M4NO_ERROR == err )
1028 {
1029 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
1030 pClipCtxt->uiAudioFrameSize =
1031 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
1032 pClipCtxt->iAudioFrameCts =
1033 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
1034 + 0.5);
1035
1036 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
1037 /* (cts is not an integer with frequency 24 kHz for example) */
1038 pClipCtxt->iAudioFrameCts = ( ( pClipCtxt->iAudioFrameCts
1039 + pClipCtxt->iSilenceFrameDuration / 2)
1040 / pClipCtxt->iSilenceFrameDuration)
1041 * pClipCtxt->iSilenceFrameDuration;
1042 }
1043 else if( M4WAR_NO_MORE_AU == err )
1044 {
1045 /**
1046 * If there is less audio than the stream duration indicated,
1047 * we return silence at the end of the stream. */
1048 pClipCtxt->pAudioFramePtr =
1049 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
1050 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
1051 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
1052
1053 M4OSA_TRACE2_0("a #### silence AU");
1054
1055 /**
1056 * Return with M4WAR_NO_MORE_AU */
1057 M4OSA_TRACE3_0(
1058 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC:\
1059 returning M4WAR_NO_MORE_AU (silence)");
1060 return M4WAR_NO_MORE_AU;
1061 }
1062 else /**< fatal error */
1063 {
1064 M4OSA_TRACE3_1(
1065 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC: m_pFctGetNextAu() returns 0x%x",
1066 err);
1067 return err;
1068 }
1069 }
1070
1071 /* --------------------------------- */
1072 /* ---------- MP3, others ---------- */
1073 /* --------------------------------- */
1074
1075 else
1076 {
1077 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
1078 pClipCtxt->pReaderContext,
1079 (M4_StreamHandler *)pClipCtxt->pAudioStream,
1080 &pClipCtxt->AudioAU);
1081
1082 if( M4NO_ERROR != err )
1083 {
1084 M4OSA_TRACE3_1(
1085 "M4VSS3GPP_intClipReadNextAudioFrame()-MP3: m_pFctGetNextAu() returns 0x%x",
1086 err);
1087 return err;
1088 }
1089
1090 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
1091 pClipCtxt->uiAudioFrameSize = (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
1092 pClipCtxt->iAudioFrameCts =
1093 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
1094 + 0.5);
1095 }
1096
1097 /**
1098 * Return with no error */
1099 M4OSA_TRACE3_0(
1100 "M4VSS3GPP_intClipReadNextAudioFrame(): returning M4NO_ERROR");
1101
1102 return M4NO_ERROR;
1103 }
1104
1105 /**
1106 ******************************************************************************
1107 * M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder()
1108 * @brief Creates and initialize the audio decoder for the clip.
1109 * @note
1110 * @param pClipCtxt (IN) internal clip context
1111 * @return M4NO_ERROR: No error
1112 ******************************************************************************
1113 */
M4VSS3GPP_intClipPrepareAudioDecoder(M4VSS3GPP_ClipContext * pClipCtxt)1114 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder(
1115 M4VSS3GPP_ClipContext *pClipCtxt )
1116 {
1117 M4OSA_ERR err = M4NO_ERROR;
1118 M4_StreamType audiotype;
1119 #ifdef M4VSS_SUPPORT_OMX_CODECS
1120
1121 M4_AACType iAacType = 0;
1122
1123 #endif
1124
1125 /**
1126 * Set the proper audio decoder */
1127
1128 audiotype = pClipCtxt->pAudioStream->m_basicProperties.m_streamType;
1129
1130 //EVRC
1131 if( M4DA_StreamTypeAudioEvrc
1132 != audiotype ) /* decoder not supported yet, but allow to do null encoding */
1133
1134 err = M4VSS3GPP_setCurrentAudioDecoder(&pClipCtxt->ShellAPI, audiotype);
1135 M4ERR_CHECK_RETURN(err);
1136
1137 /**
1138 * Creates the audio decoder */
1139 if( M4OSA_NULL == pClipCtxt->ShellAPI.m_pAudioDecoder )
1140 {
1141 M4OSA_TRACE1_0(
1142 "M4VSS3GPP_intClipPrepareAudioDecoder(): Fails to initiate the audio decoder.");
1143 return M4VSS3GPP_ERR_AUDIO_DECODER_INIT_FAILED;
1144 }
1145
1146 if( M4OSA_NULL == pClipCtxt->pAudioDecCtxt )
1147 {
1148 #ifdef M4VSS_SUPPORT_OMX_CODECS
1149
1150 if( M4OSA_TRUE == pClipCtxt->ShellAPI.bAllowFreeingOMXCodecInterface )
1151 {
1152 if( M4DA_StreamTypeAudioAac == audiotype ) {
1153 err = M4VSS3GPP_intCheckAndGetCodecAacProperties(
1154 pClipCtxt);
1155 } else if (M4DA_StreamTypeAudioPcm != audiotype) {
1156 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
1157 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
1158 M4OSA_NULL);
1159 } else {
1160 err = M4NO_ERROR;
1161 }
1162 if( M4NO_ERROR != err )
1163 {
1164 M4OSA_TRACE1_1(
1165 "M4VSS3GPP_intClipPrepareAudioDecoder: m_pAudioDecoder->m_pFctCreateAudioDec\
1166 returns 0x%x", err);
1167 return err;
1168 }
1169 }
1170 else
1171 {
1172 M4OSA_TRACE3_1(
1173 "M4VSS3GPP_intClipPrepareAudioDecoder:\
1174 Creating external audio decoder of type 0x%x", audiotype);
1175 /* External OMX codecs are used*/
1176 if( M4DA_StreamTypeAudioAac == audiotype )
1177 {
1178 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
1179 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
1180 pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData);
1181
1182 if( M4NO_ERROR == err )
1183 {
1184 /* AAC properties*/
1185 /*get from Reader; temporary, till Audio decoder shell API
1186 available to get the AAC properties*/
1187 pClipCtxt->AacProperties.aNumChan =
1188 pClipCtxt->pAudioStream->m_nbChannels;
1189 pClipCtxt->AacProperties.aSampFreq =
1190 pClipCtxt->pAudioStream->m_samplingFrequency;
1191
1192 err = pClipCtxt->ShellAPI.m_pAudioDecoder->
1193 m_pFctGetOptionAudioDec(pClipCtxt->pAudioDecCtxt,
1194 M4AD_kOptionID_StreamType,
1195 (M4OSA_DataOption) &iAacType);
1196
1197 if( M4NO_ERROR != err )
1198 {
1199 M4OSA_TRACE1_1(
1200 "M4VSS3GPP_intClipPrepareAudioDecoder:\
1201 m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", err);
1202 iAacType = M4_kAAC; //set to default
1203 err = M4NO_ERROR;
1204 }
1205 else {
1206 M4OSA_TRACE3_1(
1207 "M4VSS3GPP_intClipPrepareAudioDecoder: \
1208 m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d",
1209 iAacType);
1210 }
1211 switch( iAacType )
1212 {
1213 case M4_kAAC:
1214 pClipCtxt->AacProperties.aSBRPresent = 0;
1215 pClipCtxt->AacProperties.aPSPresent = 0;
1216 break;
1217
1218 case M4_kAACplus:
1219 pClipCtxt->AacProperties.aSBRPresent = 1;
1220 pClipCtxt->AacProperties.aPSPresent = 0;
1221 pClipCtxt->AacProperties.aExtensionSampFreq =
1222 pClipCtxt->pAudioStream->m_samplingFrequency;
1223 break;
1224
1225 case M4_keAACplus:
1226 pClipCtxt->AacProperties.aSBRPresent = 1;
1227 pClipCtxt->AacProperties.aPSPresent = 1;
1228 pClipCtxt->AacProperties.aExtensionSampFreq =
1229 pClipCtxt->pAudioStream->m_samplingFrequency;
1230 break;
1231 default:
1232 break;
1233 }
1234 M4OSA_TRACE3_2(
1235 "M4VSS3GPP_intClipPrepareAudioDecoder: AAC NBChans=%d, SamplFreq=%d",
1236 pClipCtxt->AacProperties.aNumChan,
1237 pClipCtxt->AacProperties.aSampFreq);
1238 }
1239 }
1240 else
1241 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
1242 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
1243 pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData);
1244
1245 if( M4NO_ERROR != err )
1246 {
1247 M4OSA_TRACE1_1(
1248 "M4VSS3GPP_intClipPrepareAudioDecoder:\
1249 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
1250 err);
1251 return err;
1252 }
1253 }
1254
1255 #else
1256 /* Trick, I use pUserData to retrieve aac properties,
1257 waiting for some better implementation... */
1258
1259 if( M4DA_StreamTypeAudioAac == audiotype )
1260 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
1261 &pClipCtxt->pAudioDecCtxt,
1262 pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties));
1263 else
1264 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
1265 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
1266 M4OSA_NULL /* to be changed with HW interfaces */);
1267
1268 if( M4NO_ERROR != err )
1269 {
1270 M4OSA_TRACE1_1(
1271 "M4VSS3GPP_intClipPrepareAudioDecoder:\
1272 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
1273 err);
1274 return err;
1275 }
1276
1277 #endif
1278
1279 }
1280
1281 if( M4DA_StreamTypeAudioAmrNarrowBand == audiotype ) {
1282 /* AMR DECODER CONFIGURATION */
1283
1284 /* nothing specific to do */
1285 }
1286 else if( M4DA_StreamTypeAudioEvrc == audiotype ) {
1287 /* EVRC DECODER CONFIGURATION */
1288
1289 /* nothing specific to do */
1290 }
1291 else if( M4DA_StreamTypeAudioMp3 == audiotype ) {
1292 /* MP3 DECODER CONFIGURATION */
1293
1294 /* nothing specific to do */
1295 }
1296 else if( M4DA_StreamTypeAudioAac == audiotype )
1297 {
1298 /* AAC DECODER CONFIGURATION */
1299
1300 /* Decode high quality aac but disable PS and SBR */
1301 /* Because we have to mix different kind of AAC so we must take the lowest capability */
1302 /* In MCS it was not needed because there is only one stream */
1303 M4_AacDecoderConfig AacDecParam;
1304
1305 AacDecParam.m_AACDecoderProfile = AAC_kAAC;
1306 AacDecParam.m_DownSamplingMode = AAC_kDS_OFF;
1307
1308 if( M4ENCODER_kMono == pClipCtxt->pAudioStream->m_nbChannels )
1309 {
1310 AacDecParam.m_OutputMode = AAC_kMono;
1311 }
1312 else
1313 {
1314 AacDecParam.m_OutputMode = AAC_kStereo;
1315 }
1316
1317 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
1318 pClipCtxt->pAudioDecCtxt,
1319 M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam);
1320 }
1321
1322 if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec ) {
1323 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
1324 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface,
1325 (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt);
1326
1327 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
1328 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU,
1329 (M4OSA_DataOption) &pClipCtxt->AudioAU);
1330 }
1331
1332 if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec )
1333 {
1334 /* Not implemented in all decoders */
1335 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec(
1336 pClipCtxt->pAudioDecCtxt);
1337
1338 if( M4NO_ERROR != err )
1339 {
1340 M4OSA_TRACE1_1(
1341 "M4VSS3GPP_intClipPrepareAudioDecoder:\
1342 m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x",
1343 err);
1344 return err;
1345 }
1346 }
1347
1348 /**
1349 * Allocate output buffer for the audio decoder */
1350 pClipCtxt->AudioDecBufferOut.m_bufferSize =
1351 pClipCtxt->pAudioStream->m_byteFrameLength
1352 * pClipCtxt->pAudioStream->m_byteSampleSize
1353 * pClipCtxt->pAudioStream->m_nbChannels;
1354 pClipCtxt->AudioDecBufferOut.m_dataAddress =
1355 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pClipCtxt->AudioDecBufferOut.m_bufferSize
1356 * sizeof(M4OSA_Int16),
1357 M4VSS3GPP, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize");
1358
1359 if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress )
1360 {
1361 M4OSA_TRACE1_0(
1362 "M4VSS3GPP_intClipPrepareAudioDecoder():\
1363 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
1364 return M4ERR_ALLOC;
1365 }
1366
1367 return M4NO_ERROR;
1368 }
1369
1370 /**
1371 ******************************************************************************
1372 * M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame()
1373 * @brief Decode the current AUDIO frame.
1374 * @note
1375 * @param pClipCtxt (IN) internal clip context
1376 * @return M4NO_ERROR: No error
1377 ******************************************************************************
1378 */
M4VSS3GPP_intClipDecodeCurrentAudioFrame(M4VSS3GPP_ClipContext * pClipCtxt)1379 M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame(
1380 M4VSS3GPP_ClipContext *pClipCtxt )
1381 {
1382 M4OSA_ERR err;
1383
1384 /**
1385 * Silence mode */
1386 if( pClipCtxt->pSilenceFrameData
1387 == (M4OSA_UInt8 *)pClipCtxt->pAudioFramePtr )
1388 {
1389 if( pClipCtxt->AudioDecBufferOut.m_dataAddress == M4OSA_NULL )
1390 {
1391 /**
1392 * Allocate output buffer for the audio decoder */
1393 pClipCtxt->AudioDecBufferOut.m_bufferSize =
1394 pClipCtxt->uiSilencePcmSize;
1395 pClipCtxt->AudioDecBufferOut.m_dataAddress =
1396 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(
1397 pClipCtxt->AudioDecBufferOut.m_bufferSize
1398 * sizeof(M4OSA_Int16),
1399 M4VSS3GPP,(M4OSA_Char *) "AudioDecBufferOut.m_bufferSize");
1400
1401 if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress )
1402 {
1403 M4OSA_TRACE1_0(
1404 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\
1405 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
1406 return M4ERR_ALLOC;
1407 }
1408 }
1409
1410 /* Fill it with 0 (= pcm silence) */
1411 memset(pClipCtxt->AudioDecBufferOut.m_dataAddress,0,
1412 pClipCtxt->AudioDecBufferOut.m_bufferSize * sizeof(M4OSA_Int16));
1413 }
1414 else if (pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM)
1415 {
1416 pClipCtxt->AudioDecBufferIn.m_dataAddress = (M4OSA_MemAddr8) pClipCtxt->pAudioFramePtr;
1417 pClipCtxt->AudioDecBufferIn.m_bufferSize = pClipCtxt->uiAudioFrameSize;
1418
1419 memcpy((void *)pClipCtxt->AudioDecBufferOut.m_dataAddress,
1420 (void *)pClipCtxt->AudioDecBufferIn.m_dataAddress, pClipCtxt->AudioDecBufferIn.m_bufferSize);
1421 pClipCtxt->AudioDecBufferOut.m_bufferSize = pClipCtxt->AudioDecBufferIn.m_bufferSize;
1422 /**
1423 * Return with no error */
1424
1425 M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR");
1426 return M4NO_ERROR;
1427 }
1428 /**
1429 * Standard decoding mode */
1430 else
1431 {
1432 /**
1433 * Decode current AMR frame */
1434 if ( pClipCtxt->pAudioFramePtr != M4OSA_NULL ) {
1435 pClipCtxt->AudioDecBufferIn.m_dataAddress =
1436 (M4OSA_MemAddr8)pClipCtxt->pAudioFramePtr;
1437 pClipCtxt->AudioDecBufferIn.m_bufferSize =
1438 pClipCtxt->uiAudioFrameSize;
1439 pClipCtxt->AudioDecBufferIn.m_timeStampUs =
1440 (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL);
1441
1442 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
1443 pClipCtxt->pAudioDecCtxt,
1444 &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut,
1445 M4OSA_FALSE);
1446 } else {
1447 // Pass Null input buffer
1448 // Reader invoked from Audio decoder source
1449 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
1450 pClipCtxt->pAudioDecCtxt,
1451 M4OSA_NULL, &pClipCtxt->AudioDecBufferOut,
1452 M4OSA_FALSE);
1453 }
1454
1455 if( M4NO_ERROR != err )
1456 {
1457 M4OSA_TRACE1_1(
1458 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\
1459 m_pAudioDecoder->m_pFctStepAudio returns 0x%x",
1460 err);
1461 return err;
1462 }
1463 }
1464
1465 /**
1466 * Return with no error */
1467 M4OSA_TRACE3_0(
1468 "M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR");
1469 return M4NO_ERROR;
1470 }
1471
1472 /**
1473 ******************************************************************************
1474 * M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt()
1475 * @brief Jump in the audio track of the clip.
1476 * @note
1477 * @param pClipCtxt (IN) internal clip context
1478 * @param pJumpCts (IN/OUT) in:target CTS, out: reached CTS
1479 * @return M4NO_ERROR: No error
1480 ******************************************************************************
1481 */
M4VSS3GPP_intClipJumpAudioAt(M4VSS3GPP_ClipContext * pClipCtxt,M4OSA_Int32 * pJumpCts)1482 M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt( M4VSS3GPP_ClipContext *pClipCtxt,
1483 M4OSA_Int32 *pJumpCts )
1484 {
1485 M4OSA_ERR err;
1486 M4OSA_Int32 iTargetCts;
1487 M4OSA_Int32 iJumpCtsMs;
1488
1489 /**
1490 * Check input parameters */
1491 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
1492 "M4VSS3GPP_intClipJumpAudioAt: pClipCtxt is M4OSA_NULL");
1493 M4OSA_DEBUG_IF2((M4OSA_NULL == pJumpCts), M4ERR_PARAMETER,
1494 "M4VSS3GPP_intClipJumpAudioAt: pJumpCts is M4OSA_NULL");
1495
1496 iTargetCts = *pJumpCts;
1497
1498 /**
1499 * If there is no audio stream, we simulate a jump at the target jump CTS */
1500 if( M4OSA_NULL == pClipCtxt->pAudioStream )
1501 {
1502 /**
1503 * the target CTS will be reached at next ReadFrame call (thus the -20) */
1504 *pJumpCts = iTargetCts - pClipCtxt->iSilenceFrameDuration;
1505
1506 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
1507 /* (cts is not an integer with frequency 24 kHz for example) */
1508 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2)
1509 / pClipCtxt->iSilenceFrameDuration)
1510 * pClipCtxt->iSilenceFrameDuration;
1511 pClipCtxt->iAudioFrameCts =
1512 *
1513 pJumpCts; /* simulate a read at jump position for later silence AUs */
1514 }
1515 else
1516 {
1517 M4OSA_Int32 current_time = 0;
1518 M4OSA_Int32 loop_counter = 0;
1519
1520 if( (M4DA_StreamTypeAudioMp3
1521 == pClipCtxt->pAudioStream->m_basicProperties.m_streamType) )
1522 {
1523 while( ( loop_counter < M4VSS3GPP_MP3_JUMPED_AU_NUMBER_MAX)
1524 && (current_time < iTargetCts) )
1525 {
1526 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
1527 pClipCtxt->pReaderContext,
1528 (M4_StreamHandler *)pClipCtxt->pAudioStream,
1529 &pClipCtxt->AudioAU);
1530
1531 if( M4NO_ERROR != err )
1532 {
1533 M4OSA_TRACE3_1(
1534 "M4VSS3GPP_intClipJumpAudioAt: m_pFctGetNextAu() returns 0x%x",
1535 err);
1536 return err;
1537 }
1538
1539 current_time = (M4OSA_Int32)pClipCtxt->AudioAU.m_CTS;
1540 loop_counter++;
1541 }
1542
1543 /**
1544 * The current AU is stored */
1545 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
1546 pClipCtxt->uiAudioFrameSize =
1547 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
1548 pClipCtxt->iAudioFrameCts =
1549 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
1550 + 0.5);
1551
1552 *pJumpCts = pClipCtxt->iAudioFrameCts;
1553 }
1554 else
1555 {
1556 /**
1557 * Jump in the audio stream */
1558 iJumpCtsMs =
1559 (M4OSA_Int32)(*pJumpCts / pClipCtxt->scale_audio + 0.5);
1560
1561 err = pClipCtxt->ShellAPI.m_pReader->m_pFctJump(
1562 pClipCtxt->pReaderContext,
1563 (M4_StreamHandler *)pClipCtxt->pAudioStream,
1564 &iJumpCtsMs);
1565
1566 if( M4NO_ERROR != err )
1567 {
1568 M4OSA_TRACE1_1(
1569 "M4VSS3GPP_intClipJumpAudioAt(): m_pFctJump() returns 0x%x",
1570 err);
1571 return err;
1572 }
1573
1574 *pJumpCts =
1575 (M4OSA_Int32)(iJumpCtsMs * pClipCtxt->scale_audio + 0.5);
1576
1577 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
1578 /* (cts is not an integer with frequency 24 kHz for example) */
1579 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2)
1580 / pClipCtxt->iSilenceFrameDuration)
1581 * pClipCtxt->iSilenceFrameDuration;
1582 pClipCtxt->iAudioFrameCts = 0; /* No frame read yet */
1583
1584 /**
1585 * To detect some may-be bugs, I prefer to reset all these after a jump */
1586 pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE;
1587 pClipCtxt->pAudioFramePtr = M4OSA_NULL;
1588
1589 /**
1590 * In AMR, we have to manage multi-framed AUs,
1591 but also in AAC the jump can be 1 AU too much backward */
1592 if( *pJumpCts < iTargetCts )
1593 {
1594 /**
1595 * Jump doesn't read any AU, we must read at least one */
1596 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt);
1597
1598 if( M4OSA_ERR_IS_ERROR(err) )
1599 {
1600 M4OSA_TRACE1_1(
1601 "M4VSS3GPP_intClipJumpAudioAt():\
1602 M4VSS3GPP_intClipReadNextAudioFrame(a) returns 0x%x",
1603 err);
1604 return err;
1605 }
1606
1607 /**
1608 * Read AU frames as long as we reach the AU before the target CTS
1609 * (so the target will be reached when the user call ReadNextAudioFrame). */
1610 while( pClipCtxt->iAudioFrameCts
1611 < (iTargetCts - pClipCtxt->iSilenceFrameDuration) )
1612 {
1613 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt);
1614
1615 if( M4OSA_ERR_IS_ERROR(err) )
1616 {
1617 M4OSA_TRACE1_1(
1618 "M4VSS3GPP_intClipJumpAudioAt():\
1619 M4VSS3GPP_intClipReadNextAudioFrame(b) returns 0x%x",
1620 err);
1621 return err;
1622 }
1623 }
1624
1625 /**
1626 * Return the CTS that will be reached at next ReadFrame */
1627 *pJumpCts = pClipCtxt->iAudioFrameCts
1628 + pClipCtxt->iSilenceFrameDuration;
1629 }
1630 }
1631 }
1632
1633 /**
1634 * Return with no error */
1635 M4OSA_TRACE3_0("M4VSS3GPP_intClipJumpAudioAt(): returning M4NO_ERROR");
1636 return M4NO_ERROR;
1637 }
1638
1639 /**
1640 ******************************************************************************
1641 * M4OSA_ERR M4VSS3GPP_intClipClose()
1642 * @brief Close a clip. Destroy the context.
1643 * @note
1644 * @param pClipCtxt (IN) Internal clip context
1645 * @return M4NO_ERROR: No error
1646 ******************************************************************************
1647 */
M4VSS3GPP_intClipClose(M4VSS3GPP_ClipContext * pClipCtxt)1648 M4OSA_ERR M4VSS3GPP_intClipClose( M4VSS3GPP_ClipContext *pClipCtxt )
1649 {
1650 M4OSA_ERR err;
1651
1652 /**
1653 * Check input parameters */
1654 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
1655 "M4VSS3GPP_intClipClose: pClipCtxt is M4OSA_NULL");
1656
1657 /**
1658 * Free the video decoder context */
1659 if( M4OSA_NULL != pClipCtxt->pViDecCtxt )
1660 {
1661 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy(
1662 pClipCtxt->pViDecCtxt);
1663 pClipCtxt->pViDecCtxt = M4OSA_NULL;
1664 }
1665
1666 /**
1667 * Free the audio decoder context */
1668 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt )
1669 {
1670 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec(
1671 pClipCtxt->pAudioDecCtxt);
1672
1673 if( M4NO_ERROR != err )
1674 {
1675 M4OSA_TRACE1_1(
1676 "M4VSS3GPP_intClipClose: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
1677 err);
1678 /**< don't return, we still have stuff to free */
1679 }
1680
1681 pClipCtxt->pAudioDecCtxt = M4OSA_NULL;
1682 }
1683
1684 /**
1685 * Free the decoded audio buffer */
1686 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
1687 {
1688 free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
1689 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
1690 }
1691
1692 /**
1693 * Audio AU is allocated by reader.
1694 * If no audio track, audio AU is set at 'silent' (SID) by VSS.
1695 * As a consequence, if audio AU is set to 'silent' (static)
1696 it can't be free unless it is set to NULL */
1697 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048
1698 == pClipCtxt->AudioAU.m_dataAddress)
1699 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData
1700 == pClipCtxt->AudioAU.m_dataAddress) )
1701 {
1702 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
1703 }
1704
1705 if( M4OSA_NULL != pClipCtxt->pReaderContext )
1706 {
1707 /**
1708 * Close the 3GPP or MP3 reader */
1709 err = pClipCtxt->ShellAPI.m_pReader->m_pFctClose(
1710 pClipCtxt->pReaderContext);
1711
1712 if( M4NO_ERROR != err )
1713 {
1714 M4OSA_TRACE1_1(
1715 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctClose returns 0x%x",
1716 err);
1717 }
1718
1719 /**
1720 * Destroy the 3GPP or MP3 reader context */
1721 err = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy(
1722 pClipCtxt->pReaderContext);
1723
1724 if( M4NO_ERROR != err )
1725 {
1726 M4OSA_TRACE1_1(
1727 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctDestroy returns 0x%x",
1728 err);
1729 }
1730
1731 pClipCtxt->pReaderContext = M4OSA_NULL;
1732 }
1733
1734 /**
1735 * Return with no error */
1736 M4OSA_TRACE3_1("M4VSS3GPP_intClipClose(Ctxt=0x%x): returning M4NO_ERROR",
1737 pClipCtxt);
1738 return M4NO_ERROR;
1739 }
1740
M4VSS3GPP_intClipCleanUp(M4VSS3GPP_ClipContext * pClipCtxt)1741 M4OSA_ERR M4VSS3GPP_intClipCleanUp( M4VSS3GPP_ClipContext *pClipCtxt )
1742 {
1743 M4OSA_ERR err = M4NO_ERROR, err2;
1744
1745 /**
1746 * Check input parameters */
1747 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
1748 "M4VSS3GPP_intClipCleanUp: pClipCtxt is M4OSA_NULL");
1749
1750 /**
1751 * Free the video decoder context */
1752 if( M4OSA_NULL != pClipCtxt->pViDecCtxt )
1753 {
1754 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy(
1755 pClipCtxt->pViDecCtxt);
1756 pClipCtxt->pViDecCtxt = M4OSA_NULL;
1757 }
1758
1759 /**
1760 * Free the audio decoder context */
1761 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt )
1762 {
1763 err2 = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec(
1764 pClipCtxt->pAudioDecCtxt);
1765
1766 if( M4NO_ERROR != err2 )
1767 {
1768 M4OSA_TRACE1_1(
1769 "M4VSS3GPP_intClipCleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
1770 err);
1771 /**< don't return, we still have stuff to free */
1772 if( M4NO_ERROR != err )
1773 err = err2;
1774 }
1775
1776 pClipCtxt->pAudioDecCtxt = M4OSA_NULL;
1777 }
1778
1779 /**
1780 * Free the decoded audio buffer */
1781 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
1782 {
1783 free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
1784 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
1785 }
1786
1787 /**
1788 * Audio AU is allocated by reader.
1789 * If no audio track, audio AU is set at 'silent' (SID) by VSS.
1790 * As a consequence, if audio AU is set to 'silent' (static)
1791 it can't be free unless it is set to NULL */
1792 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048
1793 == pClipCtxt->AudioAU.m_dataAddress)
1794 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData
1795 == pClipCtxt->AudioAU.m_dataAddress) )
1796 {
1797 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
1798 }
1799
1800 if( M4OSA_NULL != pClipCtxt->pReaderContext )
1801 {
1802 /**
1803 * Close the 3GPP or MP3 reader */
1804 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctClose(
1805 pClipCtxt->pReaderContext);
1806
1807 if( M4NO_ERROR != err2 )
1808 {
1809 M4OSA_TRACE1_1(
1810 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctClose returns 0x%x",
1811 err);
1812
1813 if( M4NO_ERROR != err )
1814 err = err2;
1815 }
1816
1817 /**
1818 * Destroy the 3GPP or MP3 reader context */
1819 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy(
1820 pClipCtxt->pReaderContext);
1821
1822 if( M4NO_ERROR != err2 )
1823 {
1824 M4OSA_TRACE1_1(
1825 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctDestroy returns 0x%x",
1826 err);
1827
1828 if( M4NO_ERROR != err )
1829 err = err2;
1830 }
1831
1832 pClipCtxt->pReaderContext = M4OSA_NULL;
1833 }
1834
1835 if(pClipCtxt->pPlaneYuv != M4OSA_NULL) {
1836 if(pClipCtxt->pPlaneYuv[0].pac_data != M4OSA_NULL) {
1837 free(pClipCtxt->pPlaneYuv[0].pac_data);
1838 pClipCtxt->pPlaneYuv[0].pac_data = M4OSA_NULL;
1839 }
1840 free(pClipCtxt->pPlaneYuv);
1841 pClipCtxt->pPlaneYuv = M4OSA_NULL;
1842 }
1843
1844 if(pClipCtxt->pPlaneYuvWithEffect != M4OSA_NULL) {
1845 if(pClipCtxt->pPlaneYuvWithEffect[0].pac_data != M4OSA_NULL) {
1846 free(pClipCtxt->pPlaneYuvWithEffect[0].pac_data);
1847 pClipCtxt->pPlaneYuvWithEffect[0].pac_data = M4OSA_NULL;
1848 }
1849 free(pClipCtxt->pPlaneYuvWithEffect);
1850 pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL;
1851 }
1852 /**
1853 * Free the shells interfaces */
1854 M4VSS3GPP_unRegisterAllWriters(&pClipCtxt->ShellAPI);
1855 M4VSS3GPP_unRegisterAllEncoders(&pClipCtxt->ShellAPI);
1856 M4VSS3GPP_unRegisterAllReaders(&pClipCtxt->ShellAPI);
1857 M4VSS3GPP_unRegisterAllDecoders(&pClipCtxt->ShellAPI);
1858
1859 M4OSA_TRACE3_1("M4VSS3GPP_intClipCleanUp: pClipCtxt=0x%x", pClipCtxt);
1860 /**
1861 * Free the clip context */
1862 free(pClipCtxt);
1863
1864 return err;
1865 }
1866
1867 /**
1868 ******************************************************************************
1869 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB()
1870 * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer
1871 * @note
1872 * @param pAudioFrame (IN) AMRNB frame
1873 * @return M4NO_ERROR: No error
1874 ******************************************************************************
1875 */
1876
M4VSS3GPP_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame)1877 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame )
1878 {
1879 M4OSA_UInt32 frameSize = 0;
1880 M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3;
1881
1882 switch( frameType )
1883 {
1884 case 0:
1885 frameSize = 95;
1886 break; /* 4750 bps */
1887
1888 case 1:
1889 frameSize = 103;
1890 break; /* 5150 bps */
1891
1892 case 2:
1893 frameSize = 118;
1894 break; /* 5900 bps */
1895
1896 case 3:
1897 frameSize = 134;
1898 break; /* 6700 bps */
1899
1900 case 4:
1901 frameSize = 148;
1902 break; /* 7400 bps */
1903
1904 case 5:
1905 frameSize = 159;
1906 break; /* 7950 bps */
1907
1908 case 6:
1909 frameSize = 204;
1910 break; /* 10200 bps */
1911
1912 case 7:
1913 frameSize = 244;
1914 break; /* 12000 bps */
1915
1916 case 8:
1917 frameSize = 39;
1918 break; /* SID (Silence) */
1919
1920 case 15:
1921 frameSize = 0;
1922 break; /* No data */
1923
1924 default:
1925 M4OSA_TRACE3_0(
1926 "M4VSS3GPP_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0.");
1927 return 0;
1928 }
1929
1930 return (1 + (( frameSize + 7) / 8));
1931 }
1932
1933 /**
1934 ******************************************************************************
1935 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC()
1936 * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer
1937 * @note
1938 * 0 1 2 3
1939 * +-+-+-+-+
1940 * |fr type| RFC 3558
1941 * +-+-+-+-+
1942 *
1943 * Frame Type: 4 bits
1944 * The frame type indicates the type of the corresponding codec data
1945 * frame in the RTP packet.
1946 *
1947 * For EVRC and SMV codecs, the frame type values and size of the
1948 * associated codec data frame are described in the table below:
1949 *
1950 * Value Rate Total codec data frame size (in octets)
1951 * ---------------------------------------------------------
1952 * 0 Blank 0 (0 bit)
1953 * 1 1/8 2 (16 bits)
1954 * 2 1/4 5 (40 bits; not valid for EVRC)
1955 * 3 1/2 10 (80 bits)
1956 * 4 1 22 (171 bits; 5 padded at end with zeros)
1957 * 5 Erasure 0 (SHOULD NOT be transmitted by sender)
1958 *
1959 * @param pCpAudioFrame (IN) EVRC frame
1960 * @return M4NO_ERROR: No error
1961 ******************************************************************************
1962 */
M4VSS3GPP_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame)1963 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame )
1964 {
1965 M4OSA_UInt32 frameSize = 0;
1966 M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F;
1967
1968 switch( frameType )
1969 {
1970 case 0:
1971 frameSize = 0;
1972 break; /* blank */
1973
1974 case 1:
1975 frameSize = 16;
1976 break; /* 1/8 */
1977
1978 case 2:
1979 frameSize = 40;
1980 break; /* 1/4 */
1981
1982 case 3:
1983 frameSize = 80;
1984 break; /* 1/2 */
1985
1986 case 4:
1987 frameSize = 171;
1988 break; /* 1 */
1989
1990 case 5:
1991 frameSize = 0;
1992 break; /* erasure */
1993
1994 default:
1995 M4OSA_TRACE3_0(
1996 "M4VSS3GPP_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0.");
1997 return 0;
1998 }
1999
2000 return (1 + (( frameSize + 7) / 8));
2001 }
2002
M4VSS3GPP_intCheckAndGetCodecAacProperties(M4VSS3GPP_ClipContext * pClipCtxt)2003 M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties(
2004 M4VSS3GPP_ClipContext *pClipCtxt) {
2005
2006 M4OSA_ERR err = M4NO_ERROR;
2007 M4AD_Buffer outputBuffer;
2008 uint32_t optionValue =0;
2009
2010 // Decode first audio frame from clip to get properties from codec
2011
2012 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
2013 &pClipCtxt->pAudioDecCtxt,
2014 pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties));
2015
2016 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
2017 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface,
2018 (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt);
2019
2020 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
2021 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU,
2022 (M4OSA_DataOption) &pClipCtxt->AudioAU);
2023
2024 if( pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
2025
2026 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec(
2027 pClipCtxt->pAudioDecCtxt);
2028 if( M4NO_ERROR != err ) {
2029
2030 M4OSA_TRACE1_1(
2031 "M4VSS3GPP_intCheckAndGetCodecAacProperties: \
2032 m_pFctStartAudioDec returns 0x%x", err);
2033 return err;
2034 }
2035 }
2036
2037 /**
2038 * Allocate output buffer for the audio decoder */
2039 outputBuffer.m_bufferSize =
2040 pClipCtxt->pAudioStream->m_byteFrameLength
2041 * pClipCtxt->pAudioStream->m_byteSampleSize
2042 * pClipCtxt->pAudioStream->m_nbChannels;
2043
2044 if( outputBuffer.m_bufferSize > 0 ) {
2045
2046 outputBuffer.m_dataAddress =
2047 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
2048 *sizeof(short), M4VSS3GPP, (M4OSA_Char *)"outputBuffer.m_bufferSize");
2049
2050 if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
2051
2052 M4OSA_TRACE1_0(
2053 "M4VSS3GPP_intCheckAndGetCodecAacProperties():\
2054 unable to allocate outputBuffer.m_dataAddress");
2055 return M4ERR_ALLOC;
2056 }
2057 }
2058
2059 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
2060 pClipCtxt->pAudioDecCtxt, M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
2061
2062 if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
2063
2064 // Get the properties from codec node
2065 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec(
2066 pClipCtxt->pAudioDecCtxt,
2067 M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
2068
2069 pClipCtxt->AacProperties.aNumChan = optionValue;
2070 // Reset Reader structure value also
2071 pClipCtxt->pAudioStream->m_nbChannels = optionValue;
2072
2073 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec(
2074 pClipCtxt->pAudioDecCtxt,
2075 M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
2076
2077 pClipCtxt->AacProperties.aSampFreq = optionValue;
2078 // Reset Reader structure value also
2079 pClipCtxt->pAudioStream->m_samplingFrequency = optionValue;
2080
2081 } else if( err != M4NO_ERROR) {
2082 M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties:\
2083 m_pFctStepAudioDec returns err = 0x%x", err);
2084 }
2085
2086 free(outputBuffer.m_dataAddress);
2087
2088 // Reset the stream reader
2089 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
2090 pClipCtxt->pReaderContext,
2091 (M4_StreamHandler *)pClipCtxt->pAudioStream);
2092
2093 if (M4NO_ERROR != err) {
2094 M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties\
2095 Error in reseting reader: 0x%x", err);
2096 }
2097
2098 return err;
2099
2100 }
2101