pa_mac_core_blocking.c
来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 507 行 · 第 1/2 页
C
507 行
* this is the BlioCallback function. It expects to recieve a PaMacBlio Object * pointer as userData. * */int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ){ PaMacBlio *blio = (PaMacBlio*)userData; long avail; long toRead; long toWrite; /* set flags returned by OS: */ OSAtomicOr32( statusFlags, &blio->statusFlags ) ; /* --- Handle Input Buffer --- */ if( blio->inChan ) { avail = RingBuffer_GetWriteAvailable( &blio->inputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->inputSampleSize * blio->inChan ) OSAtomicOr32( paInputOverflow, &blio->statusFlags ); toRead = MIN( avail, frameCount * blio->inputSampleSize * blio->inChan ); /* copy the data */ /*printf( "reading %d\n", toRead );*/ assert( toRead == RingBuffer_Write( &blio->inputRingBuffer, input, toRead ) );#ifdef PA_MAC__BLIO_MUTEX /* Priority inversion. See notes below. */ blioSetIsInputEmpty( blio, false );#endif } /* --- Handle Output Buffer --- */ if( blio->outChan ) { avail = RingBuffer_GetReadAvailable( &blio->outputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->outputSampleSize * blio->outChan ) OSAtomicOr32( paOutputUnderflow, &blio->statusFlags ); toWrite = MIN( avail, frameCount * blio->outputSampleSize * blio->outChan ); if( toWrite != frameCount * blio->outputSampleSize * blio->outChan ) bzero( ((char *)output)+toWrite, frameCount * blio->outputSampleSize * blio->outChan - toWrite ); /* copy the data */ /*printf( "writing %d\n", toWrite );*/ assert( toWrite == RingBuffer_Read( &blio->outputRingBuffer, output, toWrite ) );#ifdef PA_MAC__BLIO_MUTEX /* We have a priority inversion here. However, we will only have to wait if this was true and is now false, which means we've got some room in the buffer. Hopefully problems will be minimized. */ blioSetIsOutputFull( blio, false );#endif } return paContinue;}PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ){ PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( frames > 0 ) { long avail; long toRead; do { avail = RingBuffer_GetReadAvailable( &blio->inputRingBuffer );/* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, avail, blio->inputRingBuffer.bufferSize );*/ if( avail == 0 ) {#ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret;#else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );#endif } } while( avail == 0 ); toRead = MIN( avail, frames * blio->inputSampleSize * blio->inChan ); toRead -= toRead % blio->inputSampleSize * blio->inChan ; RingBuffer_Read( &blio->inputRingBuffer, (void *)cbuf, toRead ); cbuf += toRead; frames -= toRead / ( blio->inputSampleSize * blio->inChan ); if( toRead == avail ) {#ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ if( RingBuffer_GetReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); if( ret ) return ret; }#endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( ~paInputOverflow, &blio->statusFlags ); ret = paInputOverflowed; } return ret;}PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ){ PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( frames > 0 ) { long avail = 0; long toWrite; do { avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer );/* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, avail, blio->outputRingBuffer.bufferSize );*/ if( avail == 0 ) {#ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret;#else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );#endif } } while( avail == 0 ); toWrite = MIN( avail, frames * blio->outputSampleSize * blio->outChan ); toWrite -= toWrite % blio->outputSampleSize * blio->outChan ; RingBuffer_Write( &blio->outputRingBuffer, (void *)cbuf, toWrite ); cbuf += toWrite; frames -= toWrite / ( blio->outputSampleSize * blio->outChan );#ifdef PA_MAC_BLIO_MUTEX if( toWrite == avail ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); if( ret ) return ret; } }#endif } /* Report either paNoError or paOutputUnderflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( ~paOutputUnderflow, &blio->statusFlags ); ret = paOutputUnderflowed; } return ret;}/* * */void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ){ if( blio->outputRingBuffer.buffer ) { long avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ); while( avail != blio->outputRingBuffer.bufferSize ) { if( avail == 0 ) Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ); } }}signed long GetStreamReadAvailable( PaStream* stream ){ PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamReadAvailable()\n")); return RingBuffer_GetReadAvailable( &blio->inputRingBuffer ) / ( blio->outputSampleSize * blio->outChan );}signed long GetStreamWriteAvailable( PaStream* stream ){ PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamWriteAvailable()\n")); return RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ) / ( blio->outputSampleSize * blio->outChan );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?