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