pa_mac_core_blocking.c
来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 507 行 · 第 1/2 页
C
507 行
/* This file contains the implementation * required for blocking I/O. It is separated from pa_mac_core.c simply to ease * development. */#include "pa_mac_core_blocking.h"#include "pa_mac_core_internal.h"#include <assert.h>#ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS# define OSAtomicOr32( a, b ) ( (*(b)) |= (a) )# define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) )#else# include <libkern/OSAtomic.h>#endif/* * This fnuction determines the size of a particular sample format. * if the format is not recognized, this returns zero. */static size_t computeSampleSizeFromFormat( PaSampleFormat format ){ switch( format ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 3; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; }}/* * Functions for initializing, resetting, and destroying BLIO structures. * *//* This should be called with the relevant info when initializing a stream for callback. */PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ){ void *data; int result; /* zeroify things */ bzero( blio, sizeof( PaMacBlio ) ); /* this is redundant, but the buffers are used to check if the bufffers have been initialized, so we do it explicitly. */ blio->inputRingBuffer.buffer = NULL; blio->outputRingBuffer.buffer = NULL; /* initialize simple data */ blio->inputSampleFormat = inputSampleFormat; blio->inputSampleSize = computeSampleSizeFromFormat(inputSampleFormat); blio->outputSampleFormat = outputSampleFormat; blio->outputSampleSize = computeSampleSizeFromFormat(outputSampleFormat); blio->framesPerBuffer = framesPerBuffer; blio->inChan = inChan; blio->outChan = outChan; blio->statusFlags = 0; blio->errors = paNoError;#ifdef PA_MAC_BLIO_MUTEX blio->isInputEmpty = false; blio->isOutputFull = false;#endif /* setup ring buffers */#ifdef PA_MAC_BLIO_MUTEX result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) ); if( result ) goto error; result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) );#endif if( inChan ) { data = calloc( ringBufferSize, blio->inputSampleSize ); if( !data ) { result = paInsufficientMemory; goto error; } assert( 0 == RingBuffer_Init( &blio->inputRingBuffer, ringBufferSize*blio->inputSampleSize, data ) ); } if( outChan ) { data = calloc( ringBufferSize, blio->outputSampleSize ); if( !data ) { result = paInsufficientMemory; goto error; } assert( 0 == RingBuffer_Init( &blio->outputRingBuffer, ringBufferSize*blio->outputSampleSize, data ) ); } result = resetBlioRingBuffers( blio ); if( result ) goto error; return 0; error: destroyBlioRingBuffers( blio ); return result;}#ifdef PA_MAC_BLIO_MUTEXPaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty ){ PaError result = paNoError; if( isEmpty == blio->isInputEmpty ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( result ) goto done; blio->isInputEmpty = isEmpty; result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) ); if( result ) goto done; done: return result;}PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull ){ PaError result = paNoError; if( isFull == blio->isOutputFull ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( result ) goto done; blio->isOutputFull = isFull; result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) ); if( result ) goto done; done: return result;}#endif/* This should be called after stopping or aborting the stream, so that on next start, the buffers will be ready. */PaError resetBlioRingBuffers( PaMacBlio *blio ){#ifdef PA_MAC__BLIO_MUTEX int result;#endif blio->statusFlags = 0; if( blio->outputRingBuffer.buffer ) { RingBuffer_Flush( &blio->outputRingBuffer ); bzero( blio->outputRingBuffer.buffer, blio->outputRingBuffer.bufferSize ); /* Advance buffer */ RingBuffer_AdvanceWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize ); /* Update isOutputFull. */#ifdef PA_MAC__BLIO_MUTEX result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize ); if( result ) goto error;#endif/* printf( "------%d\n" , blio->framesPerBuffer ); printf( "------%d\n" , blio->outChan ); printf( "------%d\n" , blio->outputSampleSize ); printf( "------%d\n" , blio->framesPerBuffer*blio->outChan*blio->outputSampleSize );*/ } if( blio->inputRingBuffer.buffer ) { RingBuffer_Flush( &blio->inputRingBuffer ); bzero( blio->inputRingBuffer.buffer, blio->inputRingBuffer.bufferSize ); /* Update isInputEmpty. */#ifdef PA_MAC__BLIO_MUTEX result = blioSetIsInputEmpty( blio, true ); if( result ) goto error;#endif } return paNoError;#ifdef PA_MAC__BLIO_MUTEX error: return result;#endif}/*This should be called when you are done with the blio. It can safely be called multiple times if there are no exceptions. */PaError destroyBlioRingBuffers( PaMacBlio *blio ){ PaError result = paNoError; if( blio->inputRingBuffer.buffer ) { free( blio->inputRingBuffer.buffer );#ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) ); if( result ) return result;#endif } blio->inputRingBuffer.buffer = NULL; if( blio->outputRingBuffer.buffer ) { free( blio->outputRingBuffer.buffer );#ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) ); if( result ) return result;#endif } blio->outputRingBuffer.buffer = NULL; return result;}/*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?