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  ******************************************************************************
     19  * @file    M4MP4W_Interface.c
     20  * @brief    3GPP file writer interface
     21  * @note    This implementation follows the common interface defined
     22  *          in "M4WRITER_common.h".
     23  ******************************************************************************
     24 */
     25 
     26 #include "NXPSW_CompilerSwitches.h"
     27 
     28 /**
     29  * OSAL includes */
     30 #include "M4OSA_Types.h"            /**< OSAL basic types definiton */
     31 #include "M4OSA_FileWriter.h"        /**< Include for OSAL file accesses implementation */
     32 #include "M4OSA_Memory.h"            /**< Include for OSAL memory accesses implementation */
     33 #include "M4OSA_Debug.h"            /**< OSAL debug tools */
     34 
     35 /**
     36  * Writer includes */
     37 #include "M4WRITER_common.h"        /**< Definition of the writer common interface that
     38                                           this module follows */
     39 
     40 #ifdef _M4MP4W_USE_CST_MEMORY_WRITER
     41 #include "M4MP4W_Types_CstMem.h"    /**< MP4/3GP core writer types */
     42 #include "M4MP4W_Writer_CstMem.h"    /**< MP4/3GP core writer functions */
     43 #else
     44 #include "M4MP4W_Types.h"            /**< MP4/3GP core writer types */
     45 #include "M4MP4W_Writer.h"            /**< MP4/3GP core writer functions */
     46 #endif /* _M4MP4W_USE_CST_MEMORY_WRITER */
     47 
     48 /**
     49  * Specific errors for this module */
     50 #define M4WRITER_3GP_ERR_UNSUPPORTED_STREAM_TYPE \
     51                 M4OSA_ERR_CREATE(M4_ERR, M4WRITER_3GP, 0x000001)
     52 
     53 
     54 /**
     55  ******************************************************************************
     56  * structure    M4WRITER_3GP_InternalContext
     57  * @brief        This structure defines the writer context (private)
     58  * @note        This structure is used for all writer calls to store the context
     59  ******************************************************************************
     60 */
     61 typedef struct
     62 {
     63     M4OSA_Context    pMP4Context;    /**< MP4 writer context */
     64     M4OSA_UInt32    maxAUsizes;        /**< the maximum AU size possible */
     65 } M4WRITER_3GP_InternalContext;
     66 
     67 
     68 /******************************************************************************
     69  * M4OSA_ERR M4WRITER_3GP_openWrite(M4WRITER_Context* pContext, void* pWhat,
     70  *                                   M4OSA_FileWriterPointer* pFileWriterPointer)
     71  * @brief    Open a writer session.
     72  * @note
     73  * @param    pContext:     (OUT) Execution context of the 3GP writer, allocated by this function.
     74  * @param    outputFileDescriptor (IN)  Descriptor of the output file to create.
     75  * @param    fileWriterFunction     (IN)  Pointer to structure containing the set of OSAL
     76  *                                       file write functions.
     77  * @param    tempFileDescriptor     (IN)  Descriptor of the temporary file to open
     78  *                                        (NULL if not used)
     79  * @param    fileReaderFunction     (IN)  Pointer to structure containing the set of OSAL file read
     80  *                                      functions (NULL if not used)
     81  * @return    M4NO_ERROR:  there is no error
     82  * @return    M4ERR_ALLOC: there is no more available memory
     83  * @return    M4ERR_PARAMETER: pContext or pFilePtrFct is M4OSA_NULL (debug only)
     84  * @return    any error returned by the MP4 core writer openWrite (Its coreID is M4MP4_WRITER)
     85  ******************************************************************************
     86 */
     87 M4OSA_ERR M4WRITER_3GP_openWrite( M4WRITER_Context* pContext,
     88                                   void* outputFileDescriptor,
     89                                   M4OSA_FileWriterPointer* pFileWriterPointer,
     90                                   void* tempFileDescriptor,
     91                                   M4OSA_FileReadPointer* pFileReaderPointer )
     92 {
     93     M4WRITER_3GP_InternalContext* apContext;
     94     M4OSA_ERR err;
     95 
     96     M4OSA_TRACE1_0("M4WRITER_3GP_openWrite");
     97 
     98     /**
     99      *    Check input parameters */
    100     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext),M4ERR_PARAMETER,
    101          "M4WRITER_3GP_openWrite: pContext is M4OSA_NULL");
    102     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWriterPointer),M4ERR_PARAMETER,
    103          "M4WRITER_3GP_openWrite: pFileWriterPointer is M4OSA_NULL");
    104 
    105     /**
    106      *    Allocate memory for the context */
    107     *pContext=M4OSA_NULL;
    108     apContext = (M4WRITER_3GP_InternalContext*)M4OSA_32bitAlignedMalloc(
    109                     sizeof(M4WRITER_3GP_InternalContext),
    110                     M4WRITER_3GP,
    111                     (M4OSA_Char *)"M4WRITER_3GP_InternalContext");
    112 
    113     if (M4OSA_NULL == apContext)
    114     {
    115         M4OSA_TRACE1_0("M4WRITER_3GP_openWrite:\
    116              unable to allocate context, returning M4ERR_ALLOC");
    117         return (M4OSA_ERR)M4ERR_ALLOC;
    118     }
    119 
    120     /**
    121      *    Reset context variables */
    122     apContext->pMP4Context = M4OSA_NULL;
    123     apContext->maxAUsizes = 0;
    124 
    125     /**
    126      *    Return the writer context */
    127     *pContext = (M4WRITER_Context *)apContext;
    128 
    129     /**
    130      *    Launch the openWrite of the MP4 writer */
    131     M4OSA_TRACE3_0("M4WRITER_3GP_openWrite: calling M4MP4W_openWrite()");
    132 
    133     err = M4MP4W_openWrite(&apContext->pMP4Context, outputFileDescriptor,
    134             pFileWriterPointer, tempFileDescriptor, pFileReaderPointer );
    135 
    136     if (M4OSA_ERR_IS_ERROR(err))
    137     {
    138         M4OSA_TRACE1_1("M4WRITER_3GP_openWrite: "
    139                        "M4MP4W_openWrite returns error 0x%x", err);
    140     }
    141 
    142     M4OSA_TRACE2_1("M4WRITER_3GP_openWrite: returning 0x%x", err);
    143 
    144     return err;
    145 }
    146 
    147 
    148 /******************************************************************************
    149  * M4OSA_ERR M4WRITER_3GP_startWriting(M4WRITER_Context pContext)
    150  * @brief    Indicates to the writer that the setup session is ended and that
    151  *          we will start to write.
    152  * @note
    153  * @param     pContext:   (IN) Execution context of the 3GP writer,
    154  * @return    M4NO_ERROR: there is no error
    155  * @return    M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only)
    156  * @return    any error returned by the MP4 core writer startWriting (Its
    157  *            coreID is M4MP4_WRITER)
    158  ******************************************************************************
    159 */
    160 M4OSA_ERR M4WRITER_3GP_startWriting(M4WRITER_Context pContext)
    161 {
    162     M4WRITER_3GP_InternalContext* apContext =
    163                 (M4WRITER_3GP_InternalContext*)pContext;
    164 
    165     M4OSA_ERR err;
    166 
    167     M4OSA_TRACE1_1("M4WRITER_3GP_startWriting: pContext=0x%x", pContext);
    168 
    169     /**
    170      *    Check input parameter */
    171     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext),M4ERR_PARAMETER,
    172          "M4WRITER_3GP_startWriting: pContext is M4OSA_NULL");
    173 
    174     /**
    175      *    Call the MP4 core writer */
    176     M4OSA_TRACE3_0("M4WRITER_3GP_startWriting: calling M4MP4W_startWriting()");
    177     err = M4MP4W_startWriting(apContext->pMP4Context);
    178     if (M4OSA_ERR_IS_ERROR(err))
    179     {
    180         M4OSA_TRACE1_1("M4MP4W_startWriting returns error 0x%x", err);
    181     }
    182 
    183     M4OSA_TRACE2_1("M4WRITER_3GP_startWriting: returning 0x%x", err);
    184     return err;
    185 }
    186 
    187 
    188 /******************************************************************************
    189  * M4OSA_ERR M4WRITER_3GP_addStream(
    190  *     M4WRITER_Context pContext,
    191  *     M4SYS_StreamDescription *pStreamDescription)
    192  * @brief     Add a stream (audio or video).
    193  * @note      Decoder specific info properties are correctly set before calling
    194  *            the core writer add function
    195  * @param     pContext:   (IN) Execution context of the 3GP writer,
    196  * @param     streamDescription:    (IN) stream description.
    197  * @return    M4NO_ERROR: there is no error
    198  * @return    M4ERR_PARAMETER: pContext or pStreamDescription is M4OSA_NULL
    199  *            (debug only)
    200  * @return    any error returned by the MP4 core writer addStream
    201  *            (Its coreID is M4MP4_WRITER)
    202  ******************************************************************************
    203 */
    204 M4OSA_ERR M4WRITER_3GP_addStream(M4WRITER_Context pContext,
    205                                  M4SYS_StreamDescription* pStreamDescription)
    206 {
    207     M4WRITER_3GP_InternalContext *apContext =
    208         (M4WRITER_3GP_InternalContext *)pContext;
    209 
    210     M4OSA_ERR err;
    211     M4WRITER_StreamVideoInfos *pVideoInfo = M4OSA_NULL;
    212     M4WRITER_StreamAudioInfos *pAudioInfo = M4OSA_NULL;
    213     M4MP4W_StreamIDsize sizeValue;
    214 
    215     M4OSA_TRACE1_2("M4WRITER_3GP_addStream: pContext=0x%x, "
    216                    "pStreamDescription=0x%x",
    217                    pContext, pStreamDescription);
    218 
    219     /**
    220      *    Check input parameters */
    221     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext),M4ERR_PARAMETER,
    222          "M4WRITER_3GP_addStream: pContext is M4OSA_NULL");
    223     M4OSA_DEBUG_IF2((M4OSA_NULL == pStreamDescription),M4ERR_PARAMETER,
    224          "M4WRITER_3GP_addStream: pStreamDescription is M4OSA_NULL");
    225 
    226     /**
    227      *    Adapt audio/video stream infos */
    228     switch (pStreamDescription->streamType)
    229     {
    230         case M4SYS_kMPEG_4:
    231         case M4SYS_kH264:
    232         case M4SYS_kH263:
    233             M4OSA_TRACE3_1("M4WRITER_3GP_addStream: "
    234                     "adding a Video stream (streamType=0x%x)",
    235                     pStreamDescription->streamType);
    236             /**
    237              *    Common descriptions */
    238             pStreamDescription->streamID = VideoStreamID;    /**< The only values checked by our
    239                                                                   core writer are streamID */
    240             pStreamDescription->timeScale = 1000;            /**< and timeScale */
    241 
    242 /* Not recommended for video editing -> write explicitely the 'bitr' box into 'd263' */
    243 /* Rem : it is REL 5 of 3gpp documentation */
    244 //            /**
    245 //             * Average bit-rate must not be set in H263 to be compatible with Platform4 */
    246 //            if (M4SYS_kH263 == pStreamDescription->streamType)
    247 //            {
    248 //                pStreamDescription->averageBitrate = -1;
    249 //            }
    250 
    251             /**
    252              *    Decoder specific info */
    253             pVideoInfo = (M4WRITER_StreamVideoInfos *)pStreamDescription->decoderSpecificInfo;
    254             pStreamDescription->decoderSpecificInfoSize = pVideoInfo->Header.Size;
    255             pStreamDescription->decoderSpecificInfo = (M4OSA_MemAddr32)pVideoInfo->Header.pBuf;
    256             M4OSA_TRACE3_2("M4WRITER_3GP_addStream: Video: DSI=0x%x, DSIsize=%d",
    257                  pVideoInfo->Header.pBuf, pVideoInfo->Header.Size);
    258             break;
    259 
    260         case M4SYS_kAMR:
    261         case M4SYS_kAMR_WB:
    262         case M4SYS_kAAC:
    263         case M4SYS_kEVRC:
    264             M4OSA_TRACE3_1("M4WRITER_3GP_addStream: adding an Audio stream (streamType=0x%x)",
    265                  pStreamDescription->streamType);
    266             /**
    267              *    Common descriptions */
    268             pStreamDescription->streamID = AudioStreamID;    /**< The only value checked by our
    269                                                                  core writer is streamID */
    270 
    271             /**
    272              *    Decoder specific info */
    273             pAudioInfo = (M4WRITER_StreamAudioInfos *)pStreamDescription->decoderSpecificInfo;
    274             pStreamDescription->decoderSpecificInfoSize = pAudioInfo->Header.Size;
    275             pStreamDescription->decoderSpecificInfo = (M4OSA_MemAddr32)pAudioInfo->Header.pBuf;
    276             M4OSA_TRACE3_2("M4WRITER_3GP_addStream: Audio: DSI=0x%x, DSIsize=%d",
    277                  pAudioInfo->Header.pBuf, pAudioInfo->Header.Size);
    278             break;
    279 
    280         default:
    281             M4OSA_TRACE1_1("M4WRITER_3GP_addStream:\
    282                  returning M4WRITER_3GP_ERR_UNSUPPORTED_STREAM_TYPE (streamType=0x%x)",
    283                      pStreamDescription->streamType);
    284             return (M4OSA_ERR)M4WRITER_3GP_ERR_UNSUPPORTED_STREAM_TYPE;
    285             break;
    286     }
    287 
    288     /**
    289      *    Call the MP4 core writer */
    290     M4OSA_TRACE3_0("M4WRITER_3GP_addStream: calling M4MP4W_addStream()");
    291     err = M4MP4W_addStream(apContext->pMP4Context,pStreamDescription);
    292     if (M4OSA_ERR_IS_ERROR(err))
    293     {
    294         M4OSA_TRACE1_1("M4WRITER_3GP_addStream: M4MP4W_addStream returns error 0x%x", err);
    295         M4OSA_TRACE1_1("M4WRITER_3GP_addStream: returning 0x%x", err);
    296         return (err);
    297     }
    298 
    299     /**
    300      *    For Video, set the M4MP4W_trackSize Option */
    301     switch (pStreamDescription->streamType)
    302     {
    303         case M4SYS_kMPEG_4:
    304         case M4SYS_kH264:
    305         case M4SYS_kH263:
    306             sizeValue.streamID = VideoStreamID;
    307             sizeValue.height = (M4OSA_UInt16)(pVideoInfo->height);
    308             sizeValue.width  = (M4OSA_UInt16)(pVideoInfo->width);
    309             M4OSA_TRACE3_2("M4WRITER_3GP_addStream: Video: height=%d, width=%d",
    310                  sizeValue.height, sizeValue.width);
    311 
    312             M4OSA_TRACE3_0("M4WRITER_3GP_addStream: calling M4MP4W_setOption(M4MP4W_trackSize)");
    313             err = M4MP4W_setOption( apContext->pMP4Context, M4MP4W_trackSize,
    314                  (M4OSA_DataOption)&sizeValue);
    315             if (M4OSA_ERR_IS_ERROR(err))
    316             {
    317                 M4OSA_TRACE1_1("M4WRITER_3GP_addStream: M4MP4W_setOption returns error 0x%x",
    318                      err);
    319             }
    320             break;
    321         default:
    322             break;
    323     }
    324 
    325     M4OSA_TRACE2_1("M4WRITER_3GP_addStream: returning 0x%x", err);
    326     return err;
    327 }
    328 
    329 
    330 /******************************************************************************
    331  * M4OSA_ERR M4WRITER_3GP_closeWrite(M4WRITER_Context pContext)
    332  * @brief    Close the writer. The context is freed here.
    333  * @note
    334  * @param     pContext:   (IN) Execution context of the 3GP writer,
    335  * @return    M4NO_ERROR: there is no error
    336  * @return    M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only)
    337  * @return    any error returned by the MP4 core writer closeWrite (Its coreID
    338  *            is M4MP4_WRITER)
    339  ******************************************************************************
    340 */
    341 M4OSA_ERR M4WRITER_3GP_closeWrite(M4WRITER_Context pContext)
    342 {
    343     M4WRITER_3GP_InternalContext* apContext=(M4WRITER_3GP_InternalContext*)pContext;
    344     M4OSA_ERR err = M4NO_ERROR;
    345 
    346     M4OSA_TRACE1_1("M4WRITER_3GP_closeWrite called with pContext=0x%x", pContext);
    347 
    348     /**
    349     *    Check input parameter */
    350     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext),M4ERR_PARAMETER,
    351          "M4WRITER_3GP_closeWrite: pContext is M4OSA_NULL");
    352 
    353     /**
    354      *    Call the MP4 core writer */
    355     if (M4OSA_NULL != apContext->pMP4Context)
    356     {
    357         M4OSA_TRACE3_0("M4WRITER_3GP_closeWrite: calling M4MP4W_closeWrite()");
    358         err = M4MP4W_closeWrite(apContext->pMP4Context);
    359         if (M4OSA_ERR_IS_ERROR(err))
    360         {
    361             M4OSA_TRACE1_1("M4WRITER_3GP_closeWrite: M4MP4W_closeWrite returns error 0x%x", err);
    362         }
    363     }
    364 
    365     /**
    366      *    Deallocate our own context */
    367     free(apContext);
    368 
    369     M4OSA_TRACE2_1("M4WRITER_3GP_closeWrite: returning 0x%x", err);
    370     return err;
    371 }
    372 
    373 
    374 /******************************************************************************
    375  * M4OSA_ERR M4WRITER_3GP_setOption(
    376  *        M4WRITER_Context pContext, M4OSA_UInt32 optionID,
    377  *        M4OSA_DataOption optionValue)
    378  * @brief     This function asks the writer to set the value associated with
    379  *            the optionID. The caller is responsible for allocating/
    380  *            de-allocating the memory of the value field.
    381  * @note      The options handled by the component depend on the implementation
    382  *            of the component.
    383  * @param     pContext:     (IN) Execution context of the 3GP writer,
    384  * @param     pptionId:     (IN) ID of the option to set.
    385  * @param     OptionValue : (IN) Value of the option to set.
    386  * @return    M4NO_ERROR: there is no error
    387  * @return    M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only)
    388  * @return    M4ERR_BAD_OPTION_ID: the ID of the option is not valid.
    389  * @return    any error returned by the MP4 core writer setOption (Its coreID
    390  *            is M4MP4_WRITER)
    391  ******************************************************************************
    392 */
    393 M4OSA_ERR M4WRITER_3GP_setOption(
    394         M4WRITER_Context pContext, M4OSA_UInt32 optionID,
    395         M4OSA_DataOption optionValue)
    396 {
    397     M4WRITER_3GP_InternalContext* apContext =
    398             (M4WRITER_3GP_InternalContext*)pContext;
    399 
    400     M4OSA_ERR err = M4NO_ERROR;
    401     M4MP4W_memAddr memval;
    402     M4SYS_StreamIDValue optval;
    403 
    404     M4OSA_TRACE2_3("M4WRITER_3GP_setOption: pContext=0x%x, optionID=0x%x,\
    405          optionValue=0x%x", pContext, optionID, optionValue);
    406 
    407     /**
    408      *    Check input parameter */
    409     M4OSA_DEBUG_IF2((M4OSA_NULL==apContext),M4ERR_PARAMETER,
    410          "M4WRITER_3GP_setOption: pContext is M4OSA_NULL");
    411 
    412     switch (optionID)
    413     {
    414         /**
    415          *    Maximum Access Unit size */
    416         case M4WRITER_kMaxAUSize:
    417             M4OSA_TRACE2_0("setting M4WRITER_kMaxAUSize option");
    418             err = M4MP4W_setOption(
    419                     apContext->pMP4Context,M4MP4W_maxAUsize, optionValue);
    420             if (M4OSA_ERR_IS_ERROR(err))
    421             {
    422                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_maxAUsize) "
    423                                "returns error 0x%x", err);
    424             }
    425             break;
    426         /**
    427          *    Maximum chunck size */
    428         case M4WRITER_kMaxChunckSize:
    429             M4OSA_TRACE2_0("setting M4WRITER_kMaxChunckSize option");
    430             err = M4MP4W_setOption(
    431                 apContext->pMP4Context,M4MP4W_maxChunkSize, optionValue);
    432             if (M4OSA_ERR_IS_ERROR(err))
    433             {
    434                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_maxChunkSize)\
    435                      returns error 0x%x", err);
    436             }
    437             break;
    438         /**
    439          *    File string signature */
    440         case M4WRITER_kEmbeddedString:
    441             M4OSA_TRACE2_0("setting M4WRITER_kEmbeddedString option");
    442             /* The given M4OSA_DataOption must actually
    443                be a text string */
    444             memval.addr = (M4OSA_MemAddr32)optionValue;
    445             /**< this is max string size copied by the core */
    446             memval.size = 16;
    447             err = M4MP4W_setOption(
    448                 apContext->pMP4Context,M4MP4W_embeddedString, &memval);
    449             if (M4OSA_ERR_IS_ERROR(err))
    450             {
    451                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_embeddedString)\
    452                      returns error 0x%x", err);
    453             }
    454             break;
    455         /**
    456          *    File integration tag */
    457         case M4WRITER_kIntegrationTag:
    458             M4OSA_TRACE2_0("setting M4WRITER_kIntegrationTag option");
    459             /* The given M4OSA_DataOption must actually
    460                be a text string */
    461             memval.addr = (M4OSA_MemAddr32)optionValue;
    462             /**< this is max string size copied by the core */
    463             memval.size = strlen((const char *)optionValue);
    464             err = M4MP4W_setOption(
    465                 apContext->pMP4Context,M4MP4W_integrationTag, &memval);
    466             if (M4OSA_ERR_IS_ERROR(err))
    467             {
    468                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_integrationTag)"
    469                                " returns error 0x%x", err);
    470             }
    471             break;
    472         /**
    473          *    File version signature */
    474         case M4WRITER_kEmbeddedVersion:
    475             M4OSA_TRACE2_0("setting M4WRITER_kEmbeddedVersion option");
    476             /* The given M4OSA_DataOption must actually
    477                be a version number */
    478 
    479             /**< Here 0 means both streams */
    480             optval.streamID = 0;
    481             /**< version number */
    482             optval.value = *(M4OSA_UInt32*)optionValue;
    483             err = M4MP4W_setOption(
    484                 apContext->pMP4Context,M4MP4W_CamcoderVersion, &optval);
    485             if (M4OSA_ERR_IS_ERROR(err))
    486             {
    487                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_CamcoderVersion)"
    488                                " returns error 0x%x", err);
    489             }
    490             break;
    491         /**
    492          *    Some options are read-only */
    493         case M4WRITER_kFileSize:
    494         case M4WRITER_kFileSizeAudioEstimated:
    495             M4OSA_TRACE2_1("trying to set a read-only option! (ID=0x%x)",
    496                     optionID);
    497             return (M4OSA_ERR)M4ERR_READ_ONLY;
    498             break;
    499         /**
    500          *    Maximum filesize limitation */
    501         case M4WRITER_kMaxFileSize:
    502             M4OSA_TRACE2_0("setting M4WRITER_kMaxFileSize option");
    503             err = M4MP4W_setOption(
    504                 apContext->pMP4Context,M4MP4W_maxFileSize, optionValue);
    505             if (M4OSA_ERR_IS_ERROR(err))
    506             {
    507                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_maxFileSize)\
    508                      returns error 0x%x", err);
    509             }
    510             break;
    511 
    512         /**
    513          *    Maximum file duration limitation */
    514         case M4WRITER_kMaxFileDuration:
    515             M4OSA_TRACE2_0("setting M4WRITER_kMaxFileDuration option");
    516             err = M4MP4W_setOption(
    517                 apContext->pMP4Context,M4MP4W_maxFileDuration, optionValue);
    518             if (M4OSA_ERR_IS_ERROR(err))
    519             {
    520                 M4OSA_TRACE1_1("M4MP4W_setOption(M4WRITER_kMaxFileDuration)"
    521                                " returns error 0x%x", err);
    522             }
    523             break;
    524 
    525         /**
    526          *    Set 'ftyp' atom */
    527         case M4WRITER_kSetFtypBox:
    528             M4OSA_TRACE2_0("setting M4WRITER_kSetFtypBox option");
    529             err = M4MP4W_setOption(
    530                 apContext->pMP4Context, M4MP4W_setFtypBox, optionValue);
    531             if (M4OSA_ERR_IS_ERROR(err))
    532             {
    533                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_setFtypBox)\
    534                      returns error 0x%x", err);
    535             }
    536             break;
    537 
    538         /**
    539          *    Decoder Specific Info */
    540         case M4WRITER_kDSI:
    541             M4OSA_TRACE2_0("setting M4WRITER_kDSI option");
    542             err = M4MP4W_setOption(
    543                 apContext->pMP4Context, M4MP4W_DSI, optionValue);
    544             if (M4OSA_ERR_IS_ERROR(err))
    545             {
    546                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_DSI)\
    547                      returns error 0x%x", err);
    548             }
    549             break;
    550         /*+ H.264 Trimming  */
    551         case M4WRITER_kMUL_PPS_SPS:
    552             M4OSA_TRACE2_0("setting M4WRITER_kMUL_PPS_SPS option");
    553             err = M4MP4W_setOption(
    554                 apContext->pMP4Context, M4MP4W_MUL_PPS_SPS, optionValue);
    555             if (M4OSA_ERR_IS_ERROR(err))
    556             {
    557                 M4OSA_TRACE1_1("M4MP4W_setOption(M4MP4W_DSI)\
    558                      returns error 0x%x", err);
    559             }
    560             break;
    561         /*- H.264 Trimming  */
    562 
    563         /**
    564          *    Unknown option */
    565         default:
    566             M4OSA_TRACE2_1("trying to set an unknown option!\
    567                  (optionID=0x%x)", optionID);
    568             return (M4OSA_ERR)M4ERR_BAD_OPTION_ID;
    569             break;
    570     }
    571 
    572     M4OSA_TRACE3_1("M4WRITER_3GP_setOption: returning 0x%x", err);
    573     return err;
    574 }
    575 
    576 
    577 /******************************************************************************
    578  * M4OSA_ERR M4WRITER_3GP_getOption(
    579  *     M4WRITER_Context pContext, M4OSA_UInt32 optionID,
    580  *     M4OSA_DataOption optionValue)
    581  * @brief     This function asks the writer to return the value associated with
    582  *            the optionID. The caller is responsible for allocating/
    583  *            de-allocating the memory of the value field.
    584  * @note      The options handled by the component depend on the implementation
    585  *            of the component.
    586  * @param     pContext:     (IN) Execution context of the 3GP writer,
    587  * @param     OptionId:      (IN) Id of the option to get.
    588  * @param     pOptionValue: (OUT) Value of the option to get.
    589  * @return    M4NO_ERROR: there is no error
    590  * @return    M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only)
    591  * @return    M4ERR_BAD_OPTION_ID: the ID of the option is not valid.
    592  * @return    M4ERR_NOT_IMPLEMENTED: This option is not implemented yet.
    593  * @return    any error returned by the MP4 core writer getOption (Its coreID
    594  *            is M4MP4_WRITER)
    595  ******************************************************************************
    596 */
    597 M4OSA_ERR M4WRITER_3GP_getOption(
    598         M4WRITER_Context pContext, M4OSA_UInt32 optionID,
    599         M4OSA_DataOption optionValue)
    600 {
    601     M4WRITER_3GP_InternalContext* apContext =
    602             (M4WRITER_3GP_InternalContext*)pContext;
    603 
    604     M4OSA_ERR err;
    605 
    606     M4OSA_TRACE2_3("M4WRITER_3GP_getOption: pContext=0x%x, optionID=0x%x,\
    607          optionValue=0x%x", pContext, optionID, optionValue);
    608 
    609     /**
    610     *    Check input parameter */
    611     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext),M4ERR_PARAMETER,
    612          "M4WRITER_3GP_getOption: pContext is M4OSA_NULL");
    613 
    614     switch (optionID)
    615     {
    616         /**
    617          *    Maximum Access Unit size */
    618         case M4WRITER_kMaxAUSize:
    619             M4OSA_TRACE2_0("getting M4WRITER_kMaxAUSize option");
    620             err = M4MP4W_getOption(apContext->pMP4Context,M4MP4W_maxAUsize,
    621                 (M4OSA_DataOption*)&optionValue);
    622             if (M4OSA_ERR_IS_ERROR(err))
    623             {
    624                 M4OSA_TRACE1_1("M4MP4W_getOption(M4MP4W_maxAUsize)"
    625                                " returns error 0x%x", err);
    626             }
    627             break;
    628         /**
    629          *    Maximum chunck size */
    630         case M4WRITER_kMaxChunckSize:
    631             M4OSA_TRACE2_0("getting M4WRITER_kMaxChunckSize option");
    632             err = M4MP4W_getOption(apContext->pMP4Context,M4MP4W_maxChunkSize,
    633                 (M4OSA_DataOption*)&optionValue);
    634             if (M4OSA_ERR_IS_ERROR(err))
    635             {
    636                 M4OSA_TRACE1_1("M4MP4W_getOption(M4MP4W_maxChunkSize)\
    637                      returns error 0x%x", err);
    638             }
    639             break;
    640         /**
    641          *    The file size option */
    642         case M4WRITER_kFileSize:
    643             M4OSA_TRACE2_0("getting M4WRITER_kFileSize option");
    644             /* get the current file size */
    645             err = M4MP4W_getCurrentFileSize(
    646                 apContext->pMP4Context, (M4OSA_UInt32*)optionValue);
    647             if (M4OSA_ERR_IS_ERROR(err))
    648             {
    649                 M4OSA_TRACE1_1("M4MP4W_getCurrentFileSize"
    650                                " returns error 0x%x", err);
    651             }
    652             break;
    653         /**
    654          *    The file size with audio option has its own function call
    655               in the MP4 core writer */
    656         case M4WRITER_kFileSizeAudioEstimated:
    657             M4OSA_TRACE2_0("getting M4WRITER_kFileSizeAudioEstimated option");
    658             /* get the current file size ... */
    659             err = M4MP4W_getCurrentFileSize(
    660                 apContext->pMP4Context, (M4OSA_UInt32*)optionValue);
    661             if (M4OSA_ERR_IS_ERROR(err))
    662             {
    663                 M4OSA_TRACE1_1("M4MP4W_getCurrentFileSize"
    664                                " returns error 0x%x", err);
    665             }
    666             //no more needed 3gp writer has its own mecanism
    667             ///* ... add the estimated next max AU size */
    668             //*((M4OSA_UInt32*)optionValue) += apContext->maxAUsizes;
    669             break;
    670         /**
    671          *    Unknown option */
    672         default:
    673             M4OSA_TRACE2_1("trying to get an unknown option!\
    674                  (optionID=0x%x)", optionID);
    675             return    (M4OSA_ERR)M4ERR_BAD_OPTION_ID;
    676             break;
    677     }
    678 
    679     M4OSA_TRACE3_1("M4WRITER_3GP_getOption: returning 0x%x", err);
    680     return err;
    681 }
    682 
    683 
    684 /******************************************************************************
    685  * M4OSA_ERR M4WRITER_3GP_startAU(
    686  *          M4WRITER_Context pContext, M4SYS_StreamID streamID,
    687  *          M4SYS_AccessUnit* pAU)
    688  * @brief     Prepare an Access Unit to be ready to store data
    689  * @note
    690  * @param     pContext: (IN) Execution context of the 3GP writer,
    691  * @param     streamID: (IN) Id of the stream to which the Access Unit
    692  *            is related.
    693  * @param     pAU:      (IN/OUT) Access Unit to be prepared.
    694  * @return    M4NO_ERROR: there is no error
    695  * @return    M4ERR_PARAMETER: pContext or pAU is M4OSA_NULL (debug only)
    696  * @return    M4ERR_BAD_STREAM_ID: streamID is not VideoStreamID nor
    697  *            AudioStreamID (debug only)
    698  * @return    any error returned by the MP4 core writer startAU (Its coreID
    699  *            is M4MP4_WRITER)
    700  ******************************************************************************
    701 */
    702 M4OSA_ERR M4WRITER_3GP_startAU(
    703         M4WRITER_Context pContext, M4SYS_StreamID streamID,
    704         M4SYS_AccessUnit* pAU)
    705 {
    706     M4WRITER_3GP_InternalContext* apContext =
    707             (M4WRITER_3GP_InternalContext*)pContext;
    708 
    709     M4OSA_ERR err;
    710 
    711     M4OSA_TRACE2_3("M4WRITER_3GP_startAU: pContext=0x%x, streamID=%d, pAU=0x%x",
    712          pContext, streamID, pAU);
    713 
    714     /**
    715      *    Check input parameter */
    716     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext), M4ERR_PARAMETER,
    717          "M4WRITER_3GP_startAU: pContext is M4OSA_NULL");
    718     M4OSA_DEBUG_IF2((M4OSA_NULL == pAU), M4ERR_PARAMETER,
    719          "M4WRITER_3GP_startAU: pAU is M4OSA_NULL");
    720     M4OSA_DEBUG_IF2(
    721          ((VideoStreamID != streamID) && (AudioStreamID != streamID)),
    722          M4ERR_BAD_STREAM_ID,
    723          "M4WRITER_3GP_processAU: Wrong streamID");
    724 
    725     /**
    726      * Call the MP4 writer */
    727     M4OSA_TRACE3_0("M4WRITER_3GP_startAU: calling M4MP4W_startAU()");
    728     err = M4MP4W_startAU(apContext->pMP4Context, streamID, pAU);
    729     if (M4OSA_ERR_IS_ERROR(err))
    730     {
    731         M4OSA_TRACE1_1("M4MP4W_startAU returns error 0x%x", err);
    732     }
    733 
    734     M4OSA_TRACE3_2("AU: dataAddress=0x%x, size=%d",
    735          pAU->dataAddress, pAU->size);
    736 
    737     /* Convert oversize to a request toward VES automaton */
    738     if (M4WAR_MP4W_OVERSIZE == err)
    739     {
    740         err = M4WAR_WRITER_STOP_REQ;
    741     }
    742 
    743     M4OSA_TRACE3_1("M4WRITER_3GP_startAU: returning 0x%x", err);
    744     return err;
    745 }
    746 
    747 
    748 /******************************************************************************
    749  * M4OSA_ERR M4WRITER_3GP_processAU(
    750  *          M4WRITER_Context pContext, M4SYS_StreamID streamID,
    751  *          M4SYS_AccessUnit* pAU)
    752  * @brief     Write an Access Unit
    753  * @note
    754  * @param     pContext: (IN) Execution context of the 3GP writer,
    755  * @param     streamID: (IN) Id of the stream to which the Access Unit
    756  *            is related.
    757  * @param     pAU:      (IN/OUT) Access Unit to be written
    758  * @return    M4NO_ERROR: there is no error
    759  * @return    M4ERR_PARAMETER: pContext or pAU is M4OSA_NULL (debug only)
    760  * @return    M4ERR_BAD_STREAM_ID: streamID is not VideoStreamID nor
    761  *            AudioStreamID (debug only)
    762  * @return    any error returned by the MP4 core writer processAU
    763  *            (Its coreID is M4MP4_WRITER)
    764  ******************************************************************************
    765 */
    766 M4OSA_ERR M4WRITER_3GP_processAU(
    767         M4WRITER_Context pContext, M4SYS_StreamID streamID,
    768         M4SYS_AccessUnit* pAU)
    769 {
    770     M4WRITER_3GP_InternalContext* apContext =
    771         (M4WRITER_3GP_InternalContext*)pContext;
    772 
    773     M4OSA_ERR err;
    774 
    775     M4OSA_TRACE2_3("M4WRITER_3GP_processAU: "
    776                    "pContext=0x%x, streamID=%d, pAU=0x%x",
    777                     pContext, streamID, pAU);
    778 
    779     /**
    780      *    Check input parameter */
    781     M4OSA_DEBUG_IF2((M4OSA_NULL == apContext), M4ERR_PARAMETER,
    782          "M4WRITER_3GP_processAU: pContext is M4OSA_NULL");
    783     M4OSA_DEBUG_IF2((M4OSA_NULL == pAU), M4ERR_PARAMETER,
    784          "M4WRITER_3GP_processAU: pAU is M4OSA_NULL");
    785     M4OSA_DEBUG_IF2(
    786          ((VideoStreamID != streamID) && (AudioStreamID != streamID)),
    787          M4ERR_BAD_STREAM_ID,
    788          "M4WRITER_3GP_processAU: Wrong streamID");
    789 
    790     M4OSA_TRACE3_4("M4WRITER_3GP_processAU: AU: "
    791          "dataAddress=0x%x, size=%d, CTS=%d, nbFrag=%d",
    792          pAU->dataAddress, pAU->size, (M4OSA_UInt32)pAU->CTS, pAU->nbFrag);
    793 
    794     if(pAU->size > apContext->maxAUsizes)
    795     {
    796         apContext->maxAUsizes = pAU->size;
    797     }
    798     /**
    799      * Call the MP4 writer */
    800     M4OSA_TRACE3_0("M4WRITER_3GP_processAU: calling M4MP4W_processAU()");
    801     err = M4MP4W_processAU(apContext->pMP4Context, streamID, pAU);
    802     if (M4OSA_ERR_IS_ERROR(err))
    803     {
    804         M4OSA_TRACE1_1("M4MP4W_processAU returns error 0x%x", err);
    805     }
    806 
    807     /* Convert oversize to a request toward VES automaton */
    808     if(M4WAR_MP4W_OVERSIZE == err)
    809     {
    810         err = M4WAR_WRITER_STOP_REQ;
    811     }
    812 
    813     M4OSA_TRACE3_1("M4WRITER_3GP_processAU: returning 0x%x", err);
    814     return err;
    815 }
    816 
    817 
    818 /******************************************************************************
    819  * M4OSA_ERR M4WRITER_3GP_getInterfaces(
    820  *      M4WRITER_OutputFileType* Type,
    821  *      M4WRITER_GlobalInterface** SrcGlobalInterface,
    822  *      M4WRITER_DataInterface** SrcDataInterface)
    823  * @brief     Get the 3GPP writer common interface
    824  * @note      Retrieves the set of functions needed to use the 3GPP writer.
    825  *            It follows the common writer interface.
    826  * @param     Type: (OUT) return the type of this writer. Will always be
    827  *            M4WRITER_k3GPP.
    828  * @param     SrcGlobalInterface: (OUT) Main set of function to use this
    829  *            3GPP writer
    830  * @param     SrcDataInterface:   (OUT) Set of function related to datas
    831  *            to use this 3GPP writer
    832  * @return    M4NO_ERROR: there is no error
    833  * @return    M4ERR_ALLOC: there is no more available memory
    834  * @return    M4ERR_PARAMETER: At least one of the parameters is M4OSA_NULL
    835  *            (debug only)
    836  ******************************************************************************
    837 */
    838 M4OSA_ERR M4WRITER_3GP_getInterfaces(
    839         M4WRITER_OutputFileType* Type,
    840         M4WRITER_GlobalInterface** SrcGlobalInterface,
    841         M4WRITER_DataInterface** SrcDataInterface)
    842 {
    843     M4WRITER_GlobalInterface *pGlobal;
    844     M4WRITER_DataInterface *pData;
    845 
    846     M4OSA_TRACE2_3("M4WRITER_3GP_getInterfaces: "
    847          "Type=0x%x, SrcGlobalInterface=0x%x,\
    848          SrcDataInterface=0x%x", Type, SrcGlobalInterface, SrcDataInterface);
    849 
    850     /**
    851      *    Check input parameter */
    852     M4OSA_DEBUG_IF2((M4OSA_NULL == Type), M4ERR_PARAMETER,
    853          "M4WRITER_3GP_getInterfaces: Type is M4OSA_NULL");
    854     M4OSA_DEBUG_IF2((M4OSA_NULL == SrcGlobalInterface), M4ERR_PARAMETER,
    855          "M4WRITER_3GP_getInterfaces: SrcGlobalInterface is M4OSA_NULL");
    856     M4OSA_DEBUG_IF2((M4OSA_NULL == SrcDataInterface), M4ERR_PARAMETER,
    857          "M4WRITER_3GP_getInterfaces: SrcDataInterface is M4OSA_NULL");
    858 
    859     /**
    860      *    Set the output type */
    861     *Type = M4WRITER_k3GPP;
    862 
    863     /**
    864      *    Allocate the global interface structure */
    865     pGlobal = (M4WRITER_GlobalInterface*)M4OSA_32bitAlignedMalloc(
    866                 sizeof(M4WRITER_GlobalInterface),
    867                 M4WRITER_3GP, (M4OSA_Char *)"M4WRITER_GlobalInterface");
    868     if (M4OSA_NULL == pGlobal)
    869     {
    870         M4OSA_TRACE1_0("unable to allocate M4WRITER_GlobalInterface,\
    871              returning M4ERR_ALLOC");
    872         *SrcGlobalInterface = M4OSA_NULL;
    873         *SrcDataInterface = M4OSA_NULL;
    874         return (M4OSA_ERR)M4ERR_ALLOC;
    875     }
    876 
    877     /**
    878      *    Allocate the data interface structure */
    879     pData =
    880         (M4WRITER_DataInterface *)M4OSA_32bitAlignedMalloc(sizeof(M4WRITER_DataInterface),
    881         M4WRITER_3GP, (M4OSA_Char *)"M4WRITER_DataInterface");
    882     if (M4OSA_NULL == pData)
    883     {
    884         M4OSA_TRACE1_0("unable to allocate M4WRITER_DataInterface,\
    885              returning M4ERR_ALLOC");
    886         free(pGlobal);
    887         *SrcGlobalInterface = M4OSA_NULL;
    888         *SrcDataInterface = M4OSA_NULL;
    889         return (M4OSA_ERR)M4ERR_ALLOC;
    890     }
    891 
    892     /**
    893      *    Fill the global interface structure */
    894     pGlobal->pFctOpen = M4WRITER_3GP_openWrite;
    895     pGlobal->pFctAddStream = M4WRITER_3GP_addStream;
    896     pGlobal->pFctStartWriting = M4WRITER_3GP_startWriting;
    897     pGlobal->pFctCloseWrite = M4WRITER_3GP_closeWrite;
    898     pGlobal->pFctSetOption = M4WRITER_3GP_setOption;
    899     pGlobal->pFctGetOption = M4WRITER_3GP_getOption;
    900 
    901     /**
    902      *    Fill the data interface structure */
    903     pData->pStartAU = M4WRITER_3GP_startAU;
    904     pData->pProcessAU = M4WRITER_3GP_processAU;
    905 
    906     /**
    907      *    Set the return values */
    908     *SrcGlobalInterface = pGlobal;
    909     *SrcDataInterface = pData;
    910 
    911     M4OSA_TRACE2_0("M4WRITER_3GP_getInterfaces: returning M4NO_ERROR");
    912     return M4NO_ERROR;
    913 }
    914 
    915