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 + -
显示快捷键?