M4VSS3GPP_ClipAnalysis.c revision b5c7784c96a606890eb8a8b560153ef4a5d1a0d9
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
37
38#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
39#include "M4VD_EXTERNAL_Interface.h"
40
41#endif
42
43/**
44 *    OSAL headers */
45#include "M4OSA_Memory.h" /* OSAL memory management */
46#include "M4OSA_Debug.h"  /* OSAL debug management */
47
48/**
49 ******************************************************************************
50 * M4OSA_ERR M4VSS3GPP_editAnalyseClip()
51 * @brief    This function allows checking if a clip is compatible with VSS 3GPP editing
52 * @note    It also fills a ClipAnalysis structure, which can be used to check if two
53 *        clips are compatible
54 * @param    pClip                (IN) File descriptor of the input 3GPP/MP3 clip file.
55 * @param    pClipProperties        (IN) Pointer to a valid ClipProperties structure.
56 * @param    FileType            (IN) Type of the input file (.3gp, .amr, .mp3)
57 * @return    M4NO_ERROR:            No error
58 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
59 * @return   M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED
60 * @return   M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
61 * @return   M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED
62 * @return   M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE
63 * @return   M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE
64 * @return   M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC
65 * @return   M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT
66 * @return   M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE
67 * @return   M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT
68 * @return   M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE
69 ******************************************************************************
70 */
71M4OSA_ERR M4VSS3GPP_editAnalyseClip( M4OSA_Void *pClip,
72                                    M4VIDEOEDITING_FileType FileType,
73                                    M4VIDEOEDITING_ClipProperties *pClipProperties,
74                                    M4OSA_FileReadPointer *pFileReadPtrFct )
75{
76    M4OSA_ERR err;
77    M4VSS3GPP_ClipContext *pClipContext;
78    M4VSS3GPP_ClipSettings ClipSettings;
79
80    M4OSA_TRACE3_2(
81        "M4VSS3GPP_editAnalyseClip called with pClip=0x%x, pClipProperties=0x%x",
82        pClip, pClipProperties);
83
84    /**
85    *    Check input parameter */
86    M4OSA_DEBUG_IF2((M4OSA_NULL == pClip), M4ERR_PARAMETER,
87        "M4VSS3GPP_editAnalyseClip: pClip is M4OSA_NULL");
88    M4OSA_DEBUG_IF2((M4OSA_NULL == pClipProperties), M4ERR_PARAMETER,
89        "M4VSS3GPP_editAnalyseClip: pClipProperties is M4OSA_NULL");
90
91    /**
92    * Build dummy clip settings, in order to use the editClipOpen function */
93    ClipSettings.pFile = pClip;
94    ClipSettings.FileType = FileType;
95    ClipSettings.uiBeginCutTime = 0;
96    ClipSettings.uiEndCutTime = 0;
97
98    /* Clip properties not build yet, set at least this flag */
99    ClipSettings.ClipProperties.bAnalysed = M4OSA_FALSE;
100
101    /**
102    * Open the clip in fast open mode */
103    err = M4VSS3GPP_intClipInit(&pClipContext, pFileReadPtrFct);
104
105    if( M4NO_ERROR != err )
106    {
107        M4OSA_TRACE1_1(
108            "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipInit() returns 0x%x!",
109            err);
110
111        /**
112        * Free the clip */
113        if( M4OSA_NULL != pClipContext )
114        {
115            M4VSS3GPP_intClipCleanUp(pClipContext);
116        }
117        return err;
118    }
119
120    err = M4VSS3GPP_intClipOpen(pClipContext, &ClipSettings, M4OSA_FALSE,
121        M4OSA_TRUE, M4OSA_TRUE);
122
123    if( M4NO_ERROR != err )
124    {
125        M4OSA_TRACE1_1(
126            "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipOpen() returns 0x%x!",
127            err);
128
129        M4VSS3GPP_intClipCleanUp(pClipContext);
130
131        /**
132        * Here it is better to return the Editing specific error code */
133        if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err)
134            || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) )
135        {
136            M4OSA_TRACE1_0(
137                "M4VSS3GPP_editAnalyseClip:\
138                M4VSS3GPP_intClipOpen() returns M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED");
139            return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED;
140        }
141        return err;
142    }
143
144    /**
145    * Analyse the clip */
146    err = M4VSS3GPP_intBuildAnalysis(pClipContext, pClipProperties);
147
148    if( M4NO_ERROR != err )
149    {
150        M4OSA_TRACE1_1(
151            "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intBuildAnalysis() returns 0x%x!",
152            err);
153
154        /**
155        * Free the clip */
156        M4VSS3GPP_intClipCleanUp(pClipContext);
157        return err;
158    }
159
160    /**
161    * Free the clip */
162    err = M4VSS3GPP_intClipClose(pClipContext);
163
164    if( M4NO_ERROR != err )
165    {
166        M4OSA_TRACE1_1(
167            "M4VSS3GPP_editAnalyseClip: M4VSS_intClipClose() returns 0x%x!",
168            err);
169        M4VSS3GPP_intClipCleanUp(pClipContext);
170        return err;
171    }
172
173    M4VSS3GPP_intClipCleanUp(pClipContext);
174
175    /**
176    * Check the clip is compatible with VSS editing */
177    err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing(pClipProperties);
178
179    if( M4NO_ERROR != err )
180    {
181        M4OSA_TRACE1_1(
182            "M4VSS3GPP_editAnalyseClip:\
183            M4VSS3GPP_intCheckClipCompatibleWithVssEditing() returns 0x%x!",
184            err);
185        return err;
186    }
187
188    /**
189    * Return with no error */
190    M4OSA_TRACE3_0("M4VSS3GPP_editAnalyseClip(): returning M4NO_ERROR");
191    return M4NO_ERROR;
192}
193
194/**
195 ******************************************************************************
196 * M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility()
197 * @brief    This function allows checking if two clips are compatible with each other for
198 *        VSS 3GPP editing assembly feature.
199 * @note
200 * @param    pClip1Properties        (IN) Clip analysis of the first clip
201 * @param    pClip2Properties        (IN) Clip analysis of the second clip
202 * @return    M4NO_ERROR:            No error
203 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
204 * @return    M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
205 * @return    M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT
206 * @return    M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE
207 * @return    M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE
208 * @return    M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING
209 * @return  M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY
210 * @return  M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT
211 ******************************************************************************
212 */
213M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility( M4VIDEOEDITING_ClipProperties *pClip1Properties,
214                                                M4VIDEOEDITING_ClipProperties *pClip2Properties )
215{
216    M4OSA_ERR err = M4NO_ERROR;
217    M4OSA_ERR video_err = M4NO_ERROR;
218    M4OSA_ERR audio_err = M4NO_ERROR;
219
220    M4OSA_Bool bClip1IsAAC = M4OSA_FALSE;
221    M4OSA_Bool bClip2IsAAC = M4OSA_FALSE;
222
223    M4OSA_TRACE3_2("M4VSS3GPP_editCheckClipCompatibility called with pClip1Analysis=0x%x,\
224                   pClip2Analysis=0x%x", pClip1Properties, pClip2Properties);
225
226    /**
227    *    Check input parameter */
228    M4OSA_DEBUG_IF2((M4OSA_NULL == pClip1Properties), M4ERR_PARAMETER,
229        "M4VSS3GPP_editCheckClipCompatibility: pClip1Properties is M4OSA_NULL");
230    M4OSA_DEBUG_IF2((M4OSA_NULL == pClip2Properties), M4ERR_PARAMETER,
231        "M4VSS3GPP_editCheckClipCompatibility: pClip2Properties is M4OSA_NULL");
232
233    /**
234    * Check if the two clips are, alone, comptible with VSS 3GPP.
235    *
236    * Note: if a clip is not compatible with VSS3GPP, M4VSS3GPP_editAnalyseClip()
237    * did return an error to the integrator. So he should not call
238    * M4VSS3GPP_editCheckClipCompatibility
239    * with the ClipAnalysis...
240    * Still, I think it is good to redo the test here, to be sure.
241    * M4VSS3GPP_intCheckClipCompatibleWithVssEditing is not a long function to execute.*/
242    err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing(pClip1Properties);
243
244    if( err != M4NO_ERROR )
245    {
246        M4OSA_TRACE1_1(
247            "M4VSS3GPP_editCheckClipCompatibility: Clip1 not compatible with VSS3GPP,\
248            returning 0x%x", err);
249        return err;
250    }
251    err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing(pClip2Properties);
252
253    if( err != M4NO_ERROR )
254    {
255        M4OSA_TRACE1_1(
256            "M4VSS3GPP_editCheckClipCompatibility: Clip2 not compatible with VSS3GPP,\
257            returning 0x%x", err);
258        return err;
259    }
260
261    if( ( M4VIDEOEDITING_kFileType_MP3 == pClip1Properties->FileType)
262        || (M4VIDEOEDITING_kFileType_AMR == pClip1Properties->FileType) )
263    {
264        if( pClip1Properties != pClip2Properties )
265        {
266            M4OSA_TRACE1_0(
267                "M4VSS3GPP_editCheckClipCompatibility: MP3 CAN ONLY BE CUT,\
268                returning M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY");
269            return M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY;
270        }
271        else
272        {
273            /* We are in VSS Splitter mode */
274            goto audio_analysis;
275        }
276    }
277
278    /********** Video ************/
279
280    /**
281    * Check both clips have same video stream type */
282    if( pClip1Properties->VideoStreamType != pClip2Properties->VideoStreamType )
283    {
284        M4OSA_TRACE1_0(
285            "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same video format");
286        video_err = M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT;
287        goto audio_analysis;
288    }
289
290    /**
291    * Check both clips have the same video frame size */
292    if( ( pClip1Properties->uiVideoWidth != pClip2Properties->uiVideoWidth)
293        || (pClip1Properties->uiVideoHeight
294        != pClip2Properties->uiVideoHeight) )
295    {
296        M4OSA_TRACE1_0(
297            "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same video frame size");
298        video_err = M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE;
299        goto audio_analysis;
300    }
301
302    switch( pClip1Properties->VideoStreamType )
303    {
304        case M4VIDEOEDITING_kH263:
305        case M4VIDEOEDITING_kH264:
306            /**< nothing to check here */
307            break;
308
309        case M4VIDEOEDITING_kMPEG4_EMP:
310        case M4VIDEOEDITING_kMPEG4:
311            /**
312            * Check both streams have the same time scale */
313            if( pClip1Properties->uiVideoTimeScale
314                != pClip2Properties->uiVideoTimeScale )
315            {
316                M4OSA_TRACE1_2(
317                    "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same video time\
318                    scale (%d != %d), returning M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE",
319                    pClip1Properties->uiVideoTimeScale,
320                    pClip2Properties->uiVideoTimeScale);
321                video_err = M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE;
322                goto audio_analysis;
323            }
324            /**
325            * Check both streams have the same use of data partitioning */
326            if( pClip1Properties->bMPEG4dataPartition
327                != pClip2Properties->bMPEG4dataPartition )
328            {
329                M4OSA_TRACE1_2(
330                    "M4VSS3GPP_editCheckClipCompatibility:\
331                    Clips don't have the same use of data partitioning (%d != %d),\
332                    returning M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING",
333                    pClip1Properties->bMPEG4dataPartition,
334                    pClip2Properties->bMPEG4dataPartition);
335                video_err = M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING;
336                goto audio_analysis;
337            }
338            break;
339
340        default:
341            M4OSA_TRACE1_1(
342                "M4VSS3GPP_editCheckClipCompatibility: unknown video stream type (0x%x),\
343                returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT",
344                pClip1Properties->VideoStreamType);
345            video_err =
346                M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT; /**< this error should never happen,
347                                                              it's here for code safety only... */
348            goto audio_analysis;
349    }
350
351    pClip2Properties->bVideoIsCompatibleWithMasterClip = M4OSA_TRUE;
352
353    /********** Audio ************/
354
355audio_analysis:
356    if( M4VIDEOEDITING_kNoneAudio != pClip1Properties->
357        AudioStreamType ) /**< if there is an audio stream */
358    {
359        /**
360        * Check audio format is AAC */
361        switch( pClip1Properties->AudioStreamType )
362        {
363            case M4VIDEOEDITING_kAAC:
364            case M4VIDEOEDITING_kAACplus:
365            case M4VIDEOEDITING_keAACplus:
366                bClip1IsAAC = M4OSA_TRUE;
367                break;
368            default:
369                break;
370        }
371    }
372
373    if( M4VIDEOEDITING_kNoneAudio != pClip2Properties->
374        AudioStreamType ) /**< if there is an audio stream */
375    {
376        /**
377        * Check audio format is AAC */
378        switch( pClip2Properties->AudioStreamType )
379        {
380            case M4VIDEOEDITING_kAAC:
381            case M4VIDEOEDITING_kAACplus:
382            case M4VIDEOEDITING_keAACplus:
383                bClip2IsAAC = M4OSA_TRUE;
384                break;
385            default:
386                break;
387        }
388    }
389
390    /**
391    * If there is no audio, the clips are compatibles ... */
392    if( ( pClip1Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio)
393        && (pClip2Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio) )
394    {
395        /**
396        * Check both clips have same audio stream type
397        * And let_s say AAC, AAC+ and eAAC+ are mixable */
398        if( ( pClip1Properties->AudioStreamType
399            != pClip2Properties->AudioStreamType)
400            && (( M4OSA_FALSE == bClip1IsAAC) || (M4OSA_FALSE == bClip2IsAAC)) )
401        {
402            M4OSA_TRACE1_0(
403                "M4VSS3GPP_editCheckClipCompatibility:\
404                Clips don't have the same Audio Stream Type");
405
406            audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE;
407            goto analysis_done;
408        }
409
410        /**
411        * Check both clips have same number of channels */
412        if( pClip1Properties->uiNbChannels != pClip2Properties->uiNbChannels )
413        {
414            M4OSA_TRACE1_0(
415                "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same Nb of Channels");
416            audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS;
417            goto analysis_done;
418        }
419
420        /**
421        * Check both clips have same sampling frequency */
422        if( pClip1Properties->uiSamplingFrequency
423            != pClip2Properties->uiSamplingFrequency )
424        {
425            M4OSA_TRACE1_0(
426                "M4VSS3GPP_editCheckClipCompatibility:\
427                Clips don't have the same Sampling Frequency");
428            audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY;
429            goto analysis_done;
430        }
431    }
432
433    pClip2Properties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE;
434
435    /**
436    * Return with no error */
437
438analysis_done:
439    if( video_err != M4NO_ERROR )
440        return video_err;
441
442    if( audio_err != M4NO_ERROR )
443        return audio_err;
444
445    M4OSA_TRACE3_0(
446        "M4VSS3GPP_editCheckClipCompatibility(): returning M4NO_ERROR");
447    return M4NO_ERROR;
448}
449
450/**
451 ******************************************************************************
452 * M4OSA_ERR M4VSS3GPP_intBuildAnalysis()
453 * @brief    Get video and audio properties from the clip streams
454 * @note    This function must return fatal errors only (errors that should not happen
455 *        in the final integrated product).
456 * @param   pClipCtxt            (IN) internal clip context
457 * @param    pClipProperties        (OUT) Pointer to a valid ClipProperties structure.
458 * @return    M4NO_ERROR:            No error
459 ******************************************************************************
460 */
461M4OSA_ERR M4VSS3GPP_intBuildAnalysis( M4VSS3GPP_ClipContext *pClipCtxt,
462                                     M4VIDEOEDITING_ClipProperties *pClipProperties )
463{
464    M4OSA_ERR err;
465    M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo;
466    M4DECODER_VideoSize dummySize;
467    M4DECODER_AVCProfileLevel AVCProfle;
468
469    pClipProperties->bAnalysed = M4OSA_FALSE;
470
471    /**
472    * Reset video characteristics */
473    pClipProperties->VideoStreamType = M4VIDEOEDITING_kNoneVideo;
474    pClipProperties->uiClipVideoDuration = 0;
475    pClipProperties->uiVideoBitrate = 0;
476    pClipProperties->uiVideoMaxAuSize = 0;
477    pClipProperties->uiVideoWidth = 0;
478    pClipProperties->uiVideoHeight = 0;
479    pClipProperties->uiVideoTimeScale = 0;
480    pClipProperties->fAverageFrameRate = 0.0;
481    pClipProperties->ProfileAndLevel =
482        M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range;
483    pClipProperties->uiH263level = 0;
484    pClipProperties->uiVideoProfile = 0;
485    pClipProperties->bMPEG4dataPartition = M4OSA_FALSE;
486    pClipProperties->bMPEG4rvlc = M4OSA_FALSE;
487    pClipProperties->bMPEG4resynchMarker = M4OSA_FALSE;
488
489    memset((void *) &pClipProperties->ftyp,0,
490        sizeof(pClipProperties->ftyp));
491
492    /**
493    * Video Analysis */
494    if( M4OSA_NULL != pClipCtxt->pVideoStream )
495    {
496        pClipProperties->uiVideoWidth = pClipCtxt->pVideoStream->m_videoWidth;
497        pClipProperties->uiVideoHeight = pClipCtxt->pVideoStream->m_videoHeight;
498        pClipProperties->fAverageFrameRate =
499            pClipCtxt->pVideoStream->m_averageFrameRate;
500
501        switch( pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
502        {
503            case M4DA_StreamTypeVideoMpeg4:
504
505                pClipProperties->VideoStreamType = M4VIDEOEDITING_kMPEG4;
506
507#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
508   /* This issue is so incredibly stupid that it's depressing. Basically, a file can be analysed
509   outside of any context (besides that of the clip itself), so that for instance two clips can
510   be checked for compatibility before allocating an edit context for editing them. But this
511   means there is no way in heck to pass an external video decoder (to begin with) to this
512   function, as they work by being registered in an existing context; furthermore, it is actually
513   pretty overkill to use a full decoder for that, moreso a HARDWARE decoder just to get the
514   clip config info. In fact, the hardware itself doesn't provide this service, in the case of a
515   HW decoder, the shell builds the config info itself, so we don't need the actual decoder, only
516   a detached functionality of it. So in case HW/external decoders may be present, we instead use
517   directly the DSI parsing function of the shell HW decoder (which we know to be present, since
518   HW decoders are possible) to get the config info. Notice this function is used even if the
519   software decoder is actually present and even if it will end up being actually used: figuring
520   out the config does not involve actual decoding nor the particularities of a specific decoder,
521   it's the fact that it's MPEG4 that matters, so it should not be functionally any different
522   from the way it was done before (and it's light enough for performance not to be any problem
523         whatsoever). */
524
525                err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream->
526                    m_basicProperties.m_pDecoderSpecificInfo,
527                    pClipCtxt->pVideoStream->
528                    m_basicProperties.m_decoderSpecificInfoSize,
529                    &DecConfigInfo, &dummySize);
530
531                if( M4NO_ERROR != err )
532                {
533                    M4OSA_TRACE1_1(
534                        "M4VSS3GPP_intBuildAnalysis():\
535                        M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", err);
536                    return err;
537                }
538
539    #else /* an external decoder cannot be present, so we can rely on the
540                software decoder to be installed already */
541                /* Get MPEG-4 decoder config. */
542
543                err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctGetOption(
544                    pClipCtxt->pViDecCtxt,
545                    M4DECODER_MPEG4_kOptionID_DecoderConfigInfo,
546                    &DecConfigInfo);
547
548                if( M4NO_ERROR != err )
549                {
550                    M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): m_pFctGetOption(DecConfigInfo)\
551                        returns 0x%x", err);
552                    return err;
553                }
554
555    #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
556
557                pClipProperties->uiVideoProfile = DecConfigInfo.uiProfile;
558                pClipProperties->uiVideoTimeScale = DecConfigInfo.uiTimeScale;
559                pClipProperties->bMPEG4dataPartition =
560                    DecConfigInfo.bDataPartition;
561                pClipProperties->bMPEG4rvlc = DecConfigInfo.bUseOfRVLC;
562                pClipProperties->bMPEG4resynchMarker =
563                    DecConfigInfo.uiUseOfResynchMarker;
564
565                /* Supported enum value for profile and level */
566                switch( pClipProperties->uiVideoProfile )
567                {
568                    case 0x08:
569                        pClipProperties->ProfileAndLevel =
570                            M4VIDEOEDITING_kMPEG4_SP_Level_0;
571                        break;
572
573                    case 0x09:
574                        pClipProperties->ProfileAndLevel =
575                            M4VIDEOEDITING_kMPEG4_SP_Level_0b;
576                        break;
577
578                    case 0x01:
579                        pClipProperties->ProfileAndLevel =
580                            M4VIDEOEDITING_kMPEG4_SP_Level_1;
581                        break;
582
583                    case 0x02:
584                        pClipProperties->ProfileAndLevel =
585                            M4VIDEOEDITING_kMPEG4_SP_Level_2;
586                        break;
587
588                    case 0x03:
589                        pClipProperties->ProfileAndLevel =
590                            M4VIDEOEDITING_kMPEG4_SP_Level_3;
591                        break;
592
593                    case 0x04:
594                        pClipProperties->ProfileAndLevel =
595                            M4VIDEOEDITING_kMPEG4_SP_Level_4a;
596                        break;
597
598                    case 0x05:
599                        pClipProperties->ProfileAndLevel =
600                            M4VIDEOEDITING_kMPEG4_SP_Level_5;
601                        break;
602                }
603                break;
604
605            case M4DA_StreamTypeVideoH263:
606
607                pClipProperties->VideoStreamType = M4VIDEOEDITING_kH263;
608
609                /* Get H263 level, which is sixth byte in the DSI */
610                pClipProperties->uiH263level = pClipCtxt->pVideoStream->
611                    m_basicProperties.m_pDecoderSpecificInfo[5];
612                /* Get H263 profile, which is fifth byte in the DSI */
613                pClipProperties->uiVideoProfile = pClipCtxt->pVideoStream->
614                    m_basicProperties.m_pDecoderSpecificInfo[6];
615                /* H263 time scale is always 30000 */
616                pClipProperties->uiVideoTimeScale = 30000;
617
618                /* Supported enum value for profile and level */
619                if( pClipProperties->uiVideoProfile == 0 )
620                {
621                    switch( pClipProperties->uiH263level )
622                    {
623                        case 10:
624                            pClipProperties->ProfileAndLevel =
625                                M4VIDEOEDITING_kH263_Profile_0_Level_10;
626                            break;
627
628                        case 20:
629                            pClipProperties->ProfileAndLevel =
630                                M4VIDEOEDITING_kH263_Profile_0_Level_20;
631                            break;
632
633                        case 30:
634                            pClipProperties->ProfileAndLevel =
635                                M4VIDEOEDITING_kH263_Profile_0_Level_30;
636                            break;
637
638                        case 40:
639                            pClipProperties->ProfileAndLevel =
640                                M4VIDEOEDITING_kH263_Profile_0_Level_40;
641                            break;
642
643                        case 45:
644                            pClipProperties->ProfileAndLevel =
645                                M4VIDEOEDITING_kH263_Profile_0_Level_45;
646                            break;
647                    }
648                }
649                break;
650
651            case M4DA_StreamTypeVideoMpeg4Avc:
652
653                pClipProperties->VideoStreamType = M4VIDEOEDITING_kH264;
654#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
655
656                err = M4DECODER_EXTERNAL_ParseAVCDSI(pClipCtxt->pVideoStream->
657                    m_basicProperties.m_pDecoderSpecificInfo,
658                    pClipCtxt->pVideoStream->
659                    m_basicProperties.m_decoderSpecificInfoSize,
660                    &AVCProfle);
661
662                if( M4NO_ERROR != err )
663                {
664                    M4OSA_TRACE1_1(
665                        "M4VSS3GPP_intBuildAnalysis(): \
666                         M4DECODER_EXTERNAL_ParseAVCDSI returns 0x%08X",
667                         err);
668                    return err;
669                }
670
671#else /* an external decoder cannot be present, so we can rely on the
672                software decoder to be installed already */
673
674                err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctGetOption(
675                    pClipCtxt->pViDecCtxt,
676                    M4DECODER_kOptionID_AVCProfileAndLevel, &AVCProfle);
677
678                if( M4NO_ERROR != err )
679                {
680                    M4OSA_TRACE1_1(
681                        "M4VSS3GPP_intBuildAnalysis(): m_pFctGetOption(AVCProfileInfo)\
682                            returns 0x%x", err);
683                    return err;
684                }
685
686#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
687
688                switch( AVCProfle )
689                {
690                    case M4DECODER_AVC_kProfile_0_Level_1:
691                        pClipProperties->ProfileAndLevel =
692                            M4VIDEOEDITING_kH264_Profile_0_Level_1;
693                        break;
694
695                    case M4DECODER_AVC_kProfile_0_Level_1b:
696                        pClipProperties->ProfileAndLevel =
697                            M4VIDEOEDITING_kH264_Profile_0_Level_1b;
698                        break;
699
700                    case M4DECODER_AVC_kProfile_0_Level_1_1:
701                        pClipProperties->ProfileAndLevel =
702                            M4VIDEOEDITING_kH264_Profile_0_Level_1_1;
703                        break;
704
705                    case M4DECODER_AVC_kProfile_0_Level_1_2:
706                        pClipProperties->ProfileAndLevel =
707                            M4VIDEOEDITING_kH264_Profile_0_Level_1_2;
708                        break;
709
710                    case M4DECODER_AVC_kProfile_0_Level_1_3:
711                        pClipProperties->ProfileAndLevel =
712                            M4VIDEOEDITING_kH264_Profile_0_Level_1_3;
713                        break;
714
715                    case M4DECODER_AVC_kProfile_0_Level_2:
716                        pClipProperties->ProfileAndLevel =
717                            M4VIDEOEDITING_kH264_Profile_0_Level_2;
718                        break;
719
720                    case M4DECODER_AVC_kProfile_0_Level_2_1:
721                        pClipProperties->ProfileAndLevel =
722                            M4VIDEOEDITING_kH264_Profile_0_Level_2_1;
723                        break;
724
725                    case M4DECODER_AVC_kProfile_0_Level_2_2:
726                        pClipProperties->ProfileAndLevel =
727                            M4VIDEOEDITING_kH264_Profile_0_Level_2_2;
728                        break;
729
730                    case M4DECODER_AVC_kProfile_0_Level_3:
731                        pClipProperties->ProfileAndLevel =
732                            M4VIDEOEDITING_kH264_Profile_0_Level_3;
733                        break;
734
735                    case M4DECODER_AVC_kProfile_0_Level_3_1:
736                        pClipProperties->ProfileAndLevel =
737                            M4VIDEOEDITING_kH264_Profile_0_Level_3_1;
738                        break;
739
740                    case M4DECODER_AVC_kProfile_0_Level_3_2:
741                        pClipProperties->ProfileAndLevel =
742                            M4VIDEOEDITING_kH264_Profile_0_Level_3_2;
743                        break;
744
745                    case M4DECODER_AVC_kProfile_0_Level_4:
746                        pClipProperties->ProfileAndLevel =
747                            M4VIDEOEDITING_kH264_Profile_0_Level_4;
748                        break;
749
750                    case M4DECODER_AVC_kProfile_0_Level_4_1:
751                        pClipProperties->ProfileAndLevel =
752                            M4VIDEOEDITING_kH264_Profile_0_Level_4_1;
753                        break;
754
755                    case M4DECODER_AVC_kProfile_0_Level_4_2:
756                        pClipProperties->ProfileAndLevel =
757                            M4VIDEOEDITING_kH264_Profile_0_Level_4_2;
758                        break;
759
760                    case M4DECODER_AVC_kProfile_0_Level_5:
761                        pClipProperties->ProfileAndLevel =
762                            M4VIDEOEDITING_kH264_Profile_0_Level_5;
763                        break;
764
765                    case M4DECODER_AVC_kProfile_0_Level_5_1:
766                        pClipProperties->ProfileAndLevel =
767                            M4VIDEOEDITING_kH264_Profile_0_Level_5_1;
768                        break;
769
770                    case M4DECODER_AVC_kProfile_and_Level_Out_Of_Range:
771                    default:
772                        pClipProperties->ProfileAndLevel =
773                            M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range;
774                }
775
776                break;
777
778            default:
779                M4OSA_TRACE1_1(
780                    "M4VSS3GPP_intBuildAnalysis: unknown input video format (0x%x),\
781                    returning M4NO_ERROR",pClipCtxt->pVideoStream->m_basicProperties.m_streamType);
782                return
783                    M4NO_ERROR; /**< We do not return error here.
784                                The video format compatibility check will be done latter */
785        }
786
787        pClipProperties->uiClipVideoDuration =
788            (M4OSA_UInt32)pClipCtxt->pVideoStream->m_basicProperties.m_duration;
789        pClipProperties->uiVideoMaxAuSize =
790            pClipCtxt->pVideoStream->m_basicProperties.m_maxAUSize;
791
792        /* if video bitrate not available retrieve an estimation of the overall bitrate */
793        pClipProperties->uiVideoBitrate =
794            (M4OSA_UInt32)pClipCtxt->pVideoStream->
795            m_basicProperties.m_averageBitRate;
796
797        if( 0 == pClipProperties->uiVideoBitrate )
798        {
799            pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
800                pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate,
801                &pClipProperties->uiVideoBitrate);
802
803            if( M4OSA_NULL != pClipCtxt->pAudioStream )
804            {
805                /* we get the overall bitrate, substract the audio bitrate if any */
806                pClipProperties->uiVideoBitrate -=
807                    pClipCtxt->pAudioStream->m_basicProperties.m_averageBitRate;
808            }
809        }
810    }
811
812    /**
813    * Reset audio characteristics */
814    pClipProperties->AudioStreamType = M4VIDEOEDITING_kNoneAudio;
815    pClipProperties->uiClipAudioDuration = 0;
816    pClipProperties->uiAudioBitrate = 0;
817    pClipProperties->uiAudioMaxAuSize = 0;
818    pClipProperties->uiNbChannels = 0;
819    pClipProperties->uiSamplingFrequency = 0;
820    pClipProperties->uiExtendedSamplingFrequency = 0;
821    pClipProperties->uiDecodedPcmSize = 0;
822
823    /**
824    * Audio Analysis */
825    if( M4OSA_NULL != pClipCtxt->pAudioStream )
826    {
827        switch( pClipCtxt->pAudioStream->m_basicProperties.m_streamType )
828        {
829            case M4DA_StreamTypeAudioAmrNarrowBand:
830
831                pClipProperties->AudioStreamType = M4VIDEOEDITING_kAMR_NB;
832                break;
833
834            case M4DA_StreamTypeAudioAac:
835
836                pClipProperties->AudioStreamType = M4VIDEOEDITING_kAAC;
837                break;
838
839            case M4DA_StreamTypeAudioMp3:
840
841                pClipProperties->AudioStreamType = M4VIDEOEDITING_kMP3;
842                break;
843
844            case M4DA_StreamTypeAudioEvrc:
845
846                pClipProperties->AudioStreamType = M4VIDEOEDITING_kEVRC;
847                break;
848
849            case M4DA_StreamTypeAudioPcm:
850
851                pClipProperties->AudioStreamType = M4VIDEOEDITING_kPCM;
852                break;
853
854            default:
855
856                M4OSA_TRACE1_1(
857                    "M4VSS3GPP_intBuildAnalysis: unknown input audio format (0x%x),\
858                    returning M4NO_ERROR!",
859                    pClipCtxt->pAudioStream->m_basicProperties.m_streamType);
860                return
861                    M4NO_ERROR; /**< We do not return error here.
862                                The audio format compatibility check will be done latter */
863        }
864
865        pClipProperties->uiAudioMaxAuSize =
866            pClipCtxt->pAudioStream->m_basicProperties.m_maxAUSize;
867        pClipProperties->uiClipAudioDuration =
868            (M4OSA_UInt32)pClipCtxt->pAudioStream->m_basicProperties.m_duration;
869
870        pClipProperties->uiNbChannels = pClipCtxt->pAudioStream->m_nbChannels;
871        pClipProperties->uiSamplingFrequency =
872            pClipCtxt->pAudioStream->m_samplingFrequency;
873        pClipProperties->uiDecodedPcmSize =
874            pClipCtxt->pAudioStream->m_byteFrameLength
875            * pClipCtxt->pAudioStream->m_byteSampleSize
876            * pClipCtxt->pAudioStream->m_nbChannels;
877
878        /**
879        * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps
880        according the GetProperties function */
881        pClipProperties->uiAudioBitrate =
882            (M4OSA_UInt32)pClipCtxt->pAudioStream->
883            m_basicProperties.m_averageBitRate;
884
885        if( 0 == pClipProperties->uiAudioBitrate )
886        {
887            if( M4VIDEOEDITING_kAMR_NB == pClipProperties->AudioStreamType )
888            {
889                /**
890                *Better returning a guessed 12.2 kbps value than a sure-to-be-false 0 kbps value!*/
891                pClipProperties->uiAudioBitrate = M4VSS3GPP_AMR_DEFAULT_BITRATE;
892            }
893            else if( M4VIDEOEDITING_kEVRC == pClipProperties->AudioStreamType )
894            {
895                /**
896                *Better returning a guessed 9.2 kbps value than a sure-to-be-false 0 kbps value!*/
897                pClipProperties->uiAudioBitrate =
898                    M4VSS3GPP_EVRC_DEFAULT_BITRATE;
899            }
900            else
901            {
902                pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
903                    pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate,
904                    &pClipProperties->uiAudioBitrate);
905
906                if( M4OSA_NULL != pClipCtxt->pVideoStream )
907                {
908                    /* we get the overall bitrate, substract the video bitrate if any */
909                    pClipProperties->uiAudioBitrate -= pClipCtxt->pVideoStream->
910                        m_basicProperties.m_averageBitRate;
911                }
912            }
913        }
914
915        /* New aac properties */
916        if( M4DA_StreamTypeAudioAac
917            == pClipCtxt->pAudioStream->m_basicProperties.m_streamType )
918        {
919            pClipProperties->uiNbChannels = pClipCtxt->AacProperties.aNumChan;
920            pClipProperties->uiSamplingFrequency =
921                pClipCtxt->AacProperties.aSampFreq;
922
923            if( pClipCtxt->AacProperties.aSBRPresent )
924            {
925                pClipProperties->AudioStreamType = M4VIDEOEDITING_kAACplus;
926                pClipProperties->uiExtendedSamplingFrequency =
927                    pClipCtxt->AacProperties.aExtensionSampFreq;
928            }
929
930            if( pClipCtxt->AacProperties.aPSPresent )
931            {
932                pClipProperties->AudioStreamType = M4VIDEOEDITING_keAACplus;
933            }
934        }
935    }
936
937    /* Get 'ftyp' atom */
938    err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption(
939        pClipCtxt->pReaderContext,
940        M4READER_kOptionID_3gpFtypBox, &pClipProperties->ftyp);
941
942    if( M4NO_ERROR == err )
943    {
944        M4OSA_UInt8 i;
945
946        for ( i = 0; i < pClipProperties->ftyp.nbCompatibleBrands; i++ )
947            if( M4VIDEOEDITING_BRAND_EMP
948                == pClipProperties->ftyp.compatible_brands[i] )
949                pClipProperties->VideoStreamType = M4VIDEOEDITING_kMPEG4_EMP;
950    }
951
952    /**
953    * We write the VSS 3GPP version in the clip analysis to be sure the integrator doesn't
954    * mix older analysis results with newer libraries */
955    pClipProperties->Version[0] = M4VIDEOEDITING_VERSION_MAJOR;
956    pClipProperties->Version[1] = M4VIDEOEDITING_VERSION_MINOR;
957    pClipProperties->Version[2] = M4VIDEOEDITING_VERSION_REVISION;
958
959    pClipProperties->FileType = pClipCtxt->pSettings->FileType;
960
961    if( pClipProperties->uiClipVideoDuration
962        > pClipProperties->uiClipAudioDuration )
963        pClipProperties->uiClipDuration = pClipProperties->uiClipVideoDuration;
964    else
965        pClipProperties->uiClipDuration = pClipProperties->uiClipAudioDuration;
966
967    /* Reset compatibility chart */
968    pClipProperties->bVideoIsEditable = M4OSA_FALSE;
969    pClipProperties->bAudioIsEditable = M4OSA_FALSE;
970    pClipProperties->bVideoIsCompatibleWithMasterClip = M4OSA_FALSE;
971    pClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
972
973    /* Analysis successfully completed */
974    pClipProperties->bAnalysed = M4OSA_TRUE;
975
976    /**
977    * Return with no error */
978    M4OSA_TRACE3_0("M4VSS3GPP_intBuildAnalysis(): returning M4NO_ERROR");
979    return M4NO_ERROR;
980}
981
982/**
983 ******************************************************************************
984 * M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing()
985 * @brief    Check if the clip is compatible with VSS editing
986 * @note
987 * @param   pClipCtxt            (IN) internal clip context
988 * @param    pClipProperties     (OUT) Pointer to a valid ClipProperties structure.
989 * @return    M4NO_ERROR:            No error
990 ******************************************************************************
991 */
992M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing(
993    M4VIDEOEDITING_ClipProperties *pClipProperties )
994{
995    M4OSA_UInt32 uiNbOfValidStreams = 0;
996    M4OSA_ERR video_err = M4NO_ERROR;
997    M4OSA_ERR audio_err = M4NO_ERROR;
998
999    /**
1000    * Check that analysis has been generated by this version of the VSS3GPP library */
1001    if( ( pClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR)
1002        || (pClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR)
1003        || (pClipProperties->Version[2]
1004    != M4VIDEOEDITING_VERSION_REVISION) )
1005    {
1006        M4OSA_TRACE1_0(
1007            "M4VSS3GPP_intCheckClipCompatibleWithVssEditing: The clip analysis has been generated\
1008            by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION");
1009        return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION;
1010    }
1011
1012    /********* file type *********/
1013
1014    if( M4VIDEOEDITING_kFileType_AMR == pClipProperties->FileType )
1015    {
1016        M4OSA_TRACE1_0(
1017            "M4VSS3GPP_intCheckClipCompatibleWithVssEditing:\
1018            returning M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED");
1019        return M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED;
1020    }
1021
1022    if( M4VIDEOEDITING_kFileType_MP3 == pClipProperties->FileType )
1023    {
1024        M4OSA_TRACE3_0(
1025            "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR");
1026        return M4NO_ERROR;
1027    }
1028
1029    /********* Video *********/
1030
1031    if( M4VIDEOEDITING_kNoneVideo
1032        != pClipProperties->VideoStreamType ) /**< if there is a video stream */
1033    {
1034        /**
1035        * Check video format is MPEG-4 or H263 */
1036        switch( pClipProperties->VideoStreamType )
1037        {
1038            case M4VIDEOEDITING_kH263:
1039                if( M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range
1040                    == pClipProperties->ProfileAndLevel )
1041                {
1042                    M4OSA_TRACE1_0(
1043                        "M4VSS3GPP_intCheckClipCompatibleWithVssEditing():\
1044                        unsupported H263 profile");
1045                    video_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE;
1046                    break;
1047                }
1048                uiNbOfValidStreams++;
1049                pClipProperties->bVideoIsEditable = M4OSA_TRUE;
1050                break;
1051
1052            case M4VIDEOEDITING_kMPEG4_EMP:
1053            case M4VIDEOEDITING_kMPEG4:
1054                if( M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range
1055                    == pClipProperties->ProfileAndLevel )
1056                {
1057                    M4OSA_TRACE1_0(
1058                        "M4VSS3GPP_intCheckClipCompatibleWithVssEditing():\
1059                        unsupported MPEG-4 profile");
1060                    video_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE;
1061                    break;
1062                }
1063
1064                if( M4OSA_TRUE == pClipProperties->bMPEG4rvlc )
1065                {
1066                    M4OSA_TRACE1_0(
1067                        "M4VSS3GPP_intCheckClipCompatibleWithVssEditing():\
1068                        unsupported MPEG-4 RVLC tool");
1069                    video_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC;
1070                    break;
1071                }
1072                uiNbOfValidStreams++;
1073                pClipProperties->bVideoIsEditable = M4OSA_TRUE;
1074                break;
1075
1076            case M4VIDEOEDITING_kH264:
1077                if( M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range
1078                    == pClipProperties->ProfileAndLevel )
1079                {
1080                    M4OSA_TRACE1_0(
1081                        "M4VSS3GPP_intCheckClipCompatibleWithVssEditing():\
1082                        unsupported H264 profile");
1083                    video_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H264_PROFILE;
1084                    break;
1085                }
1086
1087                uiNbOfValidStreams++;
1088                pClipProperties->bVideoIsEditable = M4OSA_TRUE;
1089                break;
1090
1091            default: /*< KO, we return error */
1092                M4OSA_TRACE1_0(
1093                    "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported video format");
1094                video_err = M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT;
1095                break;
1096        }
1097    }
1098    else
1099    {
1100        /**
1101        * Audio only stream are currently not supported by the VSS editing feature
1102        (unless in the MP3 case) */
1103        M4OSA_TRACE1_0(
1104            "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): No video stream in clip");
1105        video_err = M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE;
1106    }
1107
1108    /********* Audio *********/
1109    if( M4VIDEOEDITING_kNoneAudio != pClipProperties->
1110        AudioStreamType ) /**< if there is an audio stream */
1111    {
1112        /**
1113        * Check audio format is AMR-NB, EVRC or AAC */
1114        switch( pClipProperties->AudioStreamType )
1115        {
1116            case M4VIDEOEDITING_kAMR_NB:
1117                pClipProperties->bAudioIsEditable = M4OSA_TRUE;
1118                uiNbOfValidStreams++;
1119                break;
1120
1121            case M4VIDEOEDITING_kAAC:
1122            case M4VIDEOEDITING_kAACplus:
1123            case M4VIDEOEDITING_keAACplus:
1124                switch( pClipProperties->uiSamplingFrequency )
1125                {
1126                case 8000:
1127                case 16000:
1128                case 22050:
1129                case 24000:
1130                case 32000:
1131                case 44100:
1132                case 48000:
1133                    pClipProperties->bAudioIsEditable = M4OSA_TRUE;
1134                    break;
1135
1136                default:
1137                    break;
1138                }
1139                uiNbOfValidStreams++;
1140                break;
1141
1142            case M4VIDEOEDITING_kEVRC:
1143                /*< OK, we proceed, no return */
1144                uiNbOfValidStreams++;
1145                break;
1146
1147            default: /*< KO, we return error */
1148                M4OSA_TRACE1_0(
1149                    "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported audio format");
1150                audio_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT;
1151                break;
1152        }
1153    }
1154    else
1155    {
1156        /* Silence is always editable */
1157        pClipProperties->bAudioIsEditable = M4OSA_TRUE;
1158    }
1159
1160    /**
1161    * Check there is at least one valid stream in the file... */
1162    if( video_err != M4NO_ERROR )
1163        return video_err;
1164
1165    if( audio_err != M4NO_ERROR )
1166        return audio_err;
1167
1168    if( 0 == uiNbOfValidStreams )
1169    {
1170        M4OSA_TRACE1_0(
1171            "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): File contains no supported stream,\
1172            returning M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE");
1173        return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE;
1174    }
1175
1176    /**
1177    * Return with no error */
1178    M4OSA_TRACE3_0(
1179        "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR");
1180    return M4NO_ERROR;
1181}
1182
1183/**
1184 ******************************************************************************
1185 * M4OSA_ERR M4VSS3GPP_intAudioMixingCompatibility()
1186 * @brief    This function allows checking if two clips are compatible with each other for
1187 *        VSS 3GPP audio mixing feature.
1188 * @note
1189 * @param    pC                            (IN) Context of the audio mixer
1190 * @param    pInputClipProperties        (IN) Clip analysis of the first clip
1191 * @param    pAddedClipProperties        (IN) Clip analysis of the second clip
1192 * @return    M4NO_ERROR:            No error
1193 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
1194 * @return    M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION
1195 * @return  M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP
1196 * @return  M4NO_ERROR
1197 ******************************************************************************
1198 */
1199M4OSA_ERR
1200M4VSS3GPP_intAudioMixingCompatibility( M4VSS3GPP_InternalAudioMixingContext
1201                                      *pC, M4VIDEOEDITING_ClipProperties *pInputClipProperties,
1202                                      M4VIDEOEDITING_ClipProperties *pAddedClipProperties )
1203{
1204    M4OSA_Bool bClip1IsAAC = M4OSA_FALSE;
1205    M4OSA_Bool bClip2IsAAC = M4OSA_FALSE;
1206
1207    /**
1208    * Reset settings */
1209    pInputClipProperties->bAudioIsEditable = M4OSA_FALSE;
1210    pAddedClipProperties->bAudioIsEditable = M4OSA_FALSE;
1211    pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
1212    pAddedClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
1213
1214    /**
1215    * Check that analysis has been generated by this version of the VSS3GPP library */
1216    if( ( pInputClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR)
1217        || (pInputClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR)
1218        || (pInputClipProperties->Version[2]
1219    != M4VIDEOEDITING_VERSION_REVISION) )
1220    {
1221        M4OSA_TRACE1_0(
1222            "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\
1223            by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION");
1224        return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION;
1225    }
1226
1227    if( ( pAddedClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR)
1228        || (pAddedClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR)
1229        || (pAddedClipProperties->Version[2]
1230    != M4VIDEOEDITING_VERSION_REVISION) )
1231    {
1232        M4OSA_TRACE1_0(
1233            "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\
1234            by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION");
1235        return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION;
1236    }
1237
1238    /********* input file type *********/
1239
1240    if( M4VIDEOEDITING_kFileType_3GPP != pInputClipProperties->FileType )
1241    {
1242        M4OSA_TRACE1_0(
1243            "M4VSS3GPP_intAudioMixingCompatibility:\
1244            returning M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP");
1245        return M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP;
1246    }
1247
1248    /********* input audio *********/
1249
1250    if( M4VIDEOEDITING_kNoneAudio != pInputClipProperties->
1251        AudioStreamType ) /**< if there is an audio stream */
1252    {
1253        /**
1254        * Check audio format is AMR-NB or AAC */
1255        switch( pInputClipProperties->AudioStreamType )
1256        {
1257            case M4VIDEOEDITING_kAMR_NB:
1258                pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
1259                break;
1260
1261            case M4VIDEOEDITING_kAAC:
1262            case M4VIDEOEDITING_kAACplus:
1263            case M4VIDEOEDITING_keAACplus:
1264                switch( pInputClipProperties->uiSamplingFrequency )
1265                {
1266                case 8000:
1267                case 16000:
1268                case 22050:
1269                case 24000:
1270                case 32000:
1271                case 44100:
1272                case 48000:
1273                    pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
1274                    break;
1275
1276                default:
1277                    break;
1278            }
1279            bClip1IsAAC = M4OSA_TRUE;
1280            break;
1281          default:
1282            break;
1283        }
1284    }
1285    else
1286    {
1287        /* Silence is always editable */
1288        pInputClipProperties->bAudioIsEditable = M4OSA_TRUE;
1289    }
1290
1291    /********* added audio *********/
1292
1293    if( M4VIDEOEDITING_kNoneAudio != pAddedClipProperties->
1294        AudioStreamType ) /**< if there is an audio stream */
1295    {
1296        /**
1297        * Check audio format is AMR-NB or AAC */
1298        switch( pAddedClipProperties->AudioStreamType )
1299        {
1300            case M4VIDEOEDITING_kAMR_NB:
1301                pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
1302                pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
1303                    M4OSA_TRUE; /* I use this field to know if silence supported */
1304                break;
1305
1306            case M4VIDEOEDITING_kAAC:
1307            case M4VIDEOEDITING_kAACplus:
1308            case M4VIDEOEDITING_keAACplus:
1309                switch( pAddedClipProperties->uiSamplingFrequency )
1310                {
1311                case 8000:
1312                case 16000:
1313                case 22050:
1314                case 24000:
1315                case 32000:
1316                case 44100:
1317                case 48000:
1318                    pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
1319                    break;
1320
1321                default:
1322                    break;
1323                }
1324                pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
1325                    M4OSA_TRUE; /* I use this field to know if silence supported */
1326                bClip2IsAAC = M4OSA_TRUE;
1327                break;
1328
1329            case M4VIDEOEDITING_kEVRC:
1330                break;
1331
1332            case M4VIDEOEDITING_kPCM:
1333                pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
1334                pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
1335                    M4OSA_TRUE; /* I use this field to know if silence supported */
1336
1337                if( pAddedClipProperties->uiSamplingFrequency == 16000 )
1338                {
1339                    bClip2IsAAC = M4OSA_TRUE;
1340                }
1341                break;
1342
1343            case M4VIDEOEDITING_kMP3: /*RC*/
1344                pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
1345                pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
1346                    M4OSA_TRUE; /* I use this field to know if silence supported */
1347                break;
1348
1349            default:
1350                /* The writer cannot write this  into a 3gpp */
1351                M4OSA_TRACE1_0(
1352                    "M4VSS3GPP_intAudioMixingCompatibility:\
1353                    returning M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM");
1354                return M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM;
1355        }
1356    }
1357    else
1358    {
1359        /* Silence is always editable */
1360        pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE;
1361        pAddedClipProperties->bAudioIsCompatibleWithMasterClip =
1362            M4OSA_TRUE; /* I use this field to know if silence supported */
1363    }
1364
1365    if( pC->bRemoveOriginal == M4OSA_FALSE )
1366    {
1367        if( pInputClipProperties->uiSamplingFrequency
1368            != pAddedClipProperties->uiSamplingFrequency )
1369        {
1370            /* We need to call SSRC in order to align ASF and/or nb of channels */
1371            /* Moreover, audio encoder may be needed in case of audio replacing... */
1372            pC->b_SSRCneeded = M4OSA_TRUE;
1373        }
1374
1375        if( pInputClipProperties->uiNbChannels
1376            < pAddedClipProperties->uiNbChannels )
1377        {
1378            /* Stereo to Mono */
1379            pC->ChannelConversion = 1;
1380        }
1381        else if( pInputClipProperties->uiNbChannels
1382            > pAddedClipProperties->uiNbChannels )
1383        {
1384            /* Mono to Stereo */
1385            pC->ChannelConversion = 2;
1386        }
1387    }
1388
1389    pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE;
1390
1391    /**
1392    * Return with no error */
1393    M4OSA_TRACE3_0(
1394        "M4VSS3GPP_intAudioMixingCompatibility(): returning M4NO_ERROR");
1395    return M4NO_ERROR;
1396}
1397