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_ClipAnalysis.c
19 * @brief Implementation of functions related to analysis of input clips
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 #include "M4VD_EXTERNAL_Interface.h"
37
38
39 /**
40 * OSAL headers */
41 #include "M4OSA_Memory.h" /* OSAL memory management */
42 #include "M4OSA_Debug.h" /* OSAL debug management */
43
44 /**
45 ******************************************************************************
46 * M4OSA_ERR M4VSS3GPP_editAnalyseClip()
47 * @brief This function allows checking if a clip is compatible with VSS 3GPP editing
48 * @note It also fills a ClipAnalysis structure, which can be used to check if two
49 * clips are compatible
50 * @param pClip (IN) File descriptor of the input 3GPP/MP3 clip file.
51 * @param pClipProperties (IN) Pointer to a valid ClipProperties structure.
52 * @param FileType (IN) Type of the input file (.3gp, .amr, .mp3)
53 * @return M4NO_ERROR: No error
54 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only)
55 * @return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED
56 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
57 * @return M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED
58 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE
59 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE
60 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC
61 * @return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT
62 * @return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE
63 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT
64 * @return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE
65 ******************************************************************************
66 */
M4VSS3GPP_editAnalyseClip(M4OSA_Void * pClip,M4VIDEOEDITING_FileType FileType,M4VIDEOEDITING_ClipProperties * pClipProperties,M4OSA_FileReadPointer * pFileReadPtrFct)67 M4OSA_ERR M4VSS3GPP_editAnalyseClip( M4OSA_Void *pClip,
68 M4VIDEOEDITING_FileType FileType,
69 M4VIDEOEDITING_ClipProperties *pClipProperties,
70 M4OSA_FileReadPointer *pFileReadPtrFct )
71 {
72 M4OSA_ERR err;
73 M4VSS3GPP_ClipContext *pClipContext;
74 M4VSS3GPP_ClipSettings ClipSettings;
75
76 M4OSA_TRACE3_2(
77 "M4VSS3GPP_editAnalyseClip called with pClip=0x%x, pClipProperties=0x%x",
78 pClip, pClipProperties);
79
80 /**
81 * Check input parameter */
82 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip), M4ERR_PARAMETER,
83 "M4VSS3GPP_editAnalyseClip: pClip is M4OSA_NULL");
84 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipProperties), M4ERR_PARAMETER,
85 "M4VSS3GPP_editAnalyseClip: pClipProperties is M4OSA_NULL");
86
87 /**
88 * Build dummy clip settings, in order to use the editClipOpen function */
89 ClipSettings.pFile = pClip;
90 ClipSettings.FileType = FileType;
91 ClipSettings.uiBeginCutTime = 0;
92 ClipSettings.uiEndCutTime = 0;
93
94 /* Clip properties not build yet, set at least this flag */
95 ClipSettings.ClipProperties.bAnalysed = M4OSA_FALSE;
96
97 /**
98 * Open the clip in fast open mode */
99 err = M4VSS3GPP_intClipInit(&pClipContext, pFileReadPtrFct);
100
101 if( M4NO_ERROR != err )
102 {
103 M4OSA_TRACE1_1(
104 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipInit() returns 0x%x!",
105 err);
106
107 /**
108 * Free the clip */
109 if( M4OSA_NULL != pClipContext )
110 {
111 M4VSS3GPP_intClipCleanUp(pClipContext);
112 }
113 return err;
114 }
115
116 err = M4VSS3GPP_intClipOpen(pClipContext, &ClipSettings, M4OSA_FALSE,
117 M4OSA_TRUE, M4OSA_TRUE);
118
119 if( M4NO_ERROR != err )
120 {
121 M4OSA_TRACE1_1(
122 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipOpen() returns 0x%x!",
123 err);
124
125 M4VSS3GPP_intClipCleanUp(pClipContext);
126
127 /**
128 * Here it is better to return the Editing specific error code */
129 if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err)
130 || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) )
131 {
132 M4OSA_TRACE1_0(
133 "M4VSS3GPP_editAnalyseClip:\
134 M4VSS3GPP_intClipOpen() returns M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED");
135 return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED;
136 }
137 return err;
138 }
139
140 /**
141 * Analyse the clip */
142 if(M4VIDEOEDITING_kFileType_ARGB8888 != pClipContext->pSettings->FileType) {
143 err = M4VSS3GPP_intBuildAnalysis(pClipContext, pClipProperties);
144
145 if( M4NO_ERROR != err )
146 {
147 M4OSA_TRACE1_1(
148 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intBuildAnalysis() returns 0x%x!",
149 err);
150
151 /**
152 * Free the clip */
153 M4VSS3GPP_intClipCleanUp(pClipContext);
154 return err;
155 }
156 }
157 /**
158 * Free the clip */
159 err = M4VSS3GPP_intClipClose(pClipContext);
160
161 if( M4NO_ERROR != err )
162 {
163 M4OSA_TRACE1_1(
164 "M4VSS3GPP_editAnalyseClip: M4VSS_intClipClose() returns 0x%x!",
165 err);
166 M4VSS3GPP_intClipCleanUp(pClipContext);
167 return err;
168 }
169
170 M4VSS3GPP_intClipCleanUp(pClipContext);
171
172 /**
173 * Check the clip is compatible with VSS editing */
174 if(M4VIDEOEDITING_kFileType_ARGB8888 != ClipSettings.FileType) {
175 err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing(pClipProperties);
176
177 if( M4NO_ERROR != err )
178 {
179 M4OSA_TRACE1_1(
180 "M4VSS3GPP_editAnalyseClip:\
181 M4VSS3GPP_intCheckClipCompatibleWithVssEditing() returns 0x%x!",
182 err);
183 return err;
184 }
185 }
186 /**
187 * Return with no error */
188 M4OSA_TRACE3_0("M4VSS3GPP_editAnalyseClip(): returning M4NO_ERROR");
189 return M4NO_ERROR;
190 }
191
192 /**
193 ******************************************************************************
194 * M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility()
195 * @brief This function allows checking if two clips are compatible with each other for
196 * VSS 3GPP editing assembly feature.
197 * @note
198 * @param pClip1Properties (IN) Clip analysis of the first clip
199 * @param pClip2Properties (IN) Clip analysis of the second clip
200 * @return M4NO_ERROR: No error
201 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only)
202 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
203 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT
204 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE
205 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE
206 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING
207 * @return M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY
208 * @return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT
209 ******************************************************************************
210 */
M4VSS3GPP_editCheckClipCompatibility(M4VIDEOEDITING_ClipProperties * pClip1Properties,M4VIDEOEDITING_ClipProperties * pClip2Properties)211 M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility( M4VIDEOEDITING_ClipProperties *pClip1Properties,
212 M4VIDEOEDITING_ClipProperties *pClip2Properties )
213 {
214 M4OSA_ERR err = M4NO_ERROR;
215 M4OSA_ERR video_err = M4NO_ERROR;
216 M4OSA_ERR audio_err = M4NO_ERROR;
217
218 M4OSA_Bool bClip1IsAAC = M4OSA_FALSE;
219 M4OSA_Bool bClip2IsAAC = M4OSA_FALSE;
220
221 M4OSA_TRACE3_2("M4VSS3GPP_editCheckClipCompatibility called with pClip1Analysis=0x%x,\
222 pClip2Analysis=0x%x", pClip1Properties, pClip2Properties);
223
224 /**
225 * Check input parameter */
226 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip1Properties), M4ERR_PARAMETER,
227 "M4VSS3GPP_editCheckClipCompatibility: pClip1Properties is M4OSA_NULL");
228 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip2Properties), M4ERR_PARAMETER,
229 "M4VSS3GPP_editCheckClipCompatibility: pClip2Properties is M4OSA_NULL");
230
231 if( ( M4VIDEOEDITING_kFileType_MP3 == pClip1Properties->FileType)
232 || (M4VIDEOEDITING_kFileType_AMR == pClip1Properties->FileType) )
233 {
234 if( pClip1Properties != pClip2Properties )
235 {
236 M4OSA_TRACE1_0(
237 "M4VSS3GPP_editCheckClipCompatibility: MP3 CAN ONLY BE CUT,\
238 returning M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY");
239 return M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY;
240 }
241 else
242 {
243 /* We are in VSS Splitter mode */
244 goto audio_analysis;
245 }
246 }
247
248 /********** Audio ************/
249
250 audio_analysis:
251 if( M4VIDEOEDITING_kNoneAudio != pClip1Properties->
252 AudioStreamType ) /**< if there is an audio stream */
253 {
254 /**
255 * Check audio format is AAC */
256 switch( pClip1Properties->AudioStreamType )
257 {
258 case M4VIDEOEDITING_kAAC:
259 case M4VIDEOEDITING_kAACplus:
260 case M4VIDEOEDITING_keAACplus:
261 bClip1IsAAC = M4OSA_TRUE;
262 break;
263 default:
264 break;
265 }
266 }
267
268 if( M4VIDEOEDITING_kNoneAudio != pClip2Properties->
269 AudioStreamType ) /**< if there is an audio stream */
270 {
271 /**
272 * Check audio format is AAC */
273 switch( pClip2Properties->AudioStreamType )
274 {
275 case M4VIDEOEDITING_kAAC:
276 case M4VIDEOEDITING_kAACplus:
277 case M4VIDEOEDITING_keAACplus:
278 bClip2IsAAC = M4OSA_TRUE;
279 break;
280 default:
281 break;
282 }
283 }
284
285 /**
286 * If there is no audio, the clips are compatibles ... */
287 if( ( pClip1Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio)
288 && (pClip2Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio) )
289 {
290 /**
291 * Check both clips have same audio stream type
292 * And let_s say AAC, AAC+ and eAAC+ are mixable */
293 if( ( pClip1Properties->AudioStreamType
294 != pClip2Properties->AudioStreamType)
295 && (( M4OSA_FALSE == bClip1IsAAC) || (M4OSA_FALSE == bClip2IsAAC)) )
296 {
297 M4OSA_TRACE1_0(
298 "M4VSS3GPP_editCheckClipCompatibility:\
299 Clips don't have the same Audio Stream Type");
300
301 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE;
302 goto analysis_done;
303 }
304
305 /**
306 * Check both clips have same number of channels */
307 if( pClip1Properties->uiNbChannels != pClip2Properties->uiNbChannels )
308 {
309 M4OSA_TRACE1_0(
310 "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same Nb of Channels");
311 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS;
312 goto analysis_done;
313 }
314
315 /**
316 * Check both clips have same sampling frequency */
317 if( pClip1Properties->uiSamplingFrequency
318 != pClip2Properties->uiSamplingFrequency )
319 {
320 M4OSA_TRACE1_0(
321 "M4VSS3GPP_editCheckClipCompatibility:\
322 Clips don't have the same Sampling Frequency");
323 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY;
324 goto analysis_done;
325 }
326 }
327
328 pClip2Properties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE;
329
330 /**
331 * Return with no error */
332
333 analysis_done:
334 if( video_err != M4NO_ERROR )
335 return video_err;
336
337 if( audio_err != M4NO_ERROR )
338 return audio_err;
339
340 M4OSA_TRACE3_0(
341 "M4VSS3GPP_editCheckClipCompatibility(): returning M4NO_ERROR");
342 return M4NO_ERROR;
343 }
344
345 /**
346 ******************************************************************************
347 * M4OSA_ERR M4VSS3GPP_intBuildAnalysis()
348 * @brief Get video and audio properties from the clip streams
349 * @note This function must return fatal errors only (errors that should not happen
350 * in the final integrated product).
351 * @param pClipCtxt (IN) internal clip context
352 * @param pClipProperties (OUT) Pointer to a valid ClipProperties structure.
353 * @return M4NO_ERROR: No error
354 ******************************************************************************
355 */
M4VSS3GPP_intBuildAnalysis(M4VSS3GPP_ClipContext * pClipCtxt,M4VIDEOEDITING_ClipProperties * pClipProperties)356 M4OSA_ERR M4VSS3GPP_intBuildAnalysis( M4VSS3GPP_ClipContext *pClipCtxt,
357 M4VIDEOEDITING_ClipProperties *pClipProperties )
358 {
359 M4OSA_ERR err;
360 M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo;
361 M4DECODER_VideoSize dummySize;
362 M4DECODER_AVCProfileLevel AVCProfle;
363
364 pClipProperties->bAnalysed = M4OSA_FALSE;
365
366 /**
367 * Reset video characteristics */
368 pClipProperties->VideoStreamType = M4VIDEOEDITING_kNoneVideo;
369 pClipProperties->uiClipVideoDuration = 0;
370 pClipProperties->uiVideoBitrate = 0;
371 pClipProperties->uiVideoMaxAuSize = 0;
372 pClipProperties->uiVideoWidth = 0;
373 pClipProperties->uiVideoHeight = 0;
374 pClipProperties->uiVideoTimeScale = 0;
375 pClipProperties->fAverageFrameRate = 0.0;
376 pClipProperties->uiVideoProfile =
377 M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
378 pClipProperties->uiVideoLevel =
379 M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
380 pClipProperties->bMPEG4dataPartition = M4OSA_FALSE;
381 pClipProperties->bMPEG4rvlc = M4OSA_FALSE;
382 pClipProperties->bMPEG4resynchMarker = M4OSA_FALSE;
383
384 memset((void *) &pClipProperties->ftyp,0,
385 sizeof(pClipProperties->ftyp));
386
387 /**
388 * Video Analysis */
389 if( M4OSA_NULL != pClipCtxt->pVideoStream )
390 {
391 pClipProperties->uiVideoWidth = pClipCtxt->pVideoStream->m_videoWidth;
392 pClipProperties->uiVideoHeight = pClipCtxt->pVideoStream->m_videoHeight;
393 pClipProperties->fAverageFrameRate =
394 pClipCtxt->pVideoStream->m_averageFrameRate;
395
396 switch( pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
397 {
398 case M4DA_StreamTypeVideoMpeg4:
399
400 pClipProperties->VideoStreamType = M4VIDEOEDITING_kMPEG4;
401
402 /* This issue is so incredibly stupid that it's depressing. Basically, a file can be analysed
403 outside of any context (besides that of the clip itself), so that for instance two clips can
404 be checked for compatibility before allocating an edit context for editing them. But this
405 means there is no way in heck to pass an external video decoder (to begin with) to this
406 function, as they work by being registered in an existing context; furthermore, it is actually
407 pretty overkill to use a full decoder for that, moreso a HARDWARE decoder just to get the
408 clip config info. In fact, the hardware itself doesn't provide this service, in the case of a
409 HW decoder, the shell builds the config info itself, so we don't need the actual decoder, only
410 a detached functionality of it. So in case HW/external decoders may be present, we instead use
411 directly the DSI parsing function of the shell HW decoder (which we know to be present, since
412 HW decoders are possible) to get the config info. Notice this function is used even if the
413 software decoder is actually present and even if it will end up being actually used: figuring
414 out the config does not involve actual decoding nor the particularities of a specific decoder,
415 it's the fact that it's MPEG4 that matters, so it should not be functionally any different
416 from the way it was done before (and it's light enough for performance not to be any problem
417 whatsoever). */
418
419 err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream->
420 m_basicProperties.m_pDecoderSpecificInfo,
421 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
422 &DecConfigInfo, &dummySize);
423
424 if( M4NO_ERROR != err )
425 {
426 M4OSA_TRACE1_1(
427 "M4VSS3GPP_intBuildAnalysis():\
428 M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", err);
429 return err;
430 }
431
432 pClipProperties->uiVideoTimeScale =
433 DecConfigInfo.uiTimeScale;
434 pClipProperties->bMPEG4dataPartition =
435 DecConfigInfo.bDataPartition;
436 pClipProperties->bMPEG4rvlc =
437 DecConfigInfo.bUseOfRVLC;
438 pClipProperties->bMPEG4resynchMarker =
439 DecConfigInfo.uiUseOfResynchMarker;
440 err = getMPEG4ProfileAndLevel(DecConfigInfo.uiProfile,
441 &(pClipProperties->uiVideoProfile),
442 &(pClipProperties->uiVideoLevel));
443 if (M4NO_ERROR != err) {
444 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \
445 getMPEG4ProfileAndLevel returns 0x%08X", err);
446 return err;
447 }
448 break;
449
450 case M4DA_StreamTypeVideoH263:
451
452 pClipProperties->VideoStreamType = M4VIDEOEDITING_kH263;
453 /* H263 time scale is always 30000 */
454 pClipProperties->uiVideoTimeScale = 30000;
455
456 err = getH263ProfileAndLevel(pClipCtxt->pVideoStream->
457 m_basicProperties.m_pDecoderSpecificInfo,
458 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
459 &pClipProperties->uiVideoProfile,
460 &pClipProperties->uiVideoLevel);
461 if (M4NO_ERROR != err) {
462 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \
463 getH263ProfileAndLevel returns 0x%08X", err);
464 return err;
465 }
466 break;
467
468 case M4DA_StreamTypeVideoMpeg4Avc:
469
470 pClipProperties->VideoStreamType = M4VIDEOEDITING_kH264;
471 err = getAVCProfileAndLevel(pClipCtxt->pVideoStream->
472 m_basicProperties.m_pDecoderSpecificInfo,
473 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
474 &pClipProperties->uiVideoProfile,
475 &pClipProperties->uiVideoLevel);
476 if (M4NO_ERROR != err) {
477 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \
478 getAVCProfileAndLevel returns 0x%08X", err);
479 return err;
480 }
481 break;
482
483 default:
484 M4OSA_TRACE1_1(
485 "M4VSS3GPP_intBuildAnalysis: unknown input video format (0x%x),\
486 returning M4NO_ERROR",
487 pClipCtxt->pVideoStream->m_basicProperties.m_streamType);
488
489 /** We do not return error here.
490 * The video format compatibility check will be done latter */
491 return M4NO_ERROR;
492 }
493
494 pClipProperties->uiClipVideoDuration =
495 (M4OSA_UInt32)pClipCtxt->pVideoStream->m_basicProperties.m_duration;
496 pClipProperties->uiVideoMaxAuSize =
497 pClipCtxt->pVideoStream->m_basicProperties.m_maxAUSize;
498
499 /* if video bitrate not available retrieve an estimation of the overall bitrate */
500 pClipProperties->uiVideoBitrate =
501 (M4OSA_UInt32)pClipCtxt->pVideoStream->
502 m_basicProperties.m_averageBitRate;
503
504 if( 0 == pClipProperties->uiVideoBitrate )
505 {
506 pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
507 pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate,
508 &pClipProperties->uiVideoBitrate);
509
510 if( M4OSA_NULL != pClipCtxt->pAudioStream )
511 {
512 /* we get the overall bitrate, substract the audio bitrate if any */
513 pClipProperties->uiVideoBitrate -=
514 pClipCtxt->pAudioStream->m_basicProperties.m_averageBitRate;
515 }
516 }
517 }
518
519 /**
520 * Reset audio characteristics */
521 pClipProperties->AudioStreamType = M4VIDEOEDITING_kNoneAudio;
522 pClipProperties->uiClipAudioDuration = 0;
523 pClipProperties->uiAudioBitrate = 0;
524 pClipProperties->uiAudioMaxAuSize = 0;
525 pClipProperties->uiNbChannels = 0;
526 pClipProperties->uiSamplingFrequency = 0;
527 pClipProperties->uiExtendedSamplingFrequency = 0;
528 pClipProperties->uiDecodedPcmSize = 0;
529
530 /**
531 * Audio Analysis */
532 if( M4OSA_NULL != pClipCtxt->pAudioStream )
533 {
534 switch( pClipCtxt->pAudioStream->m_basicProperties.m_streamType )
535 {
536 case M4DA_StreamTypeAudioAmrNarrowBand:
537
538 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAMR_NB;
539 break;
540
541 case M4DA_StreamTypeAudioAac:
542
543 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAAC;
544 break;
545
546 case M4DA_StreamTypeAudioMp3:
547
548 pClipProperties->AudioStreamType = M4VIDEOEDITING_kMP3;
549 break;
550
551 case M4DA_StreamTypeAudioEvrc:
552
553 pClipProperties->AudioStreamType = M4VIDEOEDITING_kEVRC;
554 break;
555
556 case M4DA_StreamTypeAudioPcm:
557
558 pClipProperties->AudioStreamType = M4VIDEOEDITING_kPCM;
559 break;
560
561 default:
562
563 M4OSA_TRACE1_1(
564 "M4VSS3GPP_intBuildAnalysis: unknown input audio format (0x%x),\
565 returning M4NO_ERROR!",
566 pClipCtxt->pAudioStream->m_basicProperties.m_streamType);
567 return
568 M4NO_ERROR; /**< We do not return error here.
569 The audio format compatibility check will be done latter */
570 }
571
572 pClipProperties->uiAudioMaxAuSize =
573 pClipCtxt->pAudioStream->m_basicProperties.m_maxAUSize;
574 pClipProperties->uiClipAudioDuration =
575 (M4OSA_UInt32)pClipCtxt->pAudioStream->m_basicProperties.m_duration;
576
577 pClipProperties->uiNbChannels = pClipCtxt->pAudioStream->m_nbChannels;
578 pClipProperties->uiSamplingFrequency =
579 pClipCtxt->pAudioStream->m_samplingFrequency;
580 pClipProperties->uiDecodedPcmSize =
581 pClipCtxt->pAudioStream->m_byteFrameLength
582 * pClipCtxt->pAudioStream->m_byteSampleSize
583 * pClipCtxt->pAudioStream->m_nbChannels;
584
585 /**
586 * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps
587 according the GetProperties function */
588 pClipProperties->uiAudioBitrate =
589 (M4OSA_UInt32)pClipCtxt->pAudioStream->
590 m_basicProperties.m_averageBitRate;
591
592 if( 0 == pClipProperties->uiAudioBitrate )
593 {
594 if( M4VIDEOEDITING_kAMR_NB == pClipProperties->AudioStreamType )
595 {
596 /**
597 *Better returning a guessed 12.2 kbps value than a sure-to-be-false 0 kbps value!*/
598 pClipProperties->uiAudioBitrate = M4VSS3GPP_AMR_DEFAULT_BITRATE;
599 }
600 else if( M4VIDEOEDITING_kEVRC == pClipProperties->AudioStreamType )
601 {
602 /**
603 *Better returning a guessed 9.2 kbps value than a sure-to-be-false 0 kbps value!*/
604 pClipProperties->uiAudioBitrate =
605 M4VSS3GPP_EVRC_DEFAULT_BITRATE;
606 }
607 else
608 {
609 pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
610 pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate,
611 &pClipProperties->uiAudioBitrate);
612
613 if( M4OSA_NULL != pClipCtxt->pVideoStream )
614 {
615 /* we get the overall bitrate, substract the video bitrate if any */
616 pClipProperties->uiAudioBitrate -= pClipCtxt->pVideoStream->
617 m_basicProperties.m_averageBitRate;
618 }
619 }
620 }
621
622 /* New aac properties */
623 if( M4DA_StreamTypeAudioAac
624 == pClipCtxt->pAudioStream->m_basicProperties.m_streamType )
625 {
626 pClipProperties->uiNbChannels = pClipCtxt->AacProperties.aNumChan;
627 pClipProperties->uiSamplingFrequency =
628 pClipCtxt->AacProperties.aSampFreq;
629
630 if( pClipCtxt->AacProperties.aSBRPresent )
631 {
632 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAACplus;
633 pClipProperties->uiExtendedSamplingFrequency =
634 pClipCtxt->AacProperties.aExtensionSampFreq;
635 }
636
637 if( pClipCtxt->AacProperties.aPSPresent )
638 {
639 pClipProperties->AudioStreamType = M4VIDEOEDITING_keAACplus;
640 }
641 }
642 }
643
644 /* Get 'ftyp' atom */
645 err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
646 pClipCtxt->pReaderContext,
647 M4READER_kOptionID_3gpFtypBox, &pClipProperties->ftyp);
648
649 /**
650 * We write the VSS 3GPP version in the clip analysis to be sure the integrator doesn't
651 * mix older analysis results with newer libraries */
652 pClipProperties->Version[0] = M4VIDEOEDITING_VERSION_MAJOR;
653 pClipProperties->Version[1] = M4VIDEOEDITING_VERSION_MINOR;
654 pClipProperties->Version[2] = M4VIDEOEDITING_VERSION_REVISION;
655
656 pClipProperties->FileType = pClipCtxt->pSettings->FileType;
657
658 if( pClipProperties->uiClipVideoDuration
659 > pClipProperties->uiClipAudioDuration )
660 pClipProperties->uiClipDuration = pClipProperties->uiClipVideoDuration;
661 else
662 pClipProperties->uiClipDuration = pClipProperties->uiClipAudioDuration;
663
664 /* Reset compatibility chart */
665 pClipProperties->bVideoIsEditable = M4OSA_FALSE;
666 pClipProperties->bAudioIsEditable = M4OSA_FALSE;
667 pClipProperties->bVideoIsCompatibleWithMasterClip = M4OSA_FALSE;
668 pClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
669
670 /* Analysis successfully completed */
671 pClipProperties->bAnalysed = M4OSA_TRUE;
672
673 /**
674 * Return with no error */
675 M4OSA_TRACE3_0("M4VSS3GPP_intBuildAnalysis(): returning M4NO_ERROR");
676 return M4NO_ERROR;
677 }
678
679 /**
680 ******************************************************************************
681 * M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing()
682 * @brief Check if the clip is compatible with VSS editing
683 * @note
684 * @param pClipCtxt (IN) internal clip context
685 * @param pClipProperties (OUT) Pointer to a valid ClipProperties structure.
686 * @return M4NO_ERROR: No error
687 ******************************************************************************
688 */
M4VSS3GPP_intCheckClipCompatibleWithVssEditing(M4VIDEOEDITING_ClipProperties * pClipProperties)689 M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing(
690 M4VIDEOEDITING_ClipProperties *pClipProperties )
691 {
692 M4OSA_UInt32 uiNbOfValidStreams = 0;
693 M4OSA_ERR video_err = M4NO_ERROR;
694 M4OSA_ERR audio_err = M4NO_ERROR;
695 /********* file type *********/
696
697 if( M4VIDEOEDITING_kFileType_AMR == pClipProperties->FileType )
698 {
699 M4OSA_TRACE1_0(
700 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing:\
701 returning M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED");
702 return M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED;
703 }
704
705 if( M4VIDEOEDITING_kFileType_MP3 == pClipProperties->FileType )
706 {
707 M4OSA_TRACE3_0(
708 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR");
709 return M4NO_ERROR;
710 }
711
712 /********* Video *********/
713
714 if( M4VIDEOEDITING_kNoneVideo
715 != pClipProperties->VideoStreamType ) /**< if there is a video stream */
716 {
717 /* Check video format is MPEG-4, H263 or H264 */
718 switch( pClipProperties->VideoStreamType )
719 {
720 case M4VIDEOEDITING_kH263:
721 case M4VIDEOEDITING_kMPEG4:
722 case M4VIDEOEDITING_kH264:
723 uiNbOfValidStreams++;
724 pClipProperties->bVideoIsEditable = M4OSA_TRUE;
725 break;
726
727 default: /*< KO, we return error */
728 M4OSA_TRACE1_0(
729 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported video format");
730 video_err = M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT;
731 break;
732 }
733 }
734 else
735 {
736 /**
737 * Audio only stream are currently not supported by the VSS editing feature
738 (unless in the MP3 case) */
739 M4OSA_TRACE1_0(
740 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): No video stream in clip");
741 video_err = M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE;
742 }
743
744 /********* Audio *********/
745 if( M4VIDEOEDITING_kNoneAudio != pClipProperties->
746 AudioStreamType ) /**< if there is an audio stream */
747 {
748 /**
749 * Check audio format is AMR-NB, EVRC or AAC */
750 switch( pClipProperties->AudioStreamType )
751 {
752 case M4VIDEOEDITING_kAMR_NB:
753 pClipProperties->bAudioIsEditable = M4OSA_TRUE;
754 uiNbOfValidStreams++;
755 break;
756
757 case M4VIDEOEDITING_kAAC:
758 case M4VIDEOEDITING_kAACplus:
759 case M4VIDEOEDITING_keAACplus:
760 switch( pClipProperties->uiSamplingFrequency )
761 {
762 case 8000:
763 case 16000:
764 case 22050:
765 case 24000:
766 case 32000:
767 case 44100:
768 case 48000:
769 pClipProperties->bAudioIsEditable = M4OSA_TRUE;
770 break;
771
772 default:
773 break;
774 }
775 uiNbOfValidStreams++;
776 break;
777
778 case M4VIDEOEDITING_kEVRC:
779 /*< OK, we proceed, no return */
780 uiNbOfValidStreams++;
781 break;
782
783 default: /*< KO, we return error */
784 M4OSA_TRACE1_0(
785 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported audio format");
786 audio_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT;
787 break;
788 }
789 }
790 else
791 {
792 /* Silence is always editable */
793 pClipProperties->bAudioIsEditable = M4OSA_TRUE;
794 }
795
796 /**
797 * Check there is at least one valid stream in the file... */
798 if( video_err != M4NO_ERROR )
799 return video_err;
800
801 if( audio_err != M4NO_ERROR )
802 return audio_err;
803
804 if( 0 == uiNbOfValidStreams )
805 {
806 M4OSA_TRACE1_0(
807 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): File contains no supported stream,\
808 returning M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE");
809 return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE;
810 }
811
812 /**
813 * Return with no error */
814 M4OSA_TRACE3_0(
815 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR");
816 return M4NO_ERROR;
817 }
818
819 /**
820 ******************************************************************************
821 * M4OSA_ERR M4VSS3GPP_intAudioMixingCompatibility()
822 * @brief This function allows checking if two clips are compatible with each other for
823 * VSS 3GPP audio mixing feature.
824 * @note
825 * @param pC (IN) Context of the audio mixer
826 * @param pInputClipProperties (IN) Clip analysis of the first clip
827 * @param pAddedClipProperties (IN) Clip analysis of the second clip
828 * @return M4NO_ERROR: No error
829 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only)
830 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
831 * @return M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP
832 * @return M4NO_ERROR
833 ******************************************************************************
834 */
835 M4OSA_ERR
M4VSS3GPP_intAudioMixingCompatibility(M4VSS3GPP_InternalAudioMixingContext * pC,M4VIDEOEDITING_ClipProperties * pInputClipProperties,M4VIDEOEDITING_ClipProperties * pAddedClipProperties)836 M4VSS3GPP_intAudioMixingCompatibility( M4VSS3GPP_InternalAudioMixingContext
837 *pC, M4VIDEOEDITING_ClipProperties *pInputClipProperties,
838 M4VIDEOEDITING_ClipProperties *pAddedClipProperties )
839 {
840 M4OSA_Bool bClip1IsAAC = M4OSA_FALSE;
841 M4OSA_Bool bClip2IsAAC = M4OSA_FALSE;
842
843 /**
844 * Reset settings */
845 pInputClipProperties->bAudioIsEditable = M4OSA_FALSE;
846 pAddedClipProperties->bAudioIsEditable = M4OSA_FALSE;
847 pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
848 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
849
850 /**
851 * Check that analysis has been generated by this version of the VSS3GPP library */
852 if( ( pInputClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR)
853 || (pInputClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR)
854 || (pInputClipProperties->Version[2]
855 != M4VIDEOEDITING_VERSION_REVISION) )
856 {
857 M4OSA_TRACE1_0(
858 "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\
859 by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION");
860 return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION;
861 }
862
863 if( ( pAddedClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR)
864 || (pAddedClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR)
865 || (pAddedClipProperties->Version[2]
866 != M4VIDEOEDITING_VERSION_REVISION) )
867 {
868 M4OSA_TRACE1_0(
869 "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\
870 by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION");
871 return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION;
872 }
873
874 /********* input file type *********/
875
876 if( M4VIDEOEDITING_kFileType_3GPP != pInputClipProperties->FileType )
877 {
878 M4OSA_TRACE1_0(
879 "M4VSS3GPP_intAudioMixingCompatibility:\
880 returning M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP");
881 return M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP;
882 }
883
884 /********* input audio *********/
885
886 if( M4VIDEOEDITING_kNoneAudio != pInputClipProperties->
887 AudioStreamType ) /**< if there is an audio stream */
888 {
889 /**
890 * Check audio format is AMR-NB or AAC */
891 switch( pInputClipProperties->AudioStreamType )
892 {
893 case M4VIDEOEDITING_kAMR_NB:
894 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
895 break;
896
897 case M4VIDEOEDITING_kAAC:
898 case M4VIDEOEDITING_kAACplus:
899 case M4VIDEOEDITING_keAACplus:
900 switch( pInputClipProperties->uiSamplingFrequency )
901 {
902 case 8000:
903 case 16000:
904 case 22050:
905 case 24000:
906 case 32000:
907 case 44100:
908 case 48000:
909 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
910 break;
911
912 default:
913 break;
914 }
915 bClip1IsAAC = M4OSA_TRUE;
916 break;
917 default:
918 break;
919 }
920 }
921 else
922 {
923 /* Silence is always editable */
924 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
925 }
926
927 /********* added audio *********/
928
929 if( M4VIDEOEDITING_kNoneAudio != pAddedClipProperties->
930 AudioStreamType ) /**< if there is an audio stream */
931 {
932 /**
933 * Check audio format is AMR-NB or AAC */
934 switch( pAddedClipProperties->AudioStreamType )
935 {
936 case M4VIDEOEDITING_kAMR_NB:
937 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
938 pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
939 M4OSA_TRUE; /* I use this field to know if silence supported */
940 break;
941
942 case M4VIDEOEDITING_kAAC:
943 case M4VIDEOEDITING_kAACplus:
944 case M4VIDEOEDITING_keAACplus:
945 switch( pAddedClipProperties->uiSamplingFrequency )
946 {
947 case 8000:
948 case 16000:
949 case 22050:
950 case 24000:
951 case 32000:
952 case 44100:
953 case 48000:
954 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
955 break;
956
957 default:
958 break;
959 }
960 pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
961 M4OSA_TRUE; /* I use this field to know if silence supported */
962 bClip2IsAAC = M4OSA_TRUE;
963 break;
964
965 case M4VIDEOEDITING_kEVRC:
966 break;
967
968 case M4VIDEOEDITING_kPCM:
969 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
970 pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
971 M4OSA_TRUE; /* I use this field to know if silence supported */
972
973 if( pAddedClipProperties->uiSamplingFrequency == 16000 )
974 {
975 bClip2IsAAC = M4OSA_TRUE;
976 }
977 break;
978
979 case M4VIDEOEDITING_kMP3: /*RC*/
980 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
981 pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
982 M4OSA_TRUE; /* I use this field to know if silence supported */
983 break;
984
985 default:
986 /* The writer cannot write this into a 3gpp */
987 M4OSA_TRACE1_0(
988 "M4VSS3GPP_intAudioMixingCompatibility:\
989 returning M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM");
990 return M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM;
991 }
992 }
993 else
994 {
995 /* Silence is always editable */
996 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
997 pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
998 M4OSA_TRUE; /* I use this field to know if silence supported */
999 }
1000
1001 if( pC->bRemoveOriginal == M4OSA_FALSE )
1002 {
1003 if( pInputClipProperties->uiSamplingFrequency
1004 != pAddedClipProperties->uiSamplingFrequency )
1005 {
1006 /* We need to call SSRC in order to align ASF and/or nb of channels */
1007 /* Moreover, audio encoder may be needed in case of audio replacing... */
1008 pC->b_SSRCneeded = M4OSA_TRUE;
1009 }
1010
1011 if( pInputClipProperties->uiNbChannels
1012 < pAddedClipProperties->uiNbChannels )
1013 {
1014 /* Stereo to Mono */
1015 pC->ChannelConversion = 1;
1016 }
1017 else if( pInputClipProperties->uiNbChannels
1018 > pAddedClipProperties->uiNbChannels )
1019 {
1020 /* Mono to Stereo */
1021 pC->ChannelConversion = 2;
1022 }
1023 }
1024
1025 pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE;
1026
1027 /**
1028 * Return with no error */
1029 M4OSA_TRACE3_0(
1030 "M4VSS3GPP_intAudioMixingCompatibility(): returning M4NO_ERROR");
1031 return M4NO_ERROR;
1032 }
1033