[FFmpeg-cvslog] dshow: allow user to specify audio buffer size

Ramiro Polla git at videolan.org
Wed Aug 29 19:02:33 CEST 2012


ffmpeg | branch: master | Ramiro Polla <ramiro.polla at gmail.com> | Sat Aug 25 05:09:37 2012 -0300| [ad7fae4ee1f9c1c080bb4c8760ac503a11420bba] | committer: Michael Niedermayer

dshow: allow user to specify audio buffer size

Based on patch by rogerdpack <rogerpack2005 at gmail.com>

Tested-by: Roger Pack <rogerdpack2 at gmail.com>
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ad7fae4ee1f9c1c080bb4c8760ac503a11420bba
---

 doc/indevs.texi     |    9 +++++++++
 libavdevice/dshow.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 86f10a3..264dc58 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -112,6 +112,15 @@ defaults to 0).
 Set audio device number for devices with same name (starts at 0,
 defaults to 0).
 
+ at 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
+ at url{http://msdn.microsoft.com/en-us/library/windows/desktop/dd377582(v=vs.85).aspx}
+
 @end table
 
 @subsection Examples
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index ea6c21c..18adf8f 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -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];
@@ -447,6 +448,51 @@ end:
 }
 
 /**
+ * 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
  * object found in *ppin.
@@ -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 },
 };
 



More information about the ffmpeg-cvslog mailing list