#include "avdevice.h"
#include "libavcodec/raw.h"
-struct dshow_ctx {
- const AVClass *class;
-
- IGraphBuilder *graph;
-
- char *device_name[2];
- int video_device_number;
- int audio_device_number;
-
- int list_options;
- int list_devices;
- int audio_buffer_size;
-
- IBaseFilter *device_filter[2];
- IPin *device_pin[2];
- libAVFilter *capture_filter[2];
- libAVPin *capture_pin[2];
-
- HANDLE mutex;
- HANDLE event[2]; /* event[0] is set by DirectShow
- * event[1] is set by callback() */
- AVPacketList *pktl;
-
- int eof;
-
- int64_t curbufsize[2];
- unsigned int video_frame_num;
-
- IMediaControl *control;
- IMediaEvent *media_event;
-
- enum AVPixelFormat pixel_format;
- enum AVCodecID video_codec_id;
- char *framerate;
-
- int requested_width;
- int requested_height;
- AVRational requested_framerate;
-
- int sample_rate;
- int sample_size;
- int channels;
-};
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
{
pktl = ctx->pktl;
while (pktl) {
AVPacketList *next = pktl->next;
- av_destruct_packet(&pktl->pkt);
+ av_free_packet(&pktl->pkt);
av_free(pktl);
pktl = next;
}
static const uint8_t dropscore[] = {62, 75, 87, 100};
const int ndropscores = FF_ARRAY_ELEMS(dropscore);
unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
+ const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
av_log(s, AV_LOG_ERROR,
- "real-time buffer[%s] too full (%d%% of size: %d)! frame dropped!\n", ctx->device_name[devtype], buffer_fullness, s->max_picture_buffer);
+ "real-time buffer [%s] [%s input] too full or near too full (%d%% of size: %d [rtbufsize parameter])! frame dropped!\n",
+ ctx->device_name[devtype], devtypename, buffer_fullness, s->max_picture_buffer);
return 1;
}
*/
static int
dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
- enum dshowDeviceType devtype, IBaseFilter **pfilter)
+ enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter **pfilter)
{
struct dshow_ctx *ctx = avctx->priv_data;
IBaseFilter *device_filter = NULL;
const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
&CLSID_AudioInputDeviceCategory };
- const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
+ const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
+ const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
- r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
+ r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
(IEnumMoniker **) &classenum, 0);
if (r != S_OK) {
- av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
+ av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
devtypename);
return AVERROR(EIO);
}
while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
IPropertyBag *bag = NULL;
- char *buf = NULL;
+ char *friendly_name = NULL;
+ char *unique_name = NULL;
VARIANT var;
+ IBindCtx *bind_ctx = NULL;
+ LPOLESTR olestr = NULL;
+ LPMALLOC co_malloc = NULL;
+ int i;
+
+ r = CoGetMalloc(1, &co_malloc);
+ if (r = S_OK)
+ goto fail1;
+ r = CreateBindCtx(0, &bind_ctx);
+ if (r != S_OK)
+ goto fail1;
+ /* GetDisplayname works for both video and audio, DevicePath doesn't */
+ r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
+ if (r != S_OK)
+ goto fail1;
+ unique_name = dup_wchar_to_utf8(olestr);
+ /* replace ':' with '_' since we use : to delineate between sources */
+ for (i = 0; i < strlen(unique_name); i++) {
+ if (unique_name[i] == ':')
+ unique_name[i] = '_';
+ }
r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
if (r != S_OK)
r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
if (r != S_OK)
goto fail1;
-
- buf = dup_wchar_to_utf8(var.bstrVal);
+ friendly_name = dup_wchar_to_utf8(var.bstrVal);
if (pfilter) {
- if (strcmp(device_name, buf))
+ if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
goto fail1;
- if (!skip--)
- IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
+ if (!skip--) {
+ r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
+ if (r != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
+ goto fail1;
+ }
+ }
} else {
- av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
+ av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
+ av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name);
}
fail1:
- av_free(buf);
+ if (olestr && co_malloc)
+ IMalloc_Free(co_malloc, olestr);
+ if (bind_ctx)
+ IBindCtx_Release(bind_ctx);
+ av_free(friendly_name);
+ av_free(unique_name);
if (bag)
IPropertyBag_Release(bag);
IMoniker_Release(m);
if (pfilter) {
if (!device_filter) {
- av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
- devtypename);
+ av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
+ devtypename, device_name, sourcetypename);
return AVERROR(EIO);
}
*pfilter = device_filter;
AM_MEDIA_TYPE *type = NULL;
int format_set = 0;
void *caps = NULL;
- int i, n, size;
+ int i, n, size, r;
if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
return;
goto end;
for (i = 0; i < n && !format_set; i++) {
- IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
-
+ r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
+ if (r != S_OK)
+ goto next;
#if DSHOWDEBUG
ff_print_AM_MEDIA_TYPE(type);
#endif
return ret;
}
+/**
+ * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
+ */
+void
+dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) {
+ ISpecifyPropertyPages *property_pages = NULL;
+ IUnknown *device_filter_iunknown = NULL;
+ HRESULT hr;
+ FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
+ CAUUID ca_guid = {0};
+
+ hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
+ if (hr != S_OK) {
+ av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
+ goto end;
+ }
+ hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
+ if (hr != S_OK) {
+ goto fail;
+ }
+ hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
+ if (hr != S_OK) {
+ goto fail;
+ }
+ hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
+ if (hr != S_OK) {
+ goto fail;
+ }
+ hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
+ ca_guid.pElems, 0, 0, NULL);
+ if (hr != S_OK) {
+ goto fail;
+ }
+ goto end;
+fail:
+ av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
+end:
+ if (property_pages)
+ ISpecifyPropertyPages_Release(property_pages);
+ if (device_filter_iunknown)
+ IUnknown_Release(device_filter_iunknown);
+ if (filter_info.pGraph)
+ IFilterGraph_Release(filter_info.pGraph);
+ if (ca_guid.pElems)
+ CoTaskMemFree(ca_guid.pElems);
+}
+
/**
* Cycle through available pins using the device_filter device, of type
* devtype, retrieve the first output pin and return the pointer to the
*/
static int
dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
- IBaseFilter *device_filter, IPin **ppin)
+ enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
{
struct dshow_ctx *ctx = avctx->priv_data;
IEnumPins *pins = 0;
int r;
const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
- const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
+ const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
+ const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
int set_format = (devtype == VideoDevice && (ctx->framerate ||
(ctx->requested_width && ctx->requested_height) ||
ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
|| (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
int format_set = 0;
+ int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
+
+ if (should_show_properties)
+ dshow_show_filter_properties(device_filter, avctx);
r = IBaseFilter_EnumPins(device_filter, &pins);
if (r != S_OK) {
}
if (!ppin) {
- av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
- devtypename);
+ av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
+ devtypename, sourcetypename);
}
+
while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
IKsPropertySet *p = NULL;
IEnumMediaTypes *types = NULL;
AM_MEDIA_TYPE *type;
GUID category;
DWORD r2;
+ char *name_buf = NULL;
+ wchar_t *pin_id = NULL;
+ char *pin_buf = NULL;
+ char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
IPin_QueryPinInfo(pin, &info);
IBaseFilter_Release(info.pFilter);
goto next;
if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
goto next;
+ name_buf = dup_wchar_to_utf8(info.achName);
+
+ r = IPin_QueryId(pin, &pin_id);
+ if (r != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
+ return AVERROR(EIO);
+ }
+ pin_buf = dup_wchar_to_utf8(pin_id);
if (!ppin) {
- char *buf = dup_wchar_to_utf8(info.achName);
- av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
- av_free(buf);
+ av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
dshow_cycle_formats(avctx, devtype, pin, NULL);
goto next;
}
+
+ if (desired_pin_name) {
+ if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
+ av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
+ name_buf, pin_buf, desired_pin_name);
+ goto next;
+ }
+ }
+
if (set_format) {
dshow_cycle_formats(avctx, devtype, pin, &format_set);
if (!format_set) {
goto next;
IEnumMediaTypes_Reset(types);
+ /* in case format_set was not called, just verify the majortype */
while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
device_pin = pin;
+ av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
goto next;
}
CoTaskMemFree(type);
IKsPropertySet_Release(p);
if (device_pin != pin)
IPin_Release(pin);
+ av_free(name_buf);
+ av_free(pin_buf);
+ if (pin_id)
+ CoTaskMemFree(pin_id);
}
IEnumPins_Release(pins);
}
/**
- * List options for device with type devtype.
+ * List options for device with type devtype, source filter type sourcetype
*
* @param devenum device enumerator used for accessing the device
*/
static int
dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
- enum dshowDeviceType devtype)
+ enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
{
struct dshow_ctx *ctx = avctx->priv_data;
IBaseFilter *device_filter = NULL;
int r;
- if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
+ if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0)
return r;
ctx->device_filter[devtype] = device_filter;
- if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
+ if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
return r;
return 0;
static int
dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
- enum dshowDeviceType devtype)
+ enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
{
struct dshow_ctx *ctx = avctx->priv_data;
IBaseFilter *device_filter = NULL;
IPin *device_pin = NULL;
libAVPin *capture_pin = NULL;
libAVFilter *capture_filter = NULL;
+ ICaptureGraphBuilder2 *graph_builder2 = NULL;
int ret = AVERROR(EIO);
int r;
const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
- if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
+ if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0) {
ret = r;
goto error;
}
goto error;
}
- if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
+ if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
ret = r;
goto error;
}
+
ctx->device_pin[devtype] = device_pin;
capture_filter = libAVFilter_Create(avctx, callback, devtype);
capture_pin = capture_filter->pin;
ctx->capture_pin[devtype] = capture_pin;
- r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
+ r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
+ if (r != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
+ goto error;
+ }
+ ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
if (r != S_OK) {
- av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
+ av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
+ goto error;
+ }
+
+ r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
+ (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
+
+ if (r != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
+ goto error;
+ }
+
+ r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
+
+ if (r != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
goto error;
}
ret = 0;
error:
+ if (graph_builder2 != NULL)
+ ICaptureGraphBuilder2_Release(graph_builder2);
+
return ret;
}
}
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 video devices (some may be both video and audio devices)\n");
+ dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL);
av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
- dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
+ dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL);
ret = AVERROR_EXIT;
goto error;
}
if (ctx->list_options) {
if (ctx->device_name[VideoDevice])
- dshow_list_device_options(avctx, devenum, VideoDevice);
- if (ctx->device_name[AudioDevice])
- dshow_list_device_options(avctx, devenum, AudioDevice);
- ret = AVERROR_EXIT;
- goto error;
+ if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
+ ret = r;
+ goto error;
+ }
+ if (ctx->device_name[AudioDevice]) {
+ if (dshow_list_device_options(avctx, devenum, AudioDevice, AudioSourceDevice)) {
+ /* show audio options from combined video+audio sources as fallback */
+ if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
+ ret = r;
+ goto error;
+ }
+ }
+ }
}
-
if (ctx->device_name[VideoDevice]) {
- if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
+ if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
(r = dshow_add_device(avctx, VideoDevice)) < 0) {
ret = r;
goto error;
}
}
if (ctx->device_name[AudioDevice]) {
- if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
+ if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
(r = dshow_add_device(avctx, AudioDevice)) < 0) {
- ret = r;
- goto error;
+ av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
+ /* see if there's a video source with an audio pin with the given audio name */
+ if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
+ (r = dshow_add_device(avctx, AudioDevice)) < 0) {
+ ret = r;
+ goto error;
+ }
}
}
+ if (ctx->list_options) {
+ /* allow it to list crossbar options in dshow_open_device */
+ ret = AVERROR_EXIT;
+ goto error;
+ }
ctx->curbufsize[0] = 0;
ctx->curbufsize[1] = 0;
ctx->mutex = CreateMutex(NULL, 0, NULL);
r = IMediaControl_GetState(control, 0, &pfs);
}
if (r != S_OK) {
- av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
+ av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
goto error;
}
{ "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
{ "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
{ "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 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, {.i64 = 0}, 0, INT_MAX, DEC },
{ "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
{ "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
{ "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
{ "false", "", 0, AV_OPT_TYPE_CONST, {.i64=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, {.i64 = 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, {.i64 = 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, {.i64 = 0}, 0, INT_MAX, DEC },
+ { "video_pin_name", "select video capture pin by name", OFFSET(video_pin_name),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "audio_pin_name", "select audio capture pin by name", OFFSET(audio_pin_name),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "crossbar_video_input_pin_number", "set video input pin number for crossbar device", OFFSET(crossbar_video_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
+ { "crossbar_audio_input_pin_number", "set audio input pin number for crossbar device", OFFSET(crossbar_audio_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
+ { "show_video_device_dialog", "display property dialog for video capture device", OFFSET(show_video_device_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_video_device_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_video_device_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_video_device_dialog" },
+ { "show_audio_device_dialog", "display property dialog for audio capture device", OFFSET(show_audio_device_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_audio_device_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_audio_device_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_audio_device_dialog" },
+ { "show_video_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on video device", OFFSET(show_video_crossbar_connection_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_video_crossbar_connection_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_video_crossbar_connection_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_video_crossbar_connection_dialog" },
+ { "show_audio_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on audio device", OFFSET(show_audio_crossbar_connection_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_audio_crossbar_connection_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_audio_crossbar_connection_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_audio_crossbar_connection_dialog" },
+ { "show_analog_tv_tuner_dialog", "display property dialog for analog tuner filter", OFFSET(show_analog_tv_tuner_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_analog_tv_tuner_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_analog_tv_tuner_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_analog_tv_tuner_dialog" },
+ { "show_analog_tv_tuner_audio_dialog", "display property dialog for analog tuner audio filter", OFFSET(show_analog_tv_tuner_audio_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_analog_tv_tuner_dialog" },
+ { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_analog_tv_tuner_audio_dialog" },
+ { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_analog_tv_tuner_audio_dialog" },
{ NULL },
};