summaryrefslogtreecommitdiff
path: root/libavdevice/dshow.c
diff options
context:
space:
mode:
authorRamiro Polla <ramiro.polla@gmail.com>2011-09-09 00:09:23 -0300
committerStefano Sabatini <stefano.sabatini-lala@poste.it>2011-09-12 19:22:10 +0200
commit1c282f96ab78874cd968ea37b7342bb2d341a84a (patch)
tree32fb06793add4247e27ff4644e3b6de87382c719 /libavdevice/dshow.c
parentfad4e1a5722cb7d1bb6959d5eb084bf954d96d38 (diff)
dshow: add option to list devices
Signed-off-by: Stefano Sabatini <stefano.sabatini-lala@poste.it>
Diffstat (limited to 'libavdevice/dshow.c')
-rw-r--r--libavdevice/dshow.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 025237d9eb..2c298b2dda 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -19,14 +19,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/opt.h"
+
#include "avdevice.h"
#include "dshow.h"
struct dshow_ctx {
+ const AVClass *class;
+
IGraphBuilder *graph;
char *device_name[2];
+ int list_devices;
+
IBaseFilter *device_filter[2];
IPin *device_pin[2];
libAVFilter *capture_filter[2];
@@ -217,6 +223,7 @@ fail:
* Cycle through available devices using the device enumerator devenum,
* retrieve the device with type specified by devtype and return the
* pointer to the object found in *pfilter.
+ * If pfilter is NULL, list all device names.
*/
static int
dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
@@ -257,10 +264,14 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
buf = dup_wchar_to_utf8(var.bstrVal);
+ if (pfilter) {
if (strcmp(device_name, buf))
goto fail1;
IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
+ } else {
+ av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
+ }
fail1:
if (buf)
@@ -272,12 +283,14 @@ fail1:
IEnumMoniker_Release(classenum);
+ if (pfilter) {
if (!device_filter) {
av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
devtypename);
return AVERROR(EIO);
}
*pfilter = device_filter;
+ }
return 0;
}
@@ -555,7 +568,7 @@ static int dshow_read_header(AVFormatContext *avctx, AVFormatParameters *ap)
int ret = AVERROR(EIO);
int r;
- if (!parse_device_name(avctx)) {
+ if (!ctx->list_devices && !parse_device_name(avctx)) {
av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
goto error;
}
@@ -577,6 +590,15 @@ static int dshow_read_header(AVFormatContext *avctx, AVFormatParameters *ap)
goto error;
}
+ if (ctx->list_devices) {
+ av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
+ dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
+ av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
+ dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
+ ret = AVERROR_EXIT;
+ goto error;
+ }
+
if (ctx->device_name[VideoDevice]) {
ret = dshow_open_device(avctx, devenum, VideoDevice);
if (ret < 0)
@@ -664,6 +686,22 @@ static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
return pkt->size;
}
+#define OFFSET(x) offsetof(struct dshow_ctx, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "list_devices", "list available devices", OFFSET(list_devices), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1, DEC, "list_devices" },
+ { "true", "", 0, FF_OPT_TYPE_CONST, {.dbl=1}, 0, 0, DEC, "list_devices" },
+ { "false", "", 0, FF_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_devices" },
+ { NULL },
+};
+
+static const AVClass dshow_class = {
+ .class_name = "DirectShow indev",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_dshow_demuxer = {
"dshow",
NULL_IF_CONFIG_SMALL("DirectShow capture"),
@@ -673,4 +711,5 @@ AVInputFormat ff_dshow_demuxer = {
dshow_read_packet,
dshow_read_close,
.flags = AVFMT_NOFILE,
+ .priv_class = &dshow_class,
};