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