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