dshow: allow user to specify audio buffer size
Based on patch by rogerdpack <rogerpack2005@gmail.com> Tested-by: Roger Pack <rogerdpack2@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
a5704659e3
commit
ad7fae4ee1
@ -112,6 +112,15 @@ defaults to 0).
|
|||||||
Set audio device number for devices with same name (starts at 0,
|
Set audio device number for devices with same name (starts at 0,
|
||||||
defaults to 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
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
|
@ -36,6 +36,7 @@ struct dshow_ctx {
|
|||||||
|
|
||||||
int list_options;
|
int list_options;
|
||||||
int list_devices;
|
int list_devices;
|
||||||
|
int audio_buffer_size;
|
||||||
|
|
||||||
IBaseFilter *device_filter[2];
|
IBaseFilter *device_filter[2];
|
||||||
IPin *device_pin[2];
|
IPin *device_pin[2];
|
||||||
@ -446,6 +447,51 @@ end:
|
|||||||
*pformat_set = format_set;
|
*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
|
* Cycle through available pins using the device_filter device, of type
|
||||||
* devtype, retrieve the first output pin and return the pointer to the
|
* 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;
|
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)
|
if (IPin_EnumMediaTypes(pin, &types) != S_OK)
|
||||||
goto next;
|
goto next;
|
||||||
@ -952,6 +1002,7 @@ static const AVOption options[] = {
|
|||||||
{ "false", "", 0, AV_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_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 },
|
{ "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_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 },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user