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