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 M4READER_Amr.c 20 * @brief Generic encapsulation of the core amr reader 21 * @note This file implements the generic M4READER interface 22 * on top of the AMR reader 23 ************************************************************************ 24*/ 25#include "M4OSA_Types.h" 26#include "M4OSA_Error.h" 27#include "M4OSA_Memory.h" 28#include "M4OSA_Debug.h" 29#include "M4OSA_CoreID.h" 30 31#include "M4_Utils.h" 32 33#include "M4AMRR_CoreReader.h" 34#include "M4READER_Amr.h" 35 36/** 37 ************************************************************************ 38 * structure M4READER_AMR_Context 39 * @brief This structure defines the internal context of a amr reader instance 40 * @note The context is allocated and de-allocated by the reader 41 ************************************************************************ 42*/ 43typedef struct _M4READER_AMR_Context 44{ 45 M4OSA_Context m_pCoreContext; /**< core amr reader context */ 46 M4_AudioStreamHandler* m_pAudioStream; /**< pointer on the audio stream 47 description returned by the core */ 48 M4SYS_AccessUnit m_audioAu; /**< audio access unit to be filled by the core */ 49 M4OSA_Time m_maxDuration; /**< duration of the audio stream */ 50 M4OSA_FileReadPointer* m_pOsaFileReaderFcts; /**< OSAL file read functions */ 51 52} M4READER_AMR_Context; 53 54 55/** 56 ************************************************************************ 57 * @brief create an instance of the reader 58 * @note allocates the context 59 * @param pContext: (OUT) pointer on a reader context 60 * @return M4NO_ERROR there is no error 61 * @return M4ERR_ALLOC a memory allocation has failed 62 * @return M4ERR_PARAMETER at least one parameter is not properly set (in DEBUG only) 63 ************************************************************************ 64*/ 65M4OSA_ERR M4READER_AMR_create(M4OSA_Context *pContext) 66{ 67 M4READER_AMR_Context* pReaderContext; 68 69 /* Check function parameters */ 70 M4OSA_DEBUG_IF1((pContext == 0), M4ERR_PARAMETER, 71 "M4READER_AMR_create: invalid context pointer"); 72 73 pReaderContext = (M4READER_AMR_Context*)M4OSA_32bitAlignedMalloc(sizeof(M4READER_AMR_Context), 74 M4READER_AMR, (M4OSA_Char *)"M4READER_AMR_Context"); 75 if (pReaderContext == M4OSA_NULL) 76 { 77 return M4ERR_ALLOC; 78 } 79 80 pReaderContext->m_pAudioStream = M4OSA_NULL; 81 pReaderContext->m_audioAu.dataAddress = M4OSA_NULL; 82 pReaderContext->m_maxDuration = 0; 83 pReaderContext->m_pCoreContext = M4OSA_NULL; 84 pReaderContext->m_pOsaFileReaderFcts = M4OSA_NULL; 85 86 *pContext = pReaderContext; 87 88 return M4NO_ERROR; 89} 90 91/** 92 ************************************************************************ 93 * @brief destroy the instance of the reader 94 * @note after this call the context is invalid 95 * 96 * @param context: (IN) Context of the reader 97 * 98 * @return M4NO_ERROR there is no error 99 * @return M4ERR_PARAMETER at least one parameter is not properly set 100 ************************************************************************ 101*/ 102M4OSA_ERR M4READER_AMR_destroy(M4OSA_Context context) 103{ 104 M4READER_AMR_Context* pC=(M4READER_AMR_Context*)context; 105 106 /* Check function parameters*/ 107 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 108 "M4READER_AMR_destroy: invalid context pointer"); 109 110 /** 111 * Check input parameter */ 112 if (M4OSA_NULL == pC) 113 { 114 M4OSA_TRACE1_0("M4READER_AMR_destroy(): M4READER_AMR_destroy: context is M4OSA_NULL,\ 115 returning M4ERR_PARAMETER"); 116 return M4ERR_PARAMETER; 117 } 118 119 free(pC); 120 121 return M4NO_ERROR; 122} 123 124 125/** 126 ************************************************************************ 127 * @brief open the reader and initializes its created instance 128 * @note this function opens the AMR file 129 * @param context: (IN) Context of the reader 130 * @param pFileDescriptor: (IN) Pointer to proprietary data identifying the media to open 131 * @return M4NO_ERROR there is no error 132 * @return M4ERR_PARAMETER the context is NULL 133 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 134 ************************************************************************ 135*/ 136M4OSA_ERR M4READER_AMR_open(M4OSA_Context context, M4OSA_Void* pFileDescriptor) 137{ 138 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 139 M4OSA_ERR err; 140 141 /* Check function parameters*/ 142 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 143 "M4READER_AMR_open: invalid context pointer"); 144 M4OSA_DEBUG_IF1((M4OSA_NULL == pFileDescriptor), M4ERR_PARAMETER, 145 "M4READER_AMR_open: invalid pointer pFileDescriptor"); 146 147 err = M4AMRR_openRead( &pC->m_pCoreContext, pFileDescriptor, pC->m_pOsaFileReaderFcts); 148 149 return err; 150} 151 152 153 154/** 155 ************************************************************************ 156 * @brief close the reader 157 * @note 158 * @param context: (IN) Context of the reader 159 * @return M4NO_ERROR there is no error 160 * @return M4ERR_PARAMETER the context is NULL 161 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 162 ************************************************************************ 163*/ 164M4OSA_ERR M4READER_AMR_close(M4OSA_Context context) 165{ 166 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 167 M4OSA_ERR err; 168 M4AMRR_State State; 169 170 /* Check function parameters*/ 171 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 172 "M4READER_AMR_close: invalid context pointer"); 173 174 /** 175 * Check input parameter */ 176 if (M4OSA_NULL == pC) 177 { 178 M4OSA_TRACE1_0("M4READER_AMR_close(): M4READER_AMR_close: context is M4OSA_NULL,\ 179 returning M4ERR_PARAMETER"); 180 return M4ERR_PARAMETER; 181 } 182 183 if (M4OSA_NULL != pC->m_pAudioStream) 184 { 185 err = M4AMRR_getState(pC->m_pCoreContext, &State, 186 ((M4_StreamHandler*)pC->m_pAudioStream)->m_streamId); 187 if(M4NO_ERROR != err) 188 { 189 M4OSA_TRACE1_0("M4READER_AMR_close: error when calling M4AMRR_getState\n"); 190 return err; 191 } 192 193 if (M4AMRR_kReading_nextAU == State) 194 { 195 err = M4AMRR_freeAU(pC->m_pCoreContext, 196 ((M4_StreamHandler*)pC->m_pAudioStream)->m_streamId, &pC->m_audioAu); 197 if (err != M4NO_ERROR) 198 { 199 M4OSA_TRACE1_0("M4READER_AMR_close: error when freeing access unit\n"); 200 return err; 201 } 202 } 203 204 /* Delete the DSI if needed */ 205 if(M4OSA_NULL != pC->m_pAudioStream->m_basicProperties.m_pDecoderSpecificInfo) 206 { 207 free(\ 208 pC->m_pAudioStream->m_basicProperties.m_pDecoderSpecificInfo); 209 210 pC->m_pAudioStream->m_basicProperties.m_decoderSpecificInfoSize = 0; 211 pC->m_pAudioStream->m_basicProperties.m_pDecoderSpecificInfo = M4OSA_NULL; 212 } 213 214 /* Finally destroy the stream handler */ 215 free(pC->m_pAudioStream); 216 pC->m_pAudioStream = M4OSA_NULL; 217 } 218 219 if (M4OSA_NULL != pC->m_pCoreContext) 220 { 221 err = M4AMRR_closeRead(pC->m_pCoreContext); 222 pC->m_pCoreContext = M4OSA_NULL; 223 } 224 225 return err; 226} 227 228/** 229 ************************************************************************ 230 * @brief Get the next stream found in the media 231 * @note current version needs to translate M4SYS_Stream to M4_StreamHandler 232 * 233 * @param context: (IN) Context of the reader 234 * @param pMediaFamily: (OUT) pointer to a user allocated M4READER_MediaFamily 235 * that will be filled with the media family of the found stream 236 * @param pStreamHandler: (OUT) pointer to a stream handler that will be 237 * allocated and filled with the found stream description 238 * 239 * @return M4NO_ERROR there is no error 240 * @return M4WAR_NO_MORE_STREAM no more available stream in the media (all streams found) 241 * @return M4ERR_PARAMETER at least one parameter is not properly set (in DEBUG mode only) 242 ************************************************************************ 243*/ 244M4OSA_ERR M4READER_AMR_getNextStream(M4OSA_Context context, M4READER_MediaFamily *pMediaFamily, 245 M4_StreamHandler **pStreamHandlerParam) 246{ 247 M4READER_AMR_Context* pC=(M4READER_AMR_Context*)context; 248 M4OSA_ERR err; 249 M4SYS_StreamID streamIdArray[2]; 250 M4SYS_StreamDescription streamDesc; 251 M4_AudioStreamHandler* pAudioStreamHandler; 252 M4_StreamHandler* pStreamHandler; 253 254 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 255 "M4READER_AMR_getNextStream: invalid context"); 256 M4OSA_DEBUG_IF1((pMediaFamily == 0), M4ERR_PARAMETER, 257 "M4READER_AMR_getNextStream: invalid pointer to MediaFamily"); 258 M4OSA_DEBUG_IF1((pStreamHandlerParam == 0), M4ERR_PARAMETER, 259 "M4READER_AMR_getNextStream: invalid pointer to StreamHandler"); 260 261 err = M4AMRR_getNextStream( pC->m_pCoreContext, &streamDesc); 262 if (err == M4WAR_NO_MORE_STREAM) 263 { 264 streamIdArray[0] = 0; 265 streamIdArray[1] = 0; 266 err = M4AMRR_startReading(pC->m_pCoreContext, streamIdArray); 267 if ((M4OSA_UInt32)M4ERR_ALLOC == err) 268 { 269 M4OSA_TRACE2_0("M4READER_AMR_getNextStream: M4AMRR_startReading returns M4ERR_ALLOC!"); 270 return err; 271 } 272 return M4WAR_NO_MORE_STREAM; 273 } 274 else if (err != M4NO_ERROR) 275 { 276 return err; 277 } 278 279 *pMediaFamily = M4READER_kMediaFamilyAudio; 280 281 pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc(sizeof(M4_AudioStreamHandler), 282 M4READER_AMR, (M4OSA_Char *)"M4_AudioStreamHandler"); 283 if (pAudioStreamHandler == M4OSA_NULL) 284 { 285 return M4ERR_ALLOC; 286 } 287 pStreamHandler =(M4_StreamHandler*)(pAudioStreamHandler); 288 *pStreamHandlerParam = pStreamHandler; 289 pC->m_pAudioStream = pAudioStreamHandler; 290 291 pAudioStreamHandler->m_structSize = sizeof(M4_AudioStreamHandler); 292 293 /* 294 * Audio stream handler fields are initialised with 0 value. 295 * They will be properly set by the AMR decoder 296 */ 297 pAudioStreamHandler->m_samplingFrequency = 0; 298 pAudioStreamHandler->m_byteFrameLength = 0; 299 pAudioStreamHandler->m_byteSampleSize = 0; 300 pAudioStreamHandler->m_nbChannels = 0; 301 302 pStreamHandler->m_pDecoderSpecificInfo = (M4OSA_UInt8*)(streamDesc.decoderSpecificInfo); 303 pStreamHandler->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize; 304 pStreamHandler->m_streamId = streamDesc.streamID; 305 pStreamHandler->m_duration = streamDesc.duration; 306 pStreamHandler->m_pUserData = (void*)streamDesc.timeScale; /*trick to change*/ 307 308 if (streamDesc.duration > pC->m_maxDuration) 309 { 310 pC->m_maxDuration = streamDesc.duration; 311 } 312 pStreamHandler->m_averageBitRate = streamDesc.averageBitrate; 313 314 M4AMRR_getmaxAUsize(pC->m_pCoreContext, &pStreamHandler->m_maxAUSize); 315 316 switch (streamDesc.streamType) 317 { 318 case M4SYS_kAMR: 319 pStreamHandler->m_streamType = M4DA_StreamTypeAudioAmrNarrowBand; 320 break; 321 case M4SYS_kAMR_WB: 322 pStreamHandler->m_streamType = M4DA_StreamTypeAudioAmrWideBand; 323 break; 324 default: 325 break; 326 } 327 328 return err; 329} 330 331/** 332 ************************************************************************ 333 * @brief fill the access unit structure with initialization values 334 * @note 335 * @param context: (IN) Context of the reader 336 * @param pStreamHandler: (IN) pointer to the stream handler to 337 * which the access unit will be associated 338 * @param pAccessUnit: (IN/OUT) pointer to the access unit (allocated by the caller) 339 * to initialize 340 * 341 * @return M4NO_ERROR there is no error 342 * @return M4ERR_PARAMETER at least one parameter is not properly set 343 ************************************************************************ 344*/ 345M4OSA_ERR M4READER_AMR_fillAuStruct(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 346 M4_AccessUnit *pAccessUnit) 347{ 348 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 349 M4SYS_AccessUnit* pAu; 350 351 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 352 "M4READER_AMR_fillAuStruct: invalid context"); 353 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 354 "M4READER_AMR_fillAuStruct: invalid pointer to M4_StreamHandler"); 355 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 356 "M4READER_AMR_fillAuStruct: invalid pointer to M4_AccessUnit"); 357 358 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 359 { 360 pAu = &pC->m_audioAu; 361 } 362 else 363 { 364 M4OSA_TRACE1_0("M4READER_AMR_fillAuStruct: passed StreamHandler is not known\n"); 365 return M4ERR_PARAMETER; 366 } 367 368 pAu->dataAddress = M4OSA_NULL; 369 pAu->size = 0; 370 /* JC: bug fix 1197 (set CTS to -20 in order the first AU CTS is 0) */ 371 pAu->CTS = -20; 372 pAu->DTS = -20; 373 pAu->attribute = 0; 374 pAu->nbFrag = 0; 375 376 pAccessUnit->m_size = 0; 377 /* JC: bug fix 1197 (set CTS to -20 in order the first AU CTS is 0) */ 378 pAccessUnit->m_CTS = -20; 379 pAccessUnit->m_DTS = -20; 380 pAccessUnit->m_attribute = 0; 381 pAccessUnit->m_dataAddress = M4OSA_NULL;/*pBuffer;*/ 382 pAccessUnit->m_maxsize = pStreamHandler->m_maxAUSize; 383 pAccessUnit->m_streamID = pStreamHandler->m_streamId; 384 pAccessUnit->m_structSize = sizeof(M4_AccessUnit); 385 386 return M4NO_ERROR; 387} 388 389/** 390 ************************************************************************ 391 * @brief get an option value from the reader 392 * @note this function follows the set/get option mechanism described in OSAL 3.0 393 * it allows the caller to retrieve a property value: 394 * - the duration of the longest stream of the media 395 * - the version number of the reader (not implemented yet) 396 * 397 * @param context: (IN) Context of the reader 398 * @param optionId: (IN) indicates the option to get 399 * @param pValue: (OUT) pointer to structure or value (allocated by user) 400 * where option is stored 401 * 402 * @return M4NO_ERROR there is no error 403 * @return M4ERR_PARAMETER at least one parameter is not properly set 404 * @return M4ERR_BAD_OPTION_ID when the option ID is not a valid one 405 ************************************************************************ 406*/ 407M4OSA_ERR M4READER_AMR_getOption(M4OSA_Context context, M4OSA_OptionID optionId, 408 M4OSA_DataOption pValue) 409 410{ 411 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 412 M4OSA_ERR err = M4NO_ERROR; 413 414 /* Check function parameters */ 415 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer"); 416 M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER, "invalid value pointer"); 417 418 switch(optionId) 419 { 420 case M4READER_kOptionID_Duration : 421 { 422 *(M4OSA_Time*)pValue = pC->m_maxDuration; 423 } 424 break; 425 426 case M4READER_kOptionID_Bitrate: 427 { 428 M4OSA_UInt32* pBitrate = (M4OSA_UInt32*)pValue; 429 if (M4OSA_NULL != pC->m_pAudioStream) 430 { 431 *pBitrate = pC->m_pAudioStream->m_basicProperties.m_averageBitRate; 432 } 433 else 434 { 435 pBitrate = 0; 436 err = M4ERR_PARAMETER; 437 } 438 439 } 440 break; 441 case M4READER_kOptionID_Version: 442 { 443 err = M4AMRR_getVersion((M4_VersionInfo*)pValue); 444 } 445 break; 446 447 default : 448 { 449 err = M4ERR_PARAMETER; 450 } 451 } 452 453 return err; 454} 455 456/** 457 ************************************************************************ 458 * @brief set en option value of the readder 459 * @note this function follows the set/get option mechanism described in OSAL 3.0 460 * it allows the caller to set a property value: 461 * - the OSAL file read functions 462 * 463 * @param context: (IN) Context of the decoder 464 * @param optionId: (IN) Identifier indicating the option to set 465 * @param pValue: (IN) Pointer to structure or value (allocated by user) 466 * where option is stored 467 * 468 * @return M4NO_ERROR There is no error 469 * @return M4ERR_BAD_OPTION_ID The option ID is not a valid one 470 * @return M4ERR_STATE State automaton is not applied 471 * @return M4ERR_PARAMETER The option parameter is invalid 472 ************************************************************************ 473*/ 474M4OSA_ERR M4READER_AMR_setOption(M4OSA_Context context, M4OSA_OptionID optionId, 475 M4OSA_DataOption pValue) 476{ 477 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 478 M4OSA_ERR err = M4NO_ERROR; 479 480 /* Check function parameters */ 481 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer"); 482 M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER, "invalid value pointer"); 483 484 switch(optionId) 485 { 486 case M4READER_kOptionID_SetOsaFileReaderFctsPtr : 487 { 488 pC->m_pOsaFileReaderFcts = (M4OSA_FileReadPointer*)pValue; 489 } 490 break; 491 default : 492 { 493 err = M4ERR_PARAMETER; 494 } 495 } 496 497 return err; 498} 499 500/** 501 ************************************************************************ 502 * @brief reset the stream, that is seek it to beginning and make it ready to be read 503 * @note this function is to be deprecated in next versions 504 * 505 * @param context: (IN) Context of the reader 506 * @param pStreamHandler (IN) The stream handler of the stream to reset 507 * 508 * @return M4NO_ERROR there is no error 509 * @return M4ERR_PARAMETER at least one parameter is not properly set 510 * @return M4ERR_ALLOC there is no more memory available 511 * @return M4ERR_BAD_STREAM_ID the streamID does not exist 512 * @return M4ERR_STATE this function cannot be called now 513 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 514 * @return M4WAR_INVALID_TIME beginning of the stream can not be reached 515 ************************************************************************ 516*/ 517M4OSA_ERR M4READER_AMR_reset(M4OSA_Context context, M4_StreamHandler *pStreamHandler) 518{ 519 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 520 M4SYS_StreamID streamIdArray[2]; 521 M4OSA_ERR err; 522 M4SYS_AccessUnit* pAu; 523 M4OSA_Time time64 = 0; 524 M4AMRR_State State; 525 526 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_AMR_reset: invalid context"); 527 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 528 "M4READER_AMR_reset: invalid pointer to M4_StreamHandler"); 529 530 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 531 { 532 pAu = &pC->m_audioAu; 533 } 534 else 535 { 536 M4OSA_TRACE1_0("M4READER_AMR_reset: passed StreamHandler is not known\n"); 537 return M4ERR_PARAMETER; 538 } 539 540 err = M4AMRR_getState(pC->m_pCoreContext, &State, pStreamHandler->m_streamId); 541 if (M4AMRR_kReading_nextAU == State) 542 { 543 err = M4AMRR_freeAU(pC->m_pCoreContext, pStreamHandler->m_streamId, pAu); 544 if (err != M4NO_ERROR) 545 { 546 M4OSA_TRACE1_0("M4READER_AMR_reset: error when freeing access unit\n"); 547 return err; 548 } 549 pAu->dataAddress = M4OSA_NULL; 550 } 551 552 streamIdArray[0] = pStreamHandler->m_streamId; 553 streamIdArray[1] = 0; 554 555 err = M4NO_ERROR; 556 557 /* for reset during playback */ 558 /* (set CTS to -20 in order the first AU CTS is 0) */ 559 pAu->CTS = -20; 560 pAu->DTS = -20; 561 562 err = M4AMRR_seek(pC->m_pCoreContext, streamIdArray, time64, M4SYS_kBeginning, &time64); 563 if (err != M4NO_ERROR) 564 { 565 M4OSA_TRACE1_0("M4READER_AMR_reset: error when calling M4AMRR_seek()\n"); 566 return err; 567 } 568 569 return err; 570} 571 572/** 573 ************************************************************************ 574 * @brief jump into the stream at the specified time 575 * @note 576 * @param context: (IN) Context of the reader 577 * @param pStreamHandler (IN) the stream description of the stream to make jump 578 * @param pTime (IN/OUT) IN: the time to jump to (in ms) 579 * OUT: the time to which the stream really jumped 580 * @return M4NO_ERROR there is no error 581 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 582 * @return M4ERR_PARAMETER at least one parameter is not properly set 583 * @return M4ERR_ALLOC there is no more memory available 584 * @return M4WAR_INVALID_TIME the time can not be reached 585 ************************************************************************ 586*/ 587M4OSA_ERR M4READER_AMR_jump(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 588 M4OSA_Int32* pTime) 589{ 590 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 591 M4SYS_StreamID streamIdArray[2]; 592 M4OSA_ERR err; 593 M4SYS_AccessUnit* pAu; 594 M4OSA_Time time64 = (M4OSA_Time)*pTime; 595 M4AMRR_State State; 596 597 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_AMR_reset: invalid context"); 598 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 599 "M4READER_AMR_reset: invalid pointer to M4_StreamHandler"); 600 M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER, "M4READER_3GP_jump: invalid time pointer"); 601 602 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 603 { 604 pAu = &pC->m_audioAu; 605 } 606 else 607 { 608 M4OSA_TRACE1_0("M4READER_AMR_jump: passed StreamHandler is not known\n"); 609 return M4ERR_PARAMETER; 610 } 611 612 err = M4AMRR_getState(pC->m_pCoreContext, &State, pStreamHandler->m_streamId); 613 if (M4AMRR_kReading_nextAU == State) 614 { 615 err = M4AMRR_freeAU(pC->m_pCoreContext, pStreamHandler->m_streamId, pAu); 616 if (err != M4NO_ERROR) 617 { 618 M4OSA_TRACE1_0("M4READER_AMR_jump: error when freeing access unit\n"); 619 return err; 620 } 621 pAu->dataAddress = M4OSA_NULL; 622 } 623 624 streamIdArray[0] = pStreamHandler->m_streamId; 625 streamIdArray[1] = 0; 626 627 pAu->CTS = time64; 628 pAu->DTS = time64; 629 err = M4AMRR_seek(pC->m_pCoreContext, streamIdArray, time64, M4SYS_kNoRAPprevious, &time64); 630 if (err != M4NO_ERROR) 631 { 632 M4OSA_TRACE1_0("M4READER_AMR_jump: error when calling M4AMRR_seek()\n"); 633 return err; 634 } 635 636 *pTime = (M4OSA_Int32)time64; 637 638 return err; 639} 640 641/** 642 ************************************************************************ 643 * @brief Gets an access unit (AU) from the stream handler source. 644 * @note An AU is the smallest possible amount of data to be decoded by a decoder (audio/video). 645 * In the current version, we need to translate M4OSA_AccessUnit to M4_AccessUnit 646 * 647 * @param context: (IN) Context of the reader 648 * @param pStreamHandler (IN) The stream handler of the stream to make jump 649 * @param pAccessUnit (IN/OUT) Pointer to an access unit to fill with read data (the au 650 structure is allocated by the user, and must be 651 initialized by calling M4READER_fillAuStruct_fct after 652 creation) 653 * @return M4NO_ERROR there is no error 654 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 655 * @return M4ERR_PARAMETER at least one parameter is not properly set 656 * @return M4ERR_ALLOC memory allocation failed 657 * @return M4ERR_BAD_STREAM_ID at least one of the stream Id. does not exist. 658 * @return M4WAR_NO_MORE_AU there are no more access unit in the stream (end of stream) 659 ************************************************************************ 660*/ 661M4OSA_ERR M4READER_AMR_getNextAu(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 662 M4_AccessUnit *pAccessUnit) 663{ 664 M4READER_AMR_Context* pC = (M4READER_AMR_Context*)context; 665 M4OSA_ERR err = M4NO_ERROR; 666 M4SYS_AccessUnit* pAu; 667 M4_MediaTime timeScale; 668 M4AMRR_State State; 669 670 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 671 "M4READER_AMR_getNextAu: invalid context"); 672 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 673 "M4READER_AMR_getNextAu: invalid pointer to M4_StreamHandler"); 674 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 675 "M4READER_AMR_getNextAu: invalid pointer to M4_AccessUnit"); 676 677 /* keep trace of the allocated buffers in AU to be able to free them at destroy() 678 but be aware that system is risky and would need upgrade if more than 679 one video and one audio AU is needed */ 680 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 681 { 682 pAu = &pC->m_audioAu; 683 } 684 else 685 { 686 M4OSA_TRACE1_0("M4READER_AMR_getNextAu: passed StreamHandler is not known\n"); 687 return M4ERR_PARAMETER; 688 } 689 690 err = M4AMRR_getState(pC->m_pCoreContext, &State, pStreamHandler->m_streamId); 691 if (M4AMRR_kReading_nextAU == State) 692 { 693 err = M4AMRR_freeAU(pC->m_pCoreContext, pStreamHandler->m_streamId, pAu); 694 if (err != M4NO_ERROR) 695 { 696 M4OSA_TRACE1_0("M4READER_AVI_getNextAu: error when freeing access unit\n"); 697 return err; 698 } 699 pAu->dataAddress = M4OSA_NULL; 700 } 701 702 pAu->nbFrag = 0; 703 err = M4AMRR_nextAU(pC->m_pCoreContext, pStreamHandler->m_streamId, pAu); 704 705 if (err == M4NO_ERROR) 706 { 707 timeScale = (M4OSA_Float)(M4OSA_Int32)(pStreamHandler->m_pUserData)/1000; 708 pAccessUnit->m_dataAddress = (M4OSA_MemAddr8)pAu->dataAddress; 709 pAccessUnit->m_size = pAu->size; 710 pAccessUnit->m_CTS = (M4_MediaTime)pAu->CTS/*/timeScale*/; 711 pAccessUnit->m_DTS = (M4_MediaTime)pAu->DTS/*/timeScale*/; 712 pAccessUnit->m_attribute = pAu->attribute; 713 } 714 else 715 { 716 pAccessUnit->m_size=0; 717 } 718 719 return err; 720} 721 722/** 723************************************************************************* 724* @brief Retrieves the generic interfaces implemented by the reader 725* 726* @param pMediaType : Pointer on a M4READER_MediaType (allocated by the caller) 727* that will be filled with the media type supported by this reader 728* @param pRdrGlobalInterface : Address of a pointer that will be set to the global interface implemented 729* by this reader. The interface is a structure allocated by the function and must 730* be un-allocated by the caller. 731* @param pRdrDataInterface : Address of a pointer that will be set to the data interface implemented 732* by this reader. The interface is a structure allocated by the function and must 733* be un-allocated by the caller. 734* 735* @returns : M4NO_ERROR if OK 736* ERR_ALLOC if an allocation failed 737* ERR_PARAMETER at least one parameter is not properly set (in DEBUG only) 738************************************************************************* 739*/ 740M4OSA_ERR M4READER_AMR_getInterfaces(M4READER_MediaType *pMediaType, 741 M4READER_GlobalInterface **pRdrGlobalInterface, 742 M4READER_DataInterface **pRdrDataInterface) 743{ 744 M4OSA_DEBUG_IF1((pMediaType == 0), M4ERR_PARAMETER, 745 "M4READER_AMR_getInterfaces: invalid pointer to MediaType"); 746 M4OSA_DEBUG_IF1((pRdrGlobalInterface == 0), M4ERR_PARAMETER, 747 "M4READER_AMR_getInterfaces: invalid pointer to M4READER_GlobalInterface"); 748 M4OSA_DEBUG_IF1((pRdrDataInterface == 0), M4ERR_PARAMETER, 749 "M4READER_AMR_getInterfaces: invalid pointer to M4READER_DataInterface"); 750 751 *pRdrGlobalInterface = 752 (M4READER_GlobalInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_GlobalInterface), 753 M4READER_AMR, (M4OSA_Char *)"M4READER_GlobalInterface" ); 754 if (M4OSA_NULL == *pRdrGlobalInterface) 755 { 756 *pRdrDataInterface = M4OSA_NULL; 757 return M4ERR_ALLOC; 758 } 759 *pRdrDataInterface = (M4READER_DataInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_DataInterface), 760 M4READER_AMR, (M4OSA_Char *)"M4READER_DataInterface"); 761 if (M4OSA_NULL == *pRdrDataInterface) 762 { 763 free(*pRdrGlobalInterface); 764 *pRdrGlobalInterface = M4OSA_NULL; 765 return M4ERR_ALLOC; 766 } 767 768 *pMediaType = M4READER_kMediaTypeAMR; 769 770 (*pRdrGlobalInterface)->m_pFctCreate = M4READER_AMR_create; 771 (*pRdrGlobalInterface)->m_pFctDestroy = M4READER_AMR_destroy; 772 (*pRdrGlobalInterface)->m_pFctOpen = M4READER_AMR_open; 773 (*pRdrGlobalInterface)->m_pFctClose = M4READER_AMR_close; 774 (*pRdrGlobalInterface)->m_pFctGetOption = M4READER_AMR_getOption; 775 (*pRdrGlobalInterface)->m_pFctSetOption = M4READER_AMR_setOption; 776 (*pRdrGlobalInterface)->m_pFctGetNextStream = M4READER_AMR_getNextStream; 777 (*pRdrGlobalInterface)->m_pFctFillAuStruct = M4READER_AMR_fillAuStruct; 778 (*pRdrGlobalInterface)->m_pFctStart = M4OSA_NULL; 779 (*pRdrGlobalInterface)->m_pFctStop = M4OSA_NULL; 780 (*pRdrGlobalInterface)->m_pFctJump = M4READER_AMR_jump; 781 (*pRdrGlobalInterface)->m_pFctReset = M4READER_AMR_reset; 782 (*pRdrGlobalInterface)->m_pFctGetPrevRapTime = M4OSA_NULL; /*all AUs are RAP*/ 783 784 (*pRdrDataInterface)->m_pFctGetNextAu = M4READER_AMR_getNextAu; 785 786 (*pRdrDataInterface)->m_readerContext = M4OSA_NULL; 787 788 return M4NO_ERROR; 789} 790 791