Commit ad7fae4e authored by Ramiro Polla's avatar Ramiro Polla Committed by Michael Niedermayer

dshow: allow user to specify audio buffer size

Based on patch by rogerdpack <rogerpack2005@gmail.com>
Tested-by: 's avatarRoger Pack <rogerdpack2@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent a5704659
......@@ -112,6 +112,15 @@ defaults to 0).
Set audio device number for devices with same name (starts at 0,
defaults to 0).
@item audio_buffer_size
Set audio device buffer size in milliseconds (which can directly
impact latency, depending on the device).
Defaults to using the audio device's
default buffer size (typically some multiple of 500ms).
Setting this value too low can degrade performance.
See also
@url{http://msdn.microsoft.com/en-us/library/windows/desktop/dd377582(v=vs.85).aspx}
@end table
@subsection Examples
......
......@@ -36,6 +36,7 @@ struct dshow_ctx {
int list_options;
int list_devices;
int audio_buffer_size;
IBaseFilter *device_filter[2];
IPin *device_pin[2];
......@@ -446,6 +447,51 @@ end:
*pformat_set = format_set;
}
/**
* Set audio device buffer size in milliseconds (which can directly impact
* latency, depending on the device).
*/
static int
dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
{
struct dshow_ctx *ctx = avctx->priv_data;
IAMBufferNegotiation *buffer_negotiation = NULL;
ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
IAMStreamConfig *config = NULL;
AM_MEDIA_TYPE *type = NULL;
int ret = AVERROR(EIO);
if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
goto end;
if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
goto end;
if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
goto end;
props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
* ctx->audio_buffer_size / 1000;
if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
goto end;
if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
goto end;
ret = 0;
end:
if (buffer_negotiation)
IAMBufferNegotiation_Release(buffer_negotiation);
if (type) {
if (type->pbFormat)
CoTaskMemFree(type->pbFormat);
CoTaskMemFree(type);
}
if (config)
IAMStreamConfig_Release(config);
return ret;
}
/**
* Cycle through available pins using the device_filter device, of type
* devtype, retrieve the first output pin and return the pointer to the
......@@ -513,6 +559,10 @@ dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
goto next;
}
}
if (devtype == AudioDevice && ctx->audio_buffer_size) {
if (dshow_set_audio_buffer_size(avctx, pin) < 0)
goto next;
}
if (IPin_EnumMediaTypes(pin, &types) != S_OK)
goto next;
......@@ -952,6 +1002,7 @@ static const AVOption options[] = {
{ "false", "", 0, AV_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_options" },
{ "video_device_number", "set video device number for devices with same name (starts at 0)", OFFSET(video_device_number), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
{ "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
{ "audio_buffer_size", "set audio device buffer latency size in milliseconds (default is the device's default)", OFFSET(audio_buffer_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
{ NULL },
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment