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