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