M4READER_Pcm.c revision aa382f3637a68361989d5b70e3184bddcc472d3d
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 * @file M4READER_Wav.c 20 * @brief Generic encapsulation of the core pcm reader 21 * @note This file implements the generic M4READER interface 22 * on top of the PCM reader 23 ************************************************************************ 24*/ 25 26#include "M4OSA_Types.h" 27#include "M4OSA_Error.h" 28#include "M4OSA_Memory.h" 29#include "M4OSA_Debug.h" 30#include "M4OSA_CoreID.h" 31#include "M4TOOL_VersionInfo.h" 32#include "M4PCMR_CoreReader.h" 33#include "M4READER_Pcm.h" 34/** 35 ************************************************************************ 36 * structure M4READER_WAV_Context 37 * @brief This structure defines the internal context of a wav reader instance 38 * @note The context is allocated and de-allocated by the reader 39 ************************************************************************ 40 */ 41typedef struct _M4READER_PCM_Context 42{ 43 M4OSA_Context m_coreContext; /**< core wav reader context */ 44 M4_StreamHandler* m_pAudioStream; /**< pointer on the audio stream description 45 returned by the core */ 46 M4SYS_AccessUnit m_audioAu; /**< audio access unit to be filled by the core */ 47 M4OSA_FileReadPointer* m_pOsaFileReaderFcts; /**< OSAL file read functions */ 48 49} M4READER_PCM_Context; 50 51 52/** 53 ************************************************************************ 54 * @brief Creates a wav reader instance 55 * @note allocates the context 56 * @param pContext: (OUT) Pointer to a wav reader context 57 * @return M4NO_ERROR: there is no error 58 * @return M4ERR_ALLOC: a memory allocation has failed 59 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 60 ************************************************************************ 61 */ 62M4OSA_ERR M4READER_PCM_create(M4OSA_Context* pContext) 63{ 64 M4READER_PCM_Context* pReaderContext; 65 66 M4OSA_DEBUG_IF1((pContext == 0), M4ERR_PARAMETER, 67 "M4READER_PCM_create: invalid context pointer"); 68 69 pReaderContext = (M4READER_PCM_Context*)M4OSA_32bitAlignedMalloc(sizeof(M4READER_PCM_Context), 70 M4READER_WAV, (M4OSA_Char *)"M4READER_PCM_Context"); 71 if (pReaderContext == M4OSA_NULL) 72 { 73 return M4ERR_ALLOC; 74 } 75 76 pReaderContext->m_coreContext = M4OSA_NULL; 77 pReaderContext->m_pAudioStream = M4OSA_NULL; 78 pReaderContext->m_audioAu.dataAddress = M4OSA_NULL; 79 pReaderContext->m_pOsaFileReaderFcts = M4OSA_NULL; 80 81 *pContext = pReaderContext; 82 83 return M4NO_ERROR; 84} 85 86/** 87 ************************************************************************ 88 * @brief Destroy the instance of the reader 89 * @note the context is un-allocated 90 * @param context: (IN) context of the network reader 91 * @return M4NO_ERROR: there is no error 92 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 93 ************************************************************************ 94 */ 95M4OSA_ERR M4READER_PCM_destroy(M4OSA_Context context) 96{ 97 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 98 99 /* Check function parameters */ 100 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 101 "M4READER_PCM_destroy: invalid context pointer"); 102 103 free(pC); 104 105 return M4NO_ERROR; 106} 107 108/** 109 ************************************************************************ 110 * @brief Initializes the reader instance 111 * @param context: (IN) context of the network reader 112 * @param pFileDescriptor: (IN) Pointer to proprietary data identifying the media to open 113 * @return M4NO_ERROR: there is no error 114 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 115 ************************************************************************ 116 */ 117M4OSA_ERR M4READER_PCM_open(M4OSA_Context context, M4OSA_Void* pFileDescriptor) 118{ 119 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 120 M4OSA_ERR err; 121 122 /* Check function parameters */ 123 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 124 "M4READER_PCM_open: invalid context pointer"); 125 M4OSA_DEBUG_IF1((M4OSA_NULL == pFileDescriptor), M4ERR_PARAMETER, 126 "M4READER_PCM_open: invalid pointer pFileDescriptor"); 127 128 err = M4PCMR_openRead(&(pC->m_coreContext), (M4OSA_Char*)pFileDescriptor, 129 pC->m_pOsaFileReaderFcts); 130 131 return err; 132} 133 134/** 135 ************************************************************************ 136 * @brief close the reader 137 * @note 138 * @param context: (IN) Context of the reader 139 * @return M4NO_ERROR there is no error 140 * @return M4ERR_PARAMETER the context is NULL 141 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 142 ************************************************************************ 143 */ 144M4OSA_ERR M4READER_PCM_close(M4OSA_Context context) 145{ 146 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 147 M4OSA_ERR err; 148 149 /* Check function parameters */ 150 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 151 "M4READER_PCM_close: invalid context pointer"); 152 153 /* Free audio AU and audio stream */ 154 if (M4OSA_NULL != pC->m_pAudioStream) 155 { 156 if (M4OSA_NULL != pC->m_audioAu.dataAddress) 157 { 158 err = M4PCMR_freeAU(pC->m_coreContext, pC->m_pAudioStream->m_streamId, 159 &pC->m_audioAu); 160 if (err != M4NO_ERROR) 161 { 162 M4OSA_TRACE1_0("M4READER_PCM_close: Error when freeing audio access unit"); 163 return err; 164 } 165 } 166 free(pC->m_pAudioStream); 167 pC->m_pAudioStream = M4OSA_NULL; 168 } 169 170 171 if (M4OSA_NULL != pC->m_coreContext) 172 { 173 /* Close tha PCM file */ 174 err = M4PCMR_closeRead(pC->m_coreContext); 175 pC->m_coreContext = M4OSA_NULL; 176 } 177 178 179 return err; 180} 181 182/** 183 ************************************************************************ 184 * @brief set en option value of the reader 185 * @note this function follows the set/get option mechanism described in OSAL 3.0 186 * it allows the caller to set a property value: 187 * @param context: (IN) Context of the reader 188 * @param optionId: (IN) indicates the option to set 189 * @param pValue: (IN) pointer to structure or value (allocated by user) 190 * where option is stored 191 * 192 * @return M4NO_ERROR there is no error 193 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 194 * @return M4ERR_PARAMETER at least one parameter is not properly set 195 * @return M4ERR_BAD_OPTION_ID when the option ID is not a valid one 196 ************************************************************************ 197 */ 198M4OSA_ERR M4READER_PCM_setOption(M4OSA_Context context, M4OSA_OptionID optionId, void* pValue) 199{ 200 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 201 M4OSA_ERR err = M4NO_ERROR; 202 203 /* Check function parameters */ 204 M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, 205 "M4READER_PCM_setOption: invalid context pointer"); 206 M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER, 207 "M4READER_PCM_setOption: invalid value pointer"); 208 209 switch(optionId) 210 { 211 case M4READER_kOptionID_SetOsaFileReaderFctsPtr : 212 { 213 pC->m_pOsaFileReaderFcts = (M4OSA_FileReadPointer*)pValue; 214 } 215 break; 216 default : 217 { 218 err = M4ERR_PARAMETER; 219 } 220 } 221 222 return err; 223} 224 225/** 226 ************************************************************************ 227 * @brief Retrieves the an option value from the reader, given an option ID. 228 * @note this function follows the set/get option mechanism described in OSAL 3.0 229 * it allows the caller to retrieve a property value: 230 * 231 * @param context: (IN) context of the network reader 232 * @param optionId: (IN) option identificator whose option value is to be retrieved. 233 * @param pValue: (OUT) option value retrieved. 234 * 235 * @return M4NO_ERROR: there is no error 236 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 237 * @return M4ERR_BAD_OPTION_ID: the required option identificator is unknown 238 ************************************************************************ 239 */ 240M4OSA_ERR M4READER_PCM_getOption(M4OSA_Context context, M4OSA_OptionID optionId, void* pValue) 241{ 242 M4READER_PCM_Context* pContext = (M4READER_PCM_Context*)context; 243 M4OSA_ERR err = M4NO_ERROR; 244 245 /* no check of context at this level because some option does not need it */ 246 M4OSA_DEBUG_IF1((pValue == 0), M4ERR_PARAMETER, 247 "M4READER_PCM_getOption: invalid pointer on value"); 248 249 switch (optionId) 250 { 251 case M4READER_kOptionID_Duration: 252 *((M4OSA_UInt32*)pValue) = pContext->m_pAudioStream->m_duration; 253 break; 254 255 case M4READER_kOptionID_Version: 256 err = M4PCMR_getVersion((M4_VersionInfo*)pValue); 257 break; 258 259 case M4READER_kOptionID_Copyright: 260 return M4ERR_NOT_IMPLEMENTED; 261 break; 262 263 case M4READER_kOptionID_Bitrate: 264 { 265 M4OSA_UInt32* pBitrate = (M4OSA_UInt32*)pValue; 266 if (M4OSA_NULL != pContext->m_pAudioStream) 267 { 268 *pBitrate = pContext->m_pAudioStream->m_averageBitRate; 269 } 270 else 271 { 272 pBitrate = 0; 273 err = M4ERR_PARAMETER; 274 } 275 } 276 break; 277 278 default: 279 err = M4ERR_BAD_OPTION_ID; 280 M4OSA_TRACE1_0("M4READER_PCM_getOption: unsupported optionId"); 281 break; 282 } 283 284 return err; 285} 286 287/** 288 ************************************************************************ 289 * @brief Get the next stream found in the media 290 * @note 291 * 292 * @param context: (IN) context of the network reader 293 * @param pMediaFamily: (OUT) pointer to a user allocated M4READER_MediaFamily that will 294 * be filled 295 * @param pStreamHandler: (OUT) pointer to a stream handler that will be allocated and filled 296 * with the found stream description 297 * 298 * @return M4NO_ERROR: there is no error. 299 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 300 * @return M4WAR_NO_MORE_STREAM no more available stream in the media (all streams found) 301 ************************************************************************ 302 */ 303M4OSA_ERR M4READER_PCM_getNextStream(M4OSA_Context context, M4READER_MediaFamily *pMediaFamily, 304 M4_StreamHandler **pStreamHandler) 305{ 306 M4READER_PCM_Context* pC=(M4READER_PCM_Context*)context; 307 M4OSA_ERR err; 308/* M4_StreamHandler* pStreamHandler = M4OSA_NULL;*/ 309 M4SYS_StreamDescription streamDesc; 310 M4_AudioStreamHandler* pAudioStreamHandler; 311 M4OSA_Double fDuration; 312 M4SYS_StreamID streamIdArray[2]; 313 M4PCMC_DecoderSpecificInfo* pDsi; 314 315 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 316 "M4READER_PCM_getNextStream: invalid context"); 317 M4OSA_DEBUG_IF1((pMediaFamily == 0), M4ERR_PARAMETER, 318 "M4READER_PCM_getNextStream: invalid pointer to MediaFamily"); 319 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 320 "M4READER_PCM_getNextStream: invalid pointer to StreamHandler"); 321 322 err = M4PCMR_getNextStream( pC->m_coreContext, &streamDesc); 323 if (err == M4WAR_NO_MORE_STREAM) 324 { 325 streamIdArray[0] = 0; 326 streamIdArray[1] = 0; 327 err = M4PCMR_startReading(pC->m_coreContext, streamIdArray); /*to put in open function*/ 328 329 return M4WAR_NO_MORE_STREAM; 330 } 331 else if (M4NO_ERROR != err) 332 { 333 return err; /*also return M4WAR_NO_MORE_STREAM*/ 334 } 335 336 switch (streamDesc.streamType) 337 { 338 case M4SYS_kAudioUnknown: 339 case M4SYS_kPCM_16bitsS: 340 case M4SYS_kPCM_16bitsU: 341 case M4SYS_kPCM_8bitsU: 342 *pMediaFamily = M4READER_kMediaFamilyAudio; 343 M4OSA_TRACE2_0("M4READER_PCM_getNextStream: found audio stream"); 344 break; 345 default: 346 *pMediaFamily = M4READER_kMediaFamilyUnknown; 347 M4OSA_TRACE2_0("M4READER_PCM_getNextStream: found UNKNOWN stream"); 348 return M4NO_ERROR; 349 } 350 351 pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc(sizeof(M4_AudioStreamHandler), 352 M4READER_WAV, (M4OSA_Char *)"M4_AudioStreamHandler"); 353 if (pAudioStreamHandler == M4OSA_NULL) 354 { 355 return M4ERR_ALLOC; 356 } 357 pAudioStreamHandler->m_structSize = sizeof(M4_AudioStreamHandler); 358 pC->m_pAudioStream = (M4_StreamHandler*)(pAudioStreamHandler); 359 360 pDsi = (M4PCMC_DecoderSpecificInfo*)(streamDesc.decoderSpecificInfo); 361 M4OSA_DEBUG_IF1((pDsi == 0), M4ERR_PARAMETER, 362 "M4READER_PCM_getNextStream: invalid decoder specific info in stream"); 363 364 pAudioStreamHandler->m_samplingFrequency = pDsi->SampleFrequency; 365 pAudioStreamHandler->m_byteSampleSize = (M4OSA_UInt32)(pDsi->BitsPerSample/8); 366 /* m_byteFrameLength is badly named: it is not in bytes but in samples number */ 367 if(pAudioStreamHandler->m_samplingFrequency == 8000) 368 { 369 /* AMR case */ 370 pAudioStreamHandler->m_byteFrameLength = 371 (((streamDesc.averageBitrate/8)/50)/pDsi->nbChannels)\ 372 /pAudioStreamHandler->m_byteSampleSize;/*/50 to get around 20 ms of audio*/ 373 } 374 else 375 { 376 /* AAC Case */ 377 pAudioStreamHandler->m_byteFrameLength = 378 (M4OSA_UInt32)(((streamDesc.averageBitrate/8)/15.625)/pDsi->nbChannels)\ 379 /pAudioStreamHandler->m_byteSampleSize; 380 } 381 382 pAudioStreamHandler->m_nbChannels = pDsi->nbChannels; 383 384 M4OSA_TIME_TO_MS( fDuration, streamDesc.duration, streamDesc.timeScale); 385 pC->m_pAudioStream->m_duration = (M4OSA_Int32)fDuration; 386 pC->m_pAudioStream->m_pDecoderSpecificInfo = (M4OSA_UInt8*)(streamDesc.decoderSpecificInfo); 387 pC->m_pAudioStream->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize; 388 pC->m_pAudioStream->m_streamId = streamDesc.streamID; 389 pC->m_pAudioStream->m_pUserData = 390 (void*)streamDesc.timeScale; /*trick to change*/ 391 pC->m_pAudioStream->m_averageBitRate = streamDesc.averageBitrate; 392 pC->m_pAudioStream->m_maxAUSize = 393 pAudioStreamHandler->m_byteFrameLength*pAudioStreamHandler->m_byteSampleSize\ 394 *pAudioStreamHandler->m_nbChannels; 395 pC->m_pAudioStream->m_streamType = M4DA_StreamTypeAudioPcm; 396 397 *pStreamHandler = pC->m_pAudioStream; 398 return err; 399} 400 401/** 402 ************************************************************************ 403 * @brief fill the access unit structure with initialization values 404 * @note 405 * 406 * @param context: (IN) context of the network reader 407 * @param pStreamHandler: (IN) pointer to the stream handler to which the access unit will 408 * be associated 409 * @param pAccessUnit: (IN) pointer to the access unit(allocated by the caller) to initialize 410 * @return M4NO_ERROR: there is no error. 411 * @return M4ERR_PARAMETER: at least one parameter is not properly set (in DEBUG only) 412 ************************************************************************ 413 */ 414M4OSA_ERR M4READER_PCM_fillAuStruct(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 415 M4_AccessUnit *pAccessUnit) 416{ 417 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 418 M4SYS_AccessUnit* pAu; 419 420 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 421 "M4READER_PCM_fillAuStruct: invalid context"); 422 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 423 "M4READER_PCM_fillAuStruct: invalid pointer to M4_StreamHandler"); 424 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 425 "M4READER_PCM_fillAuStruct: invalid pointer to M4_AccessUnit"); 426 427 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 428 { 429 pAu = &pC->m_audioAu; 430 } 431 else 432 { 433 M4OSA_TRACE1_0("M4READER_PCM_fillAuStruct: passed StreamHandler is not known"); 434 return M4ERR_PARAMETER; 435 } 436 437 pAu->dataAddress = M4OSA_NULL; 438 pAu->size = 0; 439 pAu->CTS = 0; 440 pAu->DTS = 0; 441 pAu->attribute = 0; 442 pAu->nbFrag = 0; 443 444 pAccessUnit->m_size = 0; 445 pAccessUnit->m_CTS = 0; 446 pAccessUnit->m_DTS = 0; 447 pAccessUnit->m_attribute = 0; 448 pAccessUnit->m_dataAddress = M4OSA_NULL;/*pBuffer;*/ 449 pAccessUnit->m_maxsize = pStreamHandler->m_maxAUSize; 450 pAccessUnit->m_streamID = pStreamHandler->m_streamId; 451 pAccessUnit->m_structSize = sizeof(M4_AccessUnit); 452 453 return M4NO_ERROR; 454} 455 456/** 457 ************************************************************************ 458 * @brief reset the stream, that is: seek it to beginning and make it ready to be read 459 * @note 460 * @param context: (IN) context of the network reader 461 * @param pStreamHandler: (IN) The stream handler of the stream to reset 462 * @return M4NO_ERROR: there is no error. 463 ************************************************************************ 464 */ 465M4OSA_ERR M4READER_PCM_reset(M4OSA_Context context, M4_StreamHandler *pStreamHandler) 466{ 467 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 468 M4SYS_StreamID streamIdArray[2]; 469 M4OSA_ERR err; 470 M4SYS_AccessUnit* pAu; 471 M4OSA_Time time64 = 0; 472 473 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_PCM_reset: invalid context"); 474 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 475 "M4READER_PCM_reset: invalid pointer to M4_StreamHandler"); 476 477 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 478 { 479 pAu = &pC->m_audioAu; 480 } 481 else 482 { 483 M4OSA_TRACE1_0("M4READER_PCM_reset: passed StreamHandler is not known"); 484 return M4ERR_PARAMETER; 485 } 486 487 if (pAu->dataAddress != M4OSA_NULL) 488 { 489 err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu); 490 if (err != M4NO_ERROR) 491 { 492 M4OSA_TRACE1_0("M4READER_PCM_reset: error when freeing access unit"); 493 return err; 494 } 495 pAu->dataAddress = M4OSA_NULL; 496 } 497 498 streamIdArray[0] = pStreamHandler->m_streamId; 499 streamIdArray[1] = 0; 500 501 pAu->CTS = 0; 502 pAu->DTS = 0; 503 504 /* This call is needed only when replay during playback */ 505 err = M4PCMR_seek(pC->m_coreContext, streamIdArray, time64, M4SYS_kBeginning, &time64); 506 507 return err; 508} 509 510/** 511 ************************************************************************ 512 * @brief Get the next access unit of the specified stream 513 * @note 514 * @param context: (IN) Context of the reader 515 * @param pStreamHandler (IN) The stream handler of the stream to make jump 516 * @param pAccessUnit (IN/OUT) Pointer to an access unit to fill with read data 517 * (the au structure is allocated by the user, and must be 518 * initialized 519 * by calling M4READER_fillAuStruct_fct after creation) 520 * @return M4NO_ERROR there is no error 521 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 522 * @return M4ERR_PARAMETER at least one parameter is not properly set 523 * @returns M4ERR_ALLOC memory allocation failed 524 * @returns M4ERR_BAD_STREAM_ID at least one of the stream Id. does not exist. 525 * @returns M4WAR_NO_DATA_YET there is no enough data on the stream for new access unit 526 * @returns M4WAR_NO_MORE_AU there are no more access unit in the stream (end of stream) 527 ************************************************************************ 528 */ 529M4OSA_ERR M4READER_PCM_getNextAu(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 530 M4_AccessUnit *pAccessUnit) 531{ 532 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 533 M4OSA_ERR err = M4NO_ERROR; 534 M4SYS_AccessUnit* pAu; 535 536 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, 537 "M4READER_PCM_getNextAu: invalid context"); 538 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 539 "M4READER_PCM_getNextAu: invalid pointer to M4_StreamHandler"); 540 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 541 "M4READER_PCM_getNextAu: invalid pointer to M4_AccessUnit"); 542 543 /* keep trace of the allocated buffers in AU to be able to free them at destroy() 544 but be aware that system is risky and would need upgrade if more than 545 one video and one audio AU is needed */ 546 if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream) 547 { 548 pAu = &pC->m_audioAu; 549 } 550 else 551 { 552 M4OSA_TRACE1_0("M4READER_PCM_getNextAu: passed StreamHandler is not known"); 553 return M4ERR_PARAMETER; 554 } 555 556 if (pAu->dataAddress != M4OSA_NULL) 557 { 558 err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu); 559 if (err != M4NO_ERROR) 560 { 561 M4OSA_TRACE1_0("M4READER_PCM_getNextAu: error when freeing access unit"); 562 return err; 563 } 564 } 565 566 pAu->nbFrag = 0; 567 err = M4PCMR_nextAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu); 568 569 if (err == M4NO_ERROR) 570 { 571 pAccessUnit->m_dataAddress = (M4OSA_MemAddr8)pAu->dataAddress; 572 pAccessUnit->m_size = pAu->size; 573 pAccessUnit->m_CTS = (M4OSA_Double)pAu->CTS; 574 pAccessUnit->m_DTS = (M4OSA_Double)pAu->DTS; 575 pAccessUnit->m_attribute = pAu->attribute; 576 } 577 else 578 { 579 pAccessUnit->m_size=0; 580 } 581 582 return err; 583} 584 585 586/** 587 ************************************************************************ 588 * @brief jump into the stream at the specified time 589 * @note 590 * @param context: (IN) Context of the reader 591 * @param pStreamHandler (IN) the stream handler of the stream to make jump 592 * @param pTime (IN/OUT) IN: the time to jump to (in ms) 593 * OUT: the time to which the stream really jumped 594 * But in this reader, we do not modify the time 595 * @return M4NO_ERROR there is no error 596 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 597 * @return M4ERR_PARAMETER at least one parameter is not properly set 598 * @return M4ERR_ALLOC there is no more memory available 599 * @return M4ERR_BAD_STREAM_ID the streamID does not exist 600 ************************************************************************ 601 */ 602M4OSA_ERR M4READER_PCM_jump(M4OSA_Context context, M4_StreamHandler *pStreamHandler, 603 M4OSA_Int32* pTime) 604{ 605 M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context; 606 M4SYS_StreamID streamIdArray[2]; 607 M4OSA_ERR err; 608 M4SYS_AccessUnit* pAu; 609 M4OSA_Time time64; 610 611 M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_PCM_jump: invalid context"); 612 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 613 "M4READER_PCM_jump: invalid pointer to M4_StreamHandler"); 614 M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER, "M4READER_PCM_jump: invalid time pointer"); 615 616 time64 = (M4OSA_Time)*pTime; 617 618 if (pStreamHandler == pC->m_pAudioStream) 619 { 620 pAu = &pC->m_audioAu; 621 } 622 else 623 { 624 M4OSA_TRACE1_0("M4READER_PCM_jump: passed StreamHandler is not known"); 625 return M4ERR_PARAMETER; 626 } 627 628 if (pAu->dataAddress != M4OSA_NULL) 629 { 630 err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu); 631 if (err != M4NO_ERROR) 632 { 633 M4OSA_TRACE1_0("M4READER_PCM_jump: Error when freeing access unit"); 634 return err; 635 } 636 pAu->dataAddress = M4OSA_NULL; 637 } 638 639 streamIdArray[0] = pStreamHandler->m_streamId; 640 streamIdArray[1] = 0; 641 642 pAu->CTS = time64; 643 pAu->DTS = time64; 644 645 err = M4PCMR_seek(pC->m_coreContext, streamIdArray, time64, M4SYS_kBeginning, &time64); 646 647 *pTime = (M4OSA_Int32)time64; 648 649 return err; 650} 651 652/** 653 ************************************************************************* 654 * @brief Retrieves the generic interfaces implemented by the reader 655 * 656 * @param pMediaType : Pointer on a M4READER_MediaType (allocated by the caller) 657 * that will be filled with the media type supported by this reader 658 * @param pRdrGlobalInterface : Address of a pointer that will be set to the global interface 659 * implemented by this reader. The interface is a structure allocated 660 * by the function and must be un-allocated by the caller. 661 * @param pRdrDataInterface : Address of a pointer that will be set to the data interface 662 * implemented by this reader. The interface is a structure allocated 663 * by the function and must be un-allocated by the caller. 664 * 665 * @returns : M4NO_ERROR if OK 666 * ERR_ALLOC if an allocation failed 667 * ERR_PARAMETER at least one parameter is not properly set (in DEBUG only) 668 ************************************************************************* 669 */ 670M4OSA_ERR M4READER_PCM_getInterfaces(M4READER_MediaType *pMediaType, 671 M4READER_GlobalInterface **pRdrGlobalInterface, 672 M4READER_DataInterface **pRdrDataInterface) 673/************************************************************************/ 674{ 675 M4OSA_DEBUG_IF1((pMediaType == 0), M4ERR_PARAMETER, 676 "M4READER_PCM_getInterfaces: invalid pointer to MediaType passed"); 677 M4OSA_DEBUG_IF1((pRdrGlobalInterface == 0), M4ERR_PARAMETER, 678 "M4READER_PCM_getInterfaces: invalid pointer to M4READER_GlobalInterface"); 679 M4OSA_DEBUG_IF1((pRdrDataInterface == 0), M4ERR_PARAMETER, 680 "M4READER_PCM_getInterfaces: invalid pointer to M4READER_DataInterface"); 681 682 *pRdrGlobalInterface = 683 (M4READER_GlobalInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_GlobalInterface), M4READER_WAV, 684 (M4OSA_Char *)"M4READER_PCM GlobalInterface"); 685 if (M4OSA_NULL == *pRdrGlobalInterface) 686 { 687 return M4ERR_ALLOC; 688 } 689 *pRdrDataInterface = 690 (M4READER_DataInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_DataInterface), M4READER_WAV, 691 (M4OSA_Char *) "M4READER_PCM DataInterface"); 692 if (M4OSA_NULL == *pRdrDataInterface) 693 { 694 free(*pRdrGlobalInterface); 695 return M4ERR_ALLOC; 696 } 697 698 *pMediaType = M4READER_kMediaTypePCM; 699 700 (*pRdrGlobalInterface)->m_pFctCreate = M4READER_PCM_create; 701 (*pRdrGlobalInterface)->m_pFctDestroy = M4READER_PCM_destroy; 702 (*pRdrGlobalInterface)->m_pFctOpen = M4READER_PCM_open; 703 (*pRdrGlobalInterface)->m_pFctClose = M4READER_PCM_close; 704 (*pRdrGlobalInterface)->m_pFctStart = M4OSA_NULL; 705 (*pRdrGlobalInterface)->m_pFctStop = M4OSA_NULL; 706 (*pRdrGlobalInterface)->m_pFctGetOption = M4READER_PCM_getOption; 707 (*pRdrGlobalInterface)->m_pFctSetOption = M4READER_PCM_setOption; 708 (*pRdrGlobalInterface)->m_pFctGetNextStream = M4READER_PCM_getNextStream; 709 (*pRdrGlobalInterface)->m_pFctFillAuStruct = M4READER_PCM_fillAuStruct; 710 (*pRdrGlobalInterface)->m_pFctJump = M4READER_PCM_jump; 711 (*pRdrGlobalInterface)->m_pFctReset = M4READER_PCM_reset; 712 (*pRdrGlobalInterface)->m_pFctGetPrevRapTime = M4OSA_NULL; /*all AUs are RAP*/ 713 714 (*pRdrDataInterface)->m_pFctGetNextAu = M4READER_PCM_getNextAu; 715 716 (*pRdrDataInterface)->m_readerContext = M4OSA_NULL; 717 718 return M4NO_ERROR; 719} 720 721 722