• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
M4WRITER_3GP_openWrite(M4WRITER_Context * pContext,void * outputFileDescriptor,M4OSA_FileWriterPointer * pFileWriterPointer,void * tempFileDescriptor,M4OSA_FileReadPointer * pFileReaderPointer)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 */
M4WRITER_3GP_startWriting(M4WRITER_Context pContext)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 */
M4WRITER_3GP_addStream(M4WRITER_Context pContext,M4SYS_StreamDescription * pStreamDescription)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 */
M4WRITER_3GP_closeWrite(M4WRITER_Context pContext)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 */
M4WRITER_3GP_setOption(M4WRITER_Context pContext,M4OSA_UInt32 optionID,M4OSA_DataOption optionValue)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 */
M4WRITER_3GP_getOption(M4WRITER_Context pContext,M4OSA_UInt32 optionID,M4OSA_DataOption optionValue)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 */
M4WRITER_3GP_startAU(M4WRITER_Context pContext,M4SYS_StreamID streamID,M4SYS_AccessUnit * pAU)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 */
M4WRITER_3GP_processAU(M4WRITER_Context pContext,M4SYS_StreamID streamID,M4SYS_AccessUnit * pAU)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 */
M4WRITER_3GP_getInterfaces(M4WRITER_OutputFileType * Type,M4WRITER_GlobalInterface ** SrcGlobalInterface,M4WRITER_DataInterface ** SrcDataInterface)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