dshow: add option to list devices

Signed-off-by: Stefano Sabatini <stefano.sabatini-lala@poste.it>
This commit is contained in:
Ramiro Polla 2011-09-09 00:09:23 -03:00 committed by Stefano Sabatini
parent fad4e1a572
commit 1c282f96ab

View File

@ -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,
};