From 25c1f56cee55e5ab8d1dd5aee006be2c8be081dc Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 21 Jan 2016 17:28:32 -0800 Subject: [PATCH] Backed out changeset 01c279ae2fb4 (bug 1241476) for various crashes on win xp mentioning "winmm_stream_init" a=backout --HG-- extra : commitid : Cix5ETsOD0B extra : amend_source : 1929a90c36b2f8426bfe9c0815931136acb4c95e --- media/libcubeb/AUTHORS | 7 - media/libcubeb/README_MOZILLA | 2 +- media/libcubeb/include/cubeb.h | 117 +++---- media/libcubeb/src/cubeb-internal.h | 10 +- media/libcubeb/src/cubeb.c | 47 +-- media/libcubeb/src/cubeb_alsa.c | 20 +- media/libcubeb/src/cubeb_audiotrack.c | 23 +- media/libcubeb/src/cubeb_audiounit.c | 20 +- media/libcubeb/src/cubeb_opensl.c | 33 +- media/libcubeb/src/cubeb_pulse.c | 427 ++++++-------------------- media/libcubeb/src/cubeb_sndio.c | 26 +- media/libcubeb/src/cubeb_wasapi.cpp | 20 +- media/libcubeb/src/cubeb_winmm.c | 26 +- media/libcubeb/tests/test_audio.cpp | 12 +- media/libcubeb/tests/test_sanity.cpp | 31 +- media/libcubeb/tests/test_tone.cpp | 8 +- 16 files changed, 217 insertions(+), 612 deletions(-) diff --git a/media/libcubeb/AUTHORS b/media/libcubeb/AUTHORS index 0fde65baad34..394e9ae6768c 100644 --- a/media/libcubeb/AUTHORS +++ b/media/libcubeb/AUTHORS @@ -6,10 +6,3 @@ David Richards Sebastien Alaiwan KO Myung-Hun Haakon Sporsheim -Alex Chronopoulos -Jan Beich -Vito Caputo -Landry Breuil -Jacek Caban -Paul Hancock -Ted Mielczarek diff --git a/media/libcubeb/README_MOZILLA b/media/libcubeb/README_MOZILLA index 106a9f07187e..9f88a9e5384e 100644 --- a/media/libcubeb/README_MOZILLA +++ b/media/libcubeb/README_MOZILLA @@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system. The cubeb git repository is: git://github.com/kinetiknz/cubeb.git -The git commit ID used was b364f9ce2f8f7c392055b94c350ce600892ce7bc. +The git commit ID used was 23a17cb4f9ed2de78a0df5ecdfefbbe47dc83c35. diff --git a/media/libcubeb/include/cubeb.h b/media/libcubeb/include/cubeb.h index f46842f377c9..4c016e0d231e 100644 --- a/media/libcubeb/include/cubeb.h +++ b/media/libcubeb/include/cubeb.h @@ -118,10 +118,6 @@ typedef enum { } cubeb_stream_type; #endif -/** An opaque handle used to refer a particular input or output device - * across calls. */ -typedef void * cubeb_devid; - /** Stream format initialization parameters. */ typedef struct { cubeb_sample_format format; /**< Requested sample format. One of @@ -153,61 +149,41 @@ enum { CUBEB_ERROR = -1, /**< Unclassified error. */ CUBEB_ERROR_INVALID_FORMAT = -2, /**< Unsupported #cubeb_stream_params requested. */ CUBEB_ERROR_INVALID_PARAMETER = -3, /**< Invalid parameter specified. */ - CUBEB_ERROR_NOT_SUPPORTED = -4, /**< Optional function not implemented in current backend. */ - CUBEB_ERROR_DEVICE_UNAVAILABLE = -5 /**< Device specified by #cubeb_devid not available. */ + CUBEB_ERROR_NOT_SUPPORTED = -4 /**< Optional function not implemented in current backend. */ }; -/** - * Whether a particular device is an input device (e.g. a microphone), or an - * output device (e.g. headphones). */ typedef enum { CUBEB_DEVICE_TYPE_UNKNOWN, CUBEB_DEVICE_TYPE_INPUT, CUBEB_DEVICE_TYPE_OUTPUT } cubeb_device_type; -/** - * The state of a device. - */ typedef enum { - CUBEB_DEVICE_STATE_DISABLED, /**< The device has been disabled at the system level. */ - CUBEB_DEVICE_STATE_UNPLUGGED, /**< The device is enabled, but nothing is plugged into it. */ - CUBEB_DEVICE_STATE_ENABLED /**< The device is enabled. */ + CUBEB_DEVICE_STATE_DISABLED, + CUBEB_DEVICE_STATE_UNPLUGGED, + CUBEB_DEVICE_STATE_ENABLED } cubeb_device_state; -/** - * Architecture specific sample type. - */ +typedef void * cubeb_devid; + typedef enum { - CUBEB_DEVICE_FMT_S16LE = 0x0010, /**< 16-bit integers, Little Endian. */ - CUBEB_DEVICE_FMT_S16BE = 0x0020, /**< 16-bit integers, Big Endian. */ - CUBEB_DEVICE_FMT_F32LE = 0x1000, /**< 32-bit floating point, Little Endian. */ - CUBEB_DEVICE_FMT_F32BE = 0x2000 /**< 32-bit floating point, Big Endian. */ + CUBEB_DEVICE_FMT_S16LE = 0x0010, + CUBEB_DEVICE_FMT_S16BE = 0x0020, + CUBEB_DEVICE_FMT_F32LE = 0x1000, + CUBEB_DEVICE_FMT_F32BE = 0x2000 } cubeb_device_fmt; #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) -/** 16-bit integers, native endianess, when on a Big Endian environment. */ #define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16BE -/** 32-bit floating points, native endianess, when on a Big Endian environment. */ #define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32BE #else -/** 16-bit integers, native endianess, when on a Little Endian environment. */ #define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16LE -/** 32-bit floating points, native endianess, when on a Little Endian - * environment. */ #define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32LE #endif -/** All the 16-bit integers types. */ #define CUBEB_DEVICE_FMT_S16_MASK (CUBEB_DEVICE_FMT_S16LE | CUBEB_DEVICE_FMT_S16BE) -/** All the 32-bit floating points types. */ #define CUBEB_DEVICE_FMT_F32_MASK (CUBEB_DEVICE_FMT_F32LE | CUBEB_DEVICE_FMT_F32BE) -/** All the device formats types. */ #define CUBEB_DEVICE_FMT_ALL (CUBEB_DEVICE_FMT_S16_MASK | CUBEB_DEVICE_FMT_F32_MASK) -/** Channel type for a `cubeb_stream`. Depending on the backend and platform - * used, this can control inter-stream interruption, ducking, and volume - * control. - */ typedef enum { CUBEB_DEVICE_PREF_NONE = 0x00, CUBEB_DEVICE_PREF_MULTIMEDIA = 0x01, @@ -216,30 +192,26 @@ typedef enum { CUBEB_DEVICE_PREF_ALL = 0x0F } cubeb_device_pref; -/** This structure holds the characteristics - * of an input or output audio device. It can be obtained using - * `cubeb_enumerate_devices`, and must be destroyed using - * `cubeb_device_info_destroy`. */ typedef struct { - cubeb_devid devid; /**< Device identifier handle. */ - char * device_id; /**< Device identifier which might be presented in a UI. */ - char * friendly_name; /**< Friendly device name which might be presented in a UI. */ - char * group_id; /**< Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */ - char * vendor_name; /**< Optional vendor name, may be NULL. */ + cubeb_devid devid; /* Device identifier handle */ + char * device_id; /* Device identifier which might be presented in a UI */ + char * friendly_name; /* Friendly device name which might be presented in a UI */ + char * group_id; /* Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */ + char * vendor_name; /* Optional vendor name, may be NULL */ - cubeb_device_type type; /**< Type of device (Input/Output). */ - cubeb_device_state state; /**< State of device disabled/enabled/unplugged. */ - cubeb_device_pref preferred;/**< Preferred device. */ + cubeb_device_type type; /* Type of device (Input/Output) */ + cubeb_device_state state; /* State of device disabled/enabled/unplugged */ + cubeb_device_pref preferred;/* Preferred device */ - cubeb_device_fmt format; /**< Sample format supported. */ - cubeb_device_fmt default_format; /**< The default sample format for this device. */ - unsigned int max_channels; /**< Channels. */ - unsigned int default_rate; /**< Default/Preferred sample rate. */ - unsigned int max_rate; /**< Maximum sample rate supported. */ - unsigned int min_rate; /**< Minimum sample rate supported. */ + cubeb_device_fmt format; /* Sample format supported */ + cubeb_device_fmt default_format; + unsigned int max_channels; /* Channels */ + unsigned int default_rate; /* Default/Preferred sample rate */ + unsigned int max_rate; /* Maximum sample rate supported */ + unsigned int min_rate; /* Minimum sample rate supported */ - unsigned int latency_lo_ms; /**< Lowest possible latency in milliseconds. */ - unsigned int latency_hi_ms; /**< Higest possible latency in milliseconds. */ + unsigned int latency_lo_ms; /* Lowest possible latency in milliseconds */ + unsigned int latency_hi_ms; /* Higest possible latency in milliseconds */ } cubeb_device_info; /** Device collection. */ @@ -249,21 +221,17 @@ typedef struct { } cubeb_device_collection; /** User supplied data callback. - @param stream The stream for which this callback fired - @param user_ptr The pointer passed to cubeb_stream_create - @param input_buffer A pointer containing the input data, or nullptr - if this is an output-only stream. - @param output_buffer A pointer containing the output data, or nullptr - if this is an input -only stream. - @param nframes The number of frames of the two buffer. - @retval Number of frames written to the output buffer, which must equal - nframes except at end of stream. + @param stream + @param user_ptr + @param buffer + @param nframes + @retval Number of frames written to buffer, which must equal nframes except + at end of stream. @retval CUBEB_ERROR on error, in which case the data callback will stop and the stream will enter a shutdown state. */ typedef long (* cubeb_data_callback)(cubeb_stream * stream, void * user_ptr, - const void * input_buffer, - void * output_buffer, + void * buffer, long nframes); /** User supplied state callback. @@ -338,14 +306,7 @@ void cubeb_destroy(cubeb * context); @param context @param stream @param stream_name - @param input_device Device for the input side of the stream. If NULL - default input device is used. - @param input_stream_params Parameters for the input side of the stream, or - NULL if this stream is output only. - @param output_device Device for the output side of the stream. If NULL - default output device is used. - @param output_stream_params Parameters for the output side of the stream, or - NULL if this stream is input only. + @param stream_params @param latency Approximate stream latency in milliseconds. Valid range is [1, 2000]. @param data_callback Will be called to preroll data before playback is @@ -354,15 +315,11 @@ void cubeb_destroy(cubeb * context); @param user_ptr @retval CUBEB_OK @retval CUBEB_ERROR - @retval CUBEB_ERROR_INVALID_FORMAT - @retval CUBEB_ERROR_DEVICE_UNAVAILABLE */ + @retval CUBEB_ERROR_INVALID_FORMAT */ int cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, @@ -465,7 +422,7 @@ int cubeb_enumerate_devices(cubeb * context, cubeb_device_type devtype, cubeb_device_collection ** collection); -/** Destroy a cubeb_device_collection, and its `cubeb_device_info`. +/** Destroy a cubeb_device_collection. @param collection collection to destroy @retval CUBEB_OK @retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer */ diff --git a/media/libcubeb/src/cubeb-internal.h b/media/libcubeb/src/cubeb-internal.h index 3a0c1d871169..323510712bbc 100644 --- a/media/libcubeb/src/cubeb-internal.h +++ b/media/libcubeb/src/cubeb-internal.h @@ -22,14 +22,8 @@ struct cubeb_ops { int (* enumerate_devices)(cubeb * context, cubeb_device_type type, cubeb_device_collection ** collection); void (* destroy)(cubeb * context); - int (* stream_init)(cubeb * context, - cubeb_stream ** stream, - char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + int (* stream_init)(cubeb * context, cubeb_stream ** stream, char const * stream_name, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr); diff --git a/media/libcubeb/src/cubeb.c b/media/libcubeb/src/cubeb.c index 5a59dfa28e8e..f22e8a901892 100644 --- a/media/libcubeb/src/cubeb.c +++ b/media/libcubeb/src/cubeb.c @@ -61,36 +61,15 @@ int audiotrack_init(cubeb ** context, char const * context_name); int kai_init(cubeb ** context, char const * context_name); #endif - int -validate_stream_params(cubeb_stream_params * input_stream_params, - cubeb_stream_params * output_stream_params) +validate_stream_params(cubeb_stream_params stream_params) { - if (output_stream_params) { - if (output_stream_params->rate < 1000 || output_stream_params->rate > 192000 || - output_stream_params->channels < 1 || output_stream_params->channels > 8) { - return CUBEB_ERROR_INVALID_FORMAT; - } - } - if (input_stream_params) { - if (input_stream_params->rate < 1000 || input_stream_params->rate > 192000 || - input_stream_params->channels < 1 || input_stream_params->channels > 8) { - return CUBEB_ERROR_INVALID_FORMAT; - } - } - // Rate and sample format must be the same for input and output, if using a - // duplex stream - if (input_stream_params && output_stream_params) { - if (input_stream_params->rate != output_stream_params->rate || - input_stream_params->format != output_stream_params->format) { - return CUBEB_ERROR_INVALID_FORMAT; - } + if (stream_params.rate < 1000 || stream_params.rate > 192000 || + stream_params.channels < 1 || stream_params.channels > 8) { + return CUBEB_ERROR_INVALID_FORMAT; } - cubeb_stream_params * params = input_stream_params ? - input_stream_params : output_stream_params; - - switch (params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: case CUBEB_SAMPLE_S16BE: case CUBEB_SAMPLE_FLOAT32LE: @@ -101,8 +80,6 @@ validate_stream_params(cubeb_stream_params * input_stream_params, return CUBEB_ERROR_INVALID_FORMAT; } - - int validate_latency(int latency) { @@ -241,11 +218,7 @@ cubeb_destroy(cubeb * context) int cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) @@ -256,17 +229,13 @@ cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n return CUBEB_ERROR_INVALID_PARAMETER; } - if ((r = validate_stream_params(input_stream_params, output_stream_params)) != CUBEB_OK || + if ((r = validate_stream_params(stream_params)) != CUBEB_OK || (r = validate_latency(latency)) != CUBEB_OK) { return r; } return context->ops->stream_init(context, stream, stream_name, - input_device, - input_stream_params, - output_device, - output_stream_params, - latency, + stream_params, latency, data_callback, state_callback, user_ptr); diff --git a/media/libcubeb/src/cubeb_alsa.c b/media/libcubeb/src/cubeb_alsa.c index 853216db99b1..5e8dab004eb8 100644 --- a/media/libcubeb/src/cubeb_alsa.c +++ b/media/libcubeb/src/cubeb_alsa.c @@ -306,7 +306,7 @@ alsa_refill_stream(cubeb_stream * stm) assert(p); pthread_mutex_unlock(&stm->mutex); - got = stm->data_callback(stm, stm->user_ptr, NULL, p, avail); + got = stm->data_callback(stm, stm->user_ptr, p, avail); pthread_mutex_lock(&stm->mutex); if (got < 0) { pthread_mutex_unlock(&stm->mutex); @@ -781,11 +781,7 @@ static void alsa_stream_destroy(cubeb_stream * stm); static int alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { @@ -796,15 +792,9 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, assert(ctx && stream); - assert(!input_stream_params && "not supported."); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - *stream = NULL; - switch (output_stream_params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: format = SND_PCM_FORMAT_S16_LE; break; @@ -836,7 +826,7 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; - stm->params = *output_stream_params; + stm->params = stream_params; stm->state = INACTIVE; stm->volume = 1.0; @@ -943,7 +933,7 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels) assert(ctx); - r = alsa_stream_init(ctx, &stm, "", NULL, NULL, NULL, ¶ms, 100, NULL, NULL, NULL); + r = alsa_stream_init(ctx, &stm, "", params, 100, NULL, NULL, NULL); if (r != CUBEB_OK) { return CUBEB_ERROR; } diff --git a/media/libcubeb/src/cubeb_audiotrack.c b/media/libcubeb/src/cubeb_audiotrack.c index e7788a8d7ed5..bf85bb8c07c6 100644 --- a/media/libcubeb/src/cubeb_audiotrack.c +++ b/media/libcubeb/src/cubeb_audiotrack.c @@ -99,11 +99,12 @@ audiotrack_refill(int event, void* user, void* info) return; } - got = stream->data_callback(stream, stream->user_ptr, NULL, b->raw, b->frameCount); + got = stream->data_callback(stream, stream->user_ptr, b->raw, b->frameCount); stream->written += got; if (got != (long)b->frameCount) { + uint32_t p; stream->draining = 1; /* set a marker so we are notified when the are done draining, that is, * when every frame has been played by android. */ @@ -278,11 +279,7 @@ audiotrack_destroy(cubeb * context) int audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) @@ -293,18 +290,12 @@ audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_ assert(ctx && stream); - assert(!input_stream_params && "not supported"); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - - if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE || - output_stream_params->format == CUBEB_SAMPLE_FLOAT32BE) { + if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE || + stream_params.format == CUBEB_SAMPLE_FLOAT32BE) { return CUBEB_ERROR_INVALID_FORMAT; } - if (audiotrack_get_min_frame_count(ctx, output_stream_params, (int *)&min_frame_count)) { + if (audiotrack_get_min_frame_count(ctx, &stream_params, (int *)&min_frame_count)) { return CUBEB_ERROR; } @@ -315,7 +306,7 @@ audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_ stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; - stm->params = *output_stream_params; + stm->params = stream_params; stm->instance = calloc(SIZE_AUDIOTRACK_INSTANCE, 1); (*(uint32_t*)((intptr_t)stm->instance + SIZE_AUDIOTRACK_INSTANCE - 4)) = 0xbaadbaad; diff --git a/media/libcubeb/src/cubeb_audiounit.c b/media/libcubeb/src/cubeb_audiounit.c index 7f3f33356ca9..750610779216 100644 --- a/media/libcubeb/src/cubeb_audiounit.c +++ b/media/libcubeb/src/cubeb_audiounit.c @@ -136,7 +136,7 @@ audiounit_output_callback(void * user_ptr, AudioUnitRenderActionFlags * flags, } pthread_mutex_unlock(&stm->mutex); - got = stm->data_callback(stm, stm->user_ptr, NULL, buf, nframes); + got = stm->data_callback(stm, stm->user_ptr, buf, nframes); pthread_mutex_lock(&stm->mutex); if (got < 0) { /* XXX handle this case. */ @@ -539,11 +539,7 @@ static void audiounit_stream_destroy(cubeb_stream * stm); static int audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { @@ -562,19 +558,13 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre UInt32 size; AudioValueRange latency_range; - assert(!input_stream_params && "not supported"); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - assert(context); *stream = NULL; memset(&ss, 0, sizeof(ss)); ss.mFormatFlags = 0; - switch (output_stream_params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: ss.mBitsPerChannel = 16; ss.mFormatFlags |= kAudioFormatFlagIsSignedInteger; @@ -599,8 +589,8 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre ss.mFormatID = kAudioFormatLinearPCM; ss.mFormatFlags |= kLinearPCMFormatFlagIsPacked; - ss.mSampleRate = output_stream_params->rate; - ss.mChannelsPerFrame = output_stream_params->channels; + ss.mSampleRate = stream_params.rate; + ss.mChannelsPerFrame = stream_params.channels; ss.mBytesPerFrame = (ss.mBitsPerChannel / 8) * ss.mChannelsPerFrame; ss.mFramesPerPacket = 1; diff --git a/media/libcubeb/src/cubeb_opensl.c b/media/libcubeb/src/cubeb_opensl.c index d5ee7569479e..526aef0a4438 100644 --- a/media/libcubeb/src/cubeb_opensl.c +++ b/media/libcubeb/src/cubeb_opensl.c @@ -120,7 +120,7 @@ bufferqueue_callback(SLBufferQueueItf caller, void * user_ptr) pthread_mutex_unlock(&stm->mutex); if (!draining) { - written = cubeb_resampler_fill(stm->resampler, NULL, buf, + written = cubeb_resampler_fill(stm->resampler, buf, stm->queuebuf_len / stm->framesize); if (written < 0 || written * stm->framesize > stm->queuebuf_len) { (*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED); @@ -465,26 +465,17 @@ static void opensl_stream_destroy(cubeb_stream * stm); static int opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { cubeb_stream * stm; assert(ctx); - assert(!input_stream_params && "not supported"); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } *stream = NULL; - if (output_stream_params->channels < 1 || output_stream_params->channels > 32 || + if (stream_params.channels < 1 || stream_params.channels > 32 || latency < 1 || latency > 2000) { return CUBEB_ERROR_INVALID_FORMAT; } @@ -492,16 +483,16 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name SLDataFormat_PCM format; format.formatType = SL_DATAFORMAT_PCM; - format.numChannels = output_stream_params->channels; + format.numChannels = stream_params.channels; // samplesPerSec is in milliHertz - format.samplesPerSec = output_stream_params->rate * 1000; + format.samplesPerSec = stream_params.rate * 1000; format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; format.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; - format.channelMask = output_stream_params->channels == 1 ? + format.channelMask = stream_params.channels == 1 ? SL_SPEAKER_FRONT_CENTER : SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - switch (output_stream_params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: format.endianness = SL_BYTEORDER_LITTLEENDIAN; break; @@ -520,10 +511,10 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name stm->state_callback = state_callback; stm->user_ptr = user_ptr; - stm->inputrate = output_stream_params->rate; + stm->inputrate = stream_params.rate; stm->latency = latency; - stm->stream_type = output_stream_params->stream_type; - stm->framesize = output_stream_params->channels * sizeof(int16_t); + stm->stream_type = stream_params.stream_type; + stm->framesize = stream_params.channels * sizeof(int16_t); stm->lastPosition = -1; stm->lastPositionTimeStamp = 0; stm->lastCompensativePosition = -1; @@ -584,7 +575,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name stm->queuebuf_len += stm->framesize - (stm->queuebuf_len % stm->framesize); } - stm->resampler = cubeb_resampler_create(stm, *output_stream_params, + stm->resampler = cubeb_resampler_create(stm, stream_params, preferred_sampling_rate, data_callback, stm->queuebuf_len / stm->framesize, @@ -603,7 +594,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name } #if defined(__ANDROID__) - SLuint32 stream_type = convert_stream_type_to_sl_stream(output_stream_params->stream_type); + SLuint32 stream_type = convert_stream_type_to_sl_stream(stream_params.stream_type); if (stream_type != 0xFFFFFFFF) { SLAndroidConfigurationItf playerConfig; res = (*stm->playerObj)->GetInterface(stm->playerObj, diff --git a/media/libcubeb/src/cubeb_pulse.c b/media/libcubeb/src/cubeb_pulse.c index febb8270fc45..ef356617573a 100644 --- a/media/libcubeb/src/cubeb_pulse.c +++ b/media/libcubeb/src/cubeb_pulse.c @@ -70,27 +70,12 @@ X(pa_threaded_mainloop_unlock) \ X(pa_threaded_mainloop_wait) \ X(pa_usec_to_bytes) \ - X(pa_stream_set_read_callback) \ - X(pa_stream_connect_record) \ - X(pa_stream_readable_size) \ - X(pa_stream_peek) \ - X(pa_stream_drop) \ - X(pa_stream_get_buffer_attr) \ #define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x; LIBPULSE_API_VISIT(MAKE_TYPEDEF); #undef MAKE_TYPEDEF #endif -//#define LOGGING_ENABLED -#ifdef LOGGING_ENABLED -#define LOG(...) do { \ - fprintf(stderr, __VA_ARGS__); \ - } while(0) -#else -#define LOG(...) -#endif - static struct cubeb_ops const pulse_ops; struct cubeb { @@ -105,14 +90,12 @@ struct cubeb { struct cubeb_stream { cubeb * context; - pa_stream * output_stream; - pa_stream * input_stream; + pa_stream * stream; cubeb_data_callback data_callback; cubeb_state_callback state_callback; void * user_ptr; pa_time_event * drain_timer; - pa_sample_spec output_sample_spec; - pa_sample_spec input_sample_spec; + pa_sample_spec sample_spec; int shutdown; float volume; }; @@ -130,7 +113,6 @@ sink_info_callback(pa_context * context, const pa_sink_info * info, int eol, voi { cubeb * ctx = u; if (!eol) { - free(ctx->default_sink_info); ctx->default_sink_info = malloc(sizeof(pa_sink_info)); memcpy(ctx->default_sink_info, info, sizeof(pa_sink_info)); } @@ -188,46 +170,46 @@ stream_state_callback(pa_stream * s, void * u) } static void -trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes, cubeb_stream * stm) +stream_request_callback(pa_stream * s, size_t nbytes, void * u) { + cubeb_stream * stm; void * buffer; size_t size; int r; long got; - size_t towrite, read_offset; + size_t towrite; size_t frame_size; - frame_size = WRAP(pa_frame_size)(&stm->output_sample_spec); + stm = u; + + if (stm->shutdown) + return; + + frame_size = WRAP(pa_frame_size)(&stm->sample_spec); + assert(nbytes % frame_size == 0); towrite = nbytes; - read_offset = 0; + while (towrite) { size = towrite; r = WRAP(pa_stream_begin_write)(s, &buffer, &size); - // Note: this has failed running under rr on occassion - needs investigation. assert(r == 0); assert(size > 0); assert(size % frame_size == 0); - LOG("Trigger user callback with output buffer size=%zd, read_offset=%zd\n", size, read_offset); - got = stm->data_callback(stm, stm->user_ptr, (uint8_t const *)input_data + read_offset, buffer, size / frame_size); + got = stm->data_callback(stm, stm->user_ptr, buffer, size / frame_size); if (got < 0) { WRAP(pa_stream_cancel_write)(s); stm->shutdown = 1; return; } - // If more iterations move offset of read buffer - if (input_data) { - size_t in_frame_size = WRAP(pa_frame_size)(&stm->input_sample_spec); - read_offset += (size / frame_size) * in_frame_size; - } if (stm->volume != PULSE_NO_GAIN) { - uint32_t samples = size * stm->output_sample_spec.channels / frame_size ; + uint32_t samples = size * stm->sample_spec.channels / frame_size ; - if (stm->output_sample_spec.format == PA_SAMPLE_S16BE || - stm->output_sample_spec.format == PA_SAMPLE_S16LE) { + if (stm->sample_spec.format == PA_SAMPLE_S16BE || + stm->sample_spec.format == PA_SAMPLE_S16LE) { short * b = buffer; for (uint32_t i = 0; i < samples; i++) { b[i] *= stm->volume; @@ -264,81 +246,6 @@ trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes, cub assert(towrite == 0); } -static int -read_from_input(pa_stream * s, void const ** buffer, size_t * size) -{ - size_t readable_size = WRAP(pa_stream_readable_size)(s); - if (readable_size > 0) { - if (WRAP(pa_stream_peek)(s, buffer, size) < 0) { - return -1; - } - } - return readable_size; -} - -static void -stream_write_callback(pa_stream * s, size_t nbytes, void * u) -{ - LOG("Output callback to be written buffer size %zd\n", nbytes); - cubeb_stream * stm = u; - if (stm->shutdown) { - return; - } - - if (!stm->input_stream){ - // Output/playback only operation. - // Write directly to output - assert(!stm->input_stream && stm->output_stream); - trigger_user_callback(s, NULL, nbytes, stm); - } -} - -static void -stream_read_callback(pa_stream * s, size_t nbytes, void * u) -{ - LOG("Input callback buffer size %zd\n", nbytes); - cubeb_stream * stm = u; - if (stm->shutdown) { - return; - } - - // Note: this has failed running under rr on occassion - needs investigation. - assert(stm->input_stream && stm->input_sample_spec.rate != 0); - - void const * read_data = NULL; - size_t read_size; - while (read_from_input(s, &read_data, &read_size) > 0) { - /* read_data can be NULL in case of a hole. */ - if (read_data) { - size_t in_frame_size = WRAP(pa_frame_size)(&stm->input_sample_spec); - size_t read_frames = read_size / in_frame_size; - - if (stm->output_stream) { - // input/capture + output/playback operation - size_t out_frame_size = WRAP(pa_frame_size)(&stm->output_sample_spec); - size_t write_size = read_frames * out_frame_size; - // Offer full duplex data for writing - trigger_user_callback(stm->output_stream, read_data, write_size, stm); - } else { - // input/capture only operation. Call callback directly - long got = stm->data_callback(stm, stm->user_ptr, read_data, NULL, read_frames); - if (got < 0 || (size_t) got != read_frames) { - WRAP(pa_stream_cancel_write)(s); - stm->shutdown = 1; - break; - } - } - } - if (read_size > 0) { - WRAP(pa_stream_drop)(s); - } - - if (stm->shutdown) { - return; - } - } -} - static int wait_until_context_ready(cubeb * ctx) { @@ -354,32 +261,15 @@ wait_until_context_ready(cubeb * ctx) } static int -wait_until_io_stream_ready(pa_stream * stream, pa_threaded_mainloop * mainloop) +wait_until_stream_ready(cubeb_stream * stm) { - if (!stream || !mainloop){ - return -1; - } for (;;) { - pa_stream_state_t state = WRAP(pa_stream_get_state)(stream); + pa_stream_state_t state = WRAP(pa_stream_get_state)(stm->stream); if (!PA_STREAM_IS_GOOD(state)) return -1; if (state == PA_STREAM_READY) break; - WRAP(pa_threaded_mainloop_wait)(mainloop); - } - return 0; -} - -static int -wait_until_stream_ready(cubeb_stream * stm) -{ - if (stm->output_stream && - wait_until_io_stream_ready(stm->output_stream, stm->context->mainloop) == -1) { - return -1; - } - if(stm->input_stream && - wait_until_io_stream_ready(stm->input_stream, stm->context->mainloop) == -1) { - return -1; + WRAP(pa_threaded_mainloop_wait)(stm->context->mainloop); } return 0; } @@ -399,26 +289,17 @@ operation_wait(cubeb * ctx, pa_stream * stream, pa_operation * o) return 0; } -static void -cork_io_stream(cubeb_stream * stm, pa_stream * io_stream, enum cork_state state) -{ - pa_operation * o; - if (!io_stream) { - return; - } - o = WRAP(pa_stream_cork)(io_stream, state & CORK, stream_success_callback, stm); - if (o) { - operation_wait(stm->context, io_stream, o); - WRAP(pa_operation_unref)(o); - } -} - static void stream_cork(cubeb_stream * stm, enum cork_state state) { + pa_operation * o; + WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); - cork_io_stream(stm, stm->output_stream, state); - cork_io_stream(stm, stm->input_stream, state); + o = WRAP(pa_stream_cork)(stm->stream, state & CORK, stream_success_callback, stm); + if (o) { + operation_wait(stm->context, stm->stream, o); + WRAP(pa_operation_unref)(o); + } WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); if (state & NOTIFY) { @@ -427,33 +308,6 @@ stream_cork(cubeb_stream * stm, enum cork_state state) } } -static int -stream_update_timing_info(cubeb_stream * stm) -{ - int r = -1; - pa_operation * o = NULL; - if (stm->output_stream) { - o = WRAP(pa_stream_update_timing_info)(stm->output_stream, stream_success_callback, stm); - if (o) { - r = operation_wait(stm->context, stm->output_stream, o); - WRAP(pa_operation_unref)(o); - } - if (r != 0) { - return r; - } - } - - if (stm->input_stream) { - o = WRAP(pa_stream_update_timing_info)(stm->input_stream, stream_success_callback, stm); - if (o) { - r = operation_wait(stm->context, stm->input_stream, o); - WRAP(pa_operation_unref)(o); - } - } - - return r; -} - static void pulse_context_destroy(cubeb * ctx); static void pulse_destroy(cubeb * ctx); @@ -631,145 +485,88 @@ pulse_destroy(cubeb * ctx) static void pulse_stream_destroy(cubeb_stream * stm); -pa_sample_format_t -cubeb_to_pulse_format(cubeb_sample_format format) -{ - switch (format) { - case CUBEB_SAMPLE_S16LE: - return PA_SAMPLE_S16LE; - case CUBEB_SAMPLE_S16BE: - return PA_SAMPLE_S16BE; - case CUBEB_SAMPLE_FLOAT32LE: - return PA_SAMPLE_FLOAT32LE; - case CUBEB_SAMPLE_FLOAT32BE: - return PA_SAMPLE_FLOAT32BE; - default: - return PA_SAMPLE_INVALID; - } -} - static int -create_pa_stream(cubeb_stream * stm, - pa_stream ** pa_stm, - cubeb_stream_params * stream_params, - char const * stream_name) -{ - assert(stm && stream_params); - *pa_stm = NULL; - pa_sample_spec ss; - ss.format = cubeb_to_pulse_format(stream_params->format); - if (ss.format == PA_SAMPLE_INVALID) - return CUBEB_ERROR_INVALID_FORMAT; - ss.rate = stream_params->rate; - ss.channels = stream_params->channels; - - *pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, NULL); - return (*pa_stm == NULL) ? CUBEB_ERROR : CUBEB_OK; -} - -static pa_buffer_attr -set_buffering_attribute(unsigned int latency, pa_sample_spec * sample_spec) -{ - pa_buffer_attr battr; - battr.maxlength = -1; - battr.prebuf = -1; - battr.tlength = WRAP(pa_usec_to_bytes)(latency * PA_USEC_PER_MSEC, sample_spec); - battr.minreq = battr.tlength / 4; - battr.fragsize = battr.minreq; - - LOG("Requested buffer attributes maxlength %u, tlength %u, prebuf %u, minreq %u, fragsize %u\n", - battr.maxlength, battr.tlength, battr.prebuf, battr.minreq, battr.fragsize); - - return battr; -} - -static int -pulse_stream_init(cubeb * context, - cubeb_stream ** stream, - char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, - cubeb_data_callback data_callback, - cubeb_state_callback state_callback, +pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, + cubeb_stream_params stream_params, unsigned int latency, + cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { + pa_sample_spec ss; cubeb_stream * stm; + pa_operation * o; pa_buffer_attr battr; int r; assert(context); + *stream = NULL; + + switch (stream_params.format) { + case CUBEB_SAMPLE_S16LE: + ss.format = PA_SAMPLE_S16LE; + break; + case CUBEB_SAMPLE_S16BE: + ss.format = PA_SAMPLE_S16BE; + break; + case CUBEB_SAMPLE_FLOAT32LE: + ss.format = PA_SAMPLE_FLOAT32LE; + break; + case CUBEB_SAMPLE_FLOAT32BE: + ss.format = PA_SAMPLE_FLOAT32BE; + break; + default: + return CUBEB_ERROR_INVALID_FORMAT; + } + // If the connection failed for some reason, try to reconnect if (context->error == 1 && pulse_context_init(context) != 0) { return CUBEB_ERROR; } - *stream = NULL; + ss.rate = stream_params.rate; + ss.channels = stream_params.channels; stm = calloc(1, sizeof(*stm)); assert(stm); stm->context = context; + stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; + + stm->sample_spec = ss; stm->volume = PULSE_NO_GAIN; + battr.maxlength = -1; + battr.tlength = WRAP(pa_usec_to_bytes)(latency * PA_USEC_PER_MSEC, &stm->sample_spec); + battr.prebuf = -1; + battr.minreq = battr.tlength / 4; + battr.fragsize = -1; + WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); - if (output_stream_params) { - r = create_pa_stream(stm, &stm->output_stream, output_stream_params, stream_name); - if (r != CUBEB_OK) { - WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); - pulse_stream_destroy(stm); - return r; - } - - stm->output_sample_spec = *(WRAP(pa_stream_get_sample_spec)(stm->output_stream)); - - WRAP(pa_stream_set_state_callback)(stm->output_stream, stream_state_callback, stm); - WRAP(pa_stream_set_write_callback)(stm->output_stream, stream_write_callback, stm); - - battr = set_buffering_attribute(latency, &stm->output_sample_spec); - WRAP(pa_stream_connect_playback)(stm->output_stream, - output_device, - &battr, - PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING | - PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY, - NULL, NULL); + stm->stream = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, NULL); + if (!stm->stream) { + pulse_stream_destroy(stm); + return CUBEB_ERROR; } - - // Set up input stream - if (input_stream_params) { - r = create_pa_stream(stm, &stm->input_stream, input_stream_params, stream_name); - if (r != CUBEB_OK) { - WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); - pulse_stream_destroy(stm); - return r; - } - - stm->input_sample_spec = *(WRAP(pa_stream_get_sample_spec)(stm->input_stream)); - - WRAP(pa_stream_set_state_callback)(stm->input_stream, stream_state_callback, stm); - WRAP(pa_stream_set_read_callback)(stm->input_stream, stream_read_callback, stm); - - battr = set_buffering_attribute(latency, &stm->input_sample_spec); - WRAP(pa_stream_connect_record)(stm->input_stream, - input_device, - &battr, + WRAP(pa_stream_set_state_callback)(stm->stream, stream_state_callback, stm); + WRAP(pa_stream_set_write_callback)(stm->stream, stream_request_callback, stm); + WRAP(pa_stream_connect_playback)(stm->stream, NULL, &battr, PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING | - PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY); - } + PA_STREAM_START_CORKED, + NULL, NULL); r = wait_until_stream_ready(stm); if (r == 0) { /* force a timing update now, otherwise timing info does not become valid until some point after initialization has completed. */ - r = stream_update_timing_info(stm); + o = WRAP(pa_stream_update_timing_info)(stm->stream, stream_success_callback, stm); + if (o) { + r = operation_wait(stm->context, stm->stream, o); + WRAP(pa_operation_unref)(o); + } } - WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); if (r != 0) { @@ -777,22 +574,6 @@ pulse_stream_init(cubeb * context, return CUBEB_ERROR; } -#ifdef LOGGING_ENABLED - if (output_stream_params){ - const pa_buffer_attr * output_att; - output_att = WRAP(pa_stream_get_buffer_attr)(stm->output_stream); - LOG("Output buffer attributes maxlength %u, tlength %u, prebuf %u, minreq %u, fragsize %u\n",output_att->maxlength, output_att->tlength, - output_att->prebuf, output_att->minreq, output_att->fragsize); - } - - if (input_stream_params){ - const pa_buffer_attr * input_att; - input_att = WRAP(pa_stream_get_buffer_attr)(stm->input_stream); - LOG("Input buffer attributes maxlength %u, tlength %u, prebuf %u, minreq %u, fragsize %u\n",input_att->maxlength, input_att->tlength, - input_att->prebuf, input_att->minreq, input_att->fragsize); - } -#endif - *stream = stm; return CUBEB_OK; @@ -801,28 +582,22 @@ pulse_stream_init(cubeb * context, static void pulse_stream_destroy(cubeb_stream * stm) { - stream_cork(stm, CORK); + if (stm->stream) { + stream_cork(stm, CORK); - WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); - if (stm->output_stream) { + WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); if (stm->drain_timer) { /* there's no pa_rttime_free, so use this instead. */ WRAP(pa_threaded_mainloop_get_api)(stm->context->mainloop)->time_free(stm->drain_timer); } - WRAP(pa_stream_set_state_callback)(stm->output_stream, NULL, NULL); - WRAP(pa_stream_disconnect)(stm->output_stream); - WRAP(pa_stream_unref)(stm->output_stream); + WRAP(pa_stream_set_state_callback)(stm->stream, NULL, NULL); + WRAP(pa_stream_disconnect)(stm->stream); + WRAP(pa_stream_unref)(stm->stream); + WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); } - if (stm->input_stream) { - WRAP(pa_stream_set_state_callback)(stm->input_stream, NULL, NULL); - WRAP(pa_stream_disconnect)(stm->input_stream); - WRAP(pa_stream_unref)(stm->input_stream); - } - WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); - free(stm); } @@ -847,16 +622,12 @@ pulse_stream_get_position(cubeb_stream * stm, uint64_t * position) pa_usec_t r_usec; uint64_t bytes; - if (!stm || !stm->output_stream) { - return CUBEB_ERROR; - } - in_thread = WRAP(pa_threaded_mainloop_in_thread)(stm->context->mainloop); if (!in_thread) { WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); } - r = WRAP(pa_stream_get_time)(stm->output_stream, &r_usec); + r = WRAP(pa_stream_get_time)(stm->stream, &r_usec); if (!in_thread) { WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop); } @@ -865,8 +636,8 @@ pulse_stream_get_position(cubeb_stream * stm, uint64_t * position) return CUBEB_ERROR; } - bytes = WRAP(pa_usec_to_bytes)(r_usec, &stm->output_sample_spec); - *position = bytes / WRAP(pa_frame_size)(&stm->output_sample_spec); + bytes = WRAP(pa_usec_to_bytes)(r_usec, &stm->sample_spec); + *position = bytes / WRAP(pa_frame_size)(&stm->sample_spec); return CUBEB_OK; } @@ -877,17 +648,17 @@ pulse_stream_get_latency(cubeb_stream * stm, uint32_t * latency) pa_usec_t r_usec; int negative, r; - if (!stm || !stm->output_stream) { + if (!stm) { return CUBEB_ERROR; } - r = WRAP(pa_stream_get_latency)(stm->output_stream, &r_usec, &negative); + r = WRAP(pa_stream_get_latency)(stm->stream, &r_usec, &negative); assert(!negative); if (r) { return CUBEB_ERROR; } - *latency = r_usec * stm->output_sample_spec.rate / PA_USEC_PER_SEC; + *latency = r_usec * stm->sample_spec.rate / PA_USEC_PER_SEC; return CUBEB_OK; } @@ -907,10 +678,6 @@ pulse_stream_set_volume(cubeb_stream * stm, float volume) pa_cvolume cvol; const pa_sample_spec * ss; - if (!stm->output_stream) { - return CUBEB_ERROR; - } - WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop); while (!stm->context->default_sink_info) { @@ -922,18 +689,18 @@ pulse_stream_set_volume(cubeb_stream * stm, float volume) if (stm->context->default_sink_info->flags & PA_SINK_FLAT_VOLUME) { stm->volume = volume; } else { - ss = WRAP(pa_stream_get_sample_spec)(stm->output_stream); + ss = WRAP(pa_stream_get_sample_spec)(stm->stream); vol = WRAP(pa_sw_volume_from_linear)(volume); WRAP(pa_cvolume_set)(&cvol, ss->channels, vol); - index = WRAP(pa_stream_get_index)(stm->output_stream); + index = WRAP(pa_stream_get_index)(stm->stream); op = WRAP(pa_context_set_sink_input_volume)(stm->context->context, index, &cvol, volume_success, stm); if (op) { - operation_wait(stm->context, stm->output_stream, op); + operation_wait(stm->context, stm->stream, op); WRAP(pa_operation_unref)(op); } } @@ -949,11 +716,7 @@ pulse_stream_set_panning(cubeb_stream * stream, float panning) const pa_channel_map * map; pa_cvolume vol; - if (!stream->output_stream) { - return CUBEB_ERROR; - } - - map = WRAP(pa_stream_get_channel_map)(stream->output_stream); + map = WRAP(pa_stream_get_channel_map)(stream->stream); if (!WRAP(pa_channel_map_can_balance)(map)) { return CUBEB_ERROR; @@ -1163,13 +926,11 @@ pulse_enumerate_devices(cubeb * context, cubeb_device_type type, } *collection = malloc(sizeof(cubeb_device_collection) + - sizeof(cubeb_device_info *) * (user_data.count > 0 ? user_data.count - 1 : 0)); + sizeof(cubeb_device_info*) * (user_data.count > 0 ? user_data.count - 1 : 0)); (*collection)->count = user_data.count; for (i = 0; i < user_data.count; i++) (*collection)->device[i] = user_data.devinfo[i]; - free(user_data.default_sink_name); - free(user_data.default_source_name); free(user_data.devinfo); return CUBEB_OK; } diff --git a/media/libcubeb/src/cubeb_sndio.c b/media/libcubeb/src/cubeb_sndio.c index 66e5838ec805..94f9961735fa 100644 --- a/media/libcubeb/src/cubeb_sndio.c +++ b/media/libcubeb/src/cubeb_sndio.c @@ -170,14 +170,10 @@ sndio_destroy(cubeb *context) } static int -sndio_stream_init(cubeb * context, - cubeb_stream ** stream, - char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, +sndio_stream_init(cubeb *context, + cubeb_stream **stream, + char const *stream_name, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void *user_ptr) @@ -187,12 +183,6 @@ sndio_stream_init(cubeb * context, DPR("sndio_stream_init(%s)\n", stream_name); size_t size; - assert(!input_stream_params && "not supported."); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - s = malloc(sizeof(cubeb_stream)); if (s == NULL) return CUBEB_ERROR; @@ -206,7 +196,7 @@ sndio_stream_init(cubeb * context, sio_initpar(&wpar); wpar.sig = 1; wpar.bits = 16; - switch (output_stream_params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: wpar.le = 1; break; @@ -220,8 +210,8 @@ sndio_stream_init(cubeb * context, DPR("sndio_stream_init() unsupported format\n"); return CUBEB_ERROR_INVALID_FORMAT; } - wpar.rate = output_stream_params->rate; - wpar.pchan = output_stream_params->channels; + wpar.rate = stream_params.rate; + wpar.pchan = stream_params.channels; wpar.appbufsz = latency * wpar.rate / 1000; if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) { sio_close(s->hdl); @@ -247,7 +237,7 @@ sndio_stream_init(cubeb * context, s->arg = user_ptr; s->mtx = PTHREAD_MUTEX_INITIALIZER; s->rdpos = s->wrpos = 0; - if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE) { + if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE) { s->conv = 1; size = rpar.round * rpar.pchan * sizeof(float); } else { diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp index 852aca51ecab..3c780e6801ca 100644 --- a/media/libcubeb/src/cubeb_wasapi.cpp +++ b/media/libcubeb/src/cubeb_wasapi.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2013 Mozilla Foundation + * Copyright © 2013 Mozilla Foundation * * This program is made available under an ISC-style license. See the * accompanying file LICENSE for details. @@ -472,7 +472,7 @@ refill(cubeb_stream * stm, float * data, long frames_needed) dest = data; } - long out_frames = cubeb_resampler_fill(stm->resampler, NULL, dest, frames_needed); + long out_frames = cubeb_resampler_fill(stm->resampler, dest, frames_needed); /* TODO: Report out_frames < 0 as an error via the API. */ XASSERT(out_frames >= 0); @@ -1201,11 +1201,7 @@ int setup_wasapi_stream(cubeb_stream * stm) int wasapi_stream_init(cubeb * context, cubeb_stream ** stream, - char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, + char const * stream_name, cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { @@ -1216,15 +1212,9 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, return CUBEB_ERROR; } - XASSERT(!input_stream_params && "not supported."); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - XASSERT(context && stream); - if (output_stream_params->format != CUBEB_SAMPLE_FLOAT32NE) { + if (stream_params.format != CUBEB_SAMPLE_FLOAT32NE) { return CUBEB_ERROR_INVALID_FORMAT; } @@ -1236,7 +1226,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; - stm->stream_params = *output_stream_params; + stm->stream_params = stream_params; stm->draining = false; stm->latency = latency; stm->volume = 1.0; diff --git a/media/libcubeb/src/cubeb_winmm.c b/media/libcubeb/src/cubeb_winmm.c index 19b3e0d4b531..da5828f1d45b 100644 --- a/media/libcubeb/src/cubeb_winmm.c +++ b/media/libcubeb/src/cubeb_winmm.c @@ -179,7 +179,7 @@ winmm_refill_stream(cubeb_stream * stm) /* It is assumed that the caller is holding this lock. It must be dropped during the callback to avoid deadlocks. */ LeaveCriticalSection(&stm->lock); - got = stm->data_callback(stm, stm->user_ptr, NULL, hdr->lpData, wanted); + got = stm->data_callback(stm, stm->user_ptr, hdr->lpData, wanted); EnterCriticalSection(&stm->lock); if (got < 0) { LeaveCriticalSection(&stm->lock); @@ -380,11 +380,7 @@ static void winmm_stream_destroy(cubeb_stream * stm); static int winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, - cubeb_devid input_device, - cubeb_stream_params * input_stream_params, - cubeb_devid output_device, - cubeb_stream_params * output_stream_params, - unsigned int latency, + cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) @@ -398,32 +394,26 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n XASSERT(context); XASSERT(stream); - XASSERT(input_stream_params && "not supported."); - if (input_device || output_device) { - /* Device selection not yet implemented. */ - return CUBEB_ERROR_DEVICE_UNAVAILABLE; - } - *stream = NULL; memset(&wfx, 0, sizeof(wfx)); - if (output_stream_params->channels > 2) { + if (stream_params.channels > 2) { wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.cbSize = sizeof(wfx) - sizeof(wfx.Format); } else { wfx.Format.wFormatTag = WAVE_FORMAT_PCM; - if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE) { + if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE) { wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } wfx.Format.cbSize = 0; } - wfx.Format.nChannels = output_stream_params->channels; - wfx.Format.nSamplesPerSec = output_stream_params->rate; + wfx.Format.nChannels = stream_params.channels; + wfx.Format.nSamplesPerSec = stream_params.rate; /* XXX fix channel mappings */ wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; - switch (output_stream_params->format) { + switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: wfx.Format.wBitsPerSample = 16; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; @@ -456,7 +446,7 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n stm->context = context; - stm->params = *output_stream_params; + stm->params = stream_params; stm->data_callback = data_callback; stm->state_callback = state_callback; diff --git a/media/libcubeb/tests/test_audio.cpp b/media/libcubeb/tests/test_audio.cpp index 7a8adf66f611..6a6ebf53caaa 100644 --- a/media/libcubeb/tests/test_audio.cpp +++ b/media/libcubeb/tests/test_audio.cpp @@ -73,10 +73,10 @@ void synth_run_float(synth_state* synth, float* audiobuffer, long nframes) } } -long data_cb_float(cubeb_stream *stream, void *user, const void * inputbuffer, void *outputbuffer, long nframes) +long data_cb_float(cubeb_stream *stream, void *user, void *buffer, long nframes) { synth_state *synth = (synth_state *)user; - synth_run_float(synth, (float*)outputbuffer, nframes); + synth_run_float(synth, (float*)buffer, nframes); return nframes; } @@ -92,10 +92,10 @@ void synth_run_16bit(synth_state* synth, short* audiobuffer, long nframes) } } -long data_cb_short(cubeb_stream *stream, void *user, const void * inputbuffer, void *outputbuffer, long nframes) +long data_cb_short(cubeb_stream *stream, void *user, void *buffer, long nframes) { synth_state *synth = (synth_state *)user; - synth_run_16bit(synth, (short*)outputbuffer, nframes); + synth_run_16bit(synth, (short*)buffer, nframes); return nframes; } @@ -160,7 +160,7 @@ int run_test(int num_channels, int sampling_rate, int is_float) goto cleanup; } - r = cubeb_stream_init(ctx, &stream, "test tone", NULL, NULL, NULL, ¶ms, + r = cubeb_stream_init(ctx, &stream, "test tone", params, 100, is_float ? data_cb_float : data_cb_short, state_cb, synth); if (r != CUBEB_OK) { fprintf(stderr, "Error initializing cubeb stream: %d\n", r); @@ -212,7 +212,7 @@ int run_panning_volume_test(int is_float) goto cleanup; } - r = cubeb_stream_init(ctx, &stream, "test tone", NULL, NULL, NULL, ¶ms, + r = cubeb_stream_init(ctx, &stream, "test tone", params, 100, is_float ? data_cb_float : data_cb_short, state_cb, synth); if (r != CUBEB_OK) { fprintf(stderr, "Error initializing cubeb stream: %d\n", r); diff --git a/media/libcubeb/tests/test_sanity.cpp b/media/libcubeb/tests/test_sanity.cpp index b09a4f955685..ca9ca1bf1b6f 100644 --- a/media/libcubeb/tests/test_sanity.cpp +++ b/media/libcubeb/tests/test_sanity.cpp @@ -40,14 +40,13 @@ static uint64_t total_frames_written; static int delay_callback; static long -test_data_callback(cubeb_stream * stm, void * user_ptr, const void * inputbuffer, void * outputbuffer, long nframes) +test_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes) { - assert(stm && user_ptr == &dummy && outputbuffer && nframes > 0); - memset(outputbuffer, 0, nframes * sizeof(short)); + assert(stm && user_ptr == &dummy && p && nframes > 0); #if (defined(_WIN32) || defined(__WIN32__)) - memset(outputbuffer, 0, nframes * sizeof(float)); + memset(p, 0, nframes * sizeof(float)); #else - memset(outputbuffer, 0, nframes * sizeof(short)); + memset(p, 0, nframes * sizeof(short)); #endif total_frames_written += nframes; @@ -159,7 +158,7 @@ test_init_destroy_stream(void) params.rate = STREAM_RATE; params.channels = STREAM_CHANNELS; - r = cubeb_stream_init(ctx, &stream, "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0 && stream); @@ -188,7 +187,7 @@ test_init_destroy_multiple_streams(void) params.channels = STREAM_CHANNELS; for (i = 0; i < ARRAY_LENGTH(stream); ++i) { - r = cubeb_stream_init(ctx, &stream[i], "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0); assert(stream[i]); @@ -220,7 +219,7 @@ test_configure_stream(void) params.rate = STREAM_RATE; params.channels = 2; // panning - r = cubeb_stream_init(ctx, &stream, "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0 && stream); @@ -254,7 +253,7 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms) params.channels = STREAM_CHANNELS; for (i = 0; i < ARRAY_LENGTH(stream); ++i) { - r = cubeb_stream_init(ctx, &stream[i], "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0); assert(stream[i]); @@ -318,7 +317,7 @@ test_init_destroy_multiple_contexts_and_streams(void) assert(r == 0 && ctx[i]); for (j = 0; j < streams_per_ctx; ++j) { - r = cubeb_stream_init(ctx[i], &stream[i * streams_per_ctx + j], "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx[i], &stream[i * streams_per_ctx + j], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0); assert(stream[i * streams_per_ctx + j]); @@ -353,7 +352,7 @@ test_basic_stream_operations(void) params.rate = STREAM_RATE; params.channels = STREAM_CHANNELS; - r = cubeb_stream_init(ctx, &stream, "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0 && stream); @@ -402,7 +401,7 @@ test_stream_position(void) params.rate = STREAM_RATE; params.channels = STREAM_CHANNELS; - r = cubeb_stream_init(ctx, &stream, "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); assert(r == 0 && stream); @@ -475,16 +474,16 @@ static int do_drain; static int got_drain; static long -test_drain_data_callback(cubeb_stream * stm, void * user_ptr, const void * inputbuffer, void * outputbuffer, long nframes) +test_drain_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes) { - assert(stm && user_ptr == &dummy && outputbuffer && nframes > 0); + assert(stm && user_ptr == &dummy && p && nframes > 0); if (do_drain == 1) { do_drain = 2; return 0; } /* once drain has started, callback must never be called again */ assert(do_drain != 2); - memset(outputbuffer, 0, nframes * sizeof(short)); + memset(p, 0, nframes * sizeof(short)); total_frames_written += nframes; return nframes; } @@ -518,7 +517,7 @@ test_drain(void) params.rate = STREAM_RATE; params.channels = STREAM_CHANNELS; - r = cubeb_stream_init(ctx, &stream, "test", NULL, NULL, NULL, ¶ms, STREAM_LATENCY, + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, test_drain_data_callback, test_drain_state_callback, &dummy); assert(r == 0 && stream); diff --git a/media/libcubeb/tests/test_tone.cpp b/media/libcubeb/tests/test_tone.cpp index 82bcb80b9cec..d0cee22b372e 100644 --- a/media/libcubeb/tests/test_tone.cpp +++ b/media/libcubeb/tests/test_tone.cpp @@ -34,13 +34,13 @@ struct cb_user_data { long position; }; -long data_cb(cubeb_stream *stream, void *user, const void* inputbuffer, void *outputbuffer, long nframes) +long data_cb(cubeb_stream *stream, void *user, void *buffer, long nframes) { struct cb_user_data *u = (struct cb_user_data *)user; #if (defined(_WIN32) || defined(__WIN32__)) - float *b = (float *)outputbuffer; + float *b = (float *)buffer; #else - short *b = (short *)outputbuffer; + short *b = (short *)buffer; #endif float t1, t2; int i; @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) } user_data->position = 0; - r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", NULL, NULL, NULL, ¶ms, + r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params, 250, data_cb, state_cb, user_data); if (r != CUBEB_OK) { fprintf(stderr, "Error initializing cubeb stream\n");