diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-01-26 14:39:22 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-01-26 14:39:25 +0100 |
commit | fcb18ab8d03d6ff94fb9b1fd8a4289e53f59ab1a (patch) | |
tree | 32c4de066555986f1d757fbefa5ca93154331e91 | |
parent | e44a4c1f5fcb2382dd7420c904590f4c8de7fec2 (diff) | |
parent | 61974c7dcca833687d4f3834c7e8200a63a7b4af (diff) | |
download | ffmpeg-fcb18ab8d03d6ff94fb9b1fd8a4289e53f59ab1a.tar.gz |
Merge remote-tracking branch 'rdp/dshow_tv_tuner'
* rdp/dshow_tv_tuner:
dshow: tweak logging
dshow: crossbar dialog was frequently being displayed twice, split up option so it can be just once
dshow: alert as to ramifications of switching crossbar routing
dshow: add properties dialog for tv tuners
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | doc/indevs.texi | 34 | ||||
-rw-r--r-- | libavdevice/dshow.c | 19 | ||||
-rw-r--r-- | libavdevice/dshow_capture.h | 5 | ||||
-rw-r--r-- | libavdevice/dshow_crossbar.c | 50 | ||||
-rw-r--r-- | libavdevice/dshow_pin.c | 12 |
5 files changed, 98 insertions, 22 deletions
diff --git a/doc/indevs.texi b/doc/indevs.texi index 75ad76f5e7..ae61331a6f 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -229,29 +229,51 @@ Select audio capture pin to use by name or alternative name. @item crossbar_video_input_pin_number Select video input pin number for crossbar device. This will be routed to the crossbar device's Video Decoder output pin. +Note that changing this value can affect future invocations +(sets a new default) until system reboot occurs. @item crossbar_audio_input_pin_number Select audio input pin number for crossbar device. This will be routed to the crossbar device's Audio Decoder output pin. +Note that changing this value can affect future invocations +(sets a new default) until system reboot occurs. @item show_video_device_dialog If set to @option{true}, before capture starts, popup a display dialog to the end user, allowing them to change video filter properties and configurations manually. -Note that for crossbar devices, this may be needed at times to toggle -between PAL and NTSC input frame rates and sizes, etc. Possibly -enabling different scan rates/frame rates and avoiding green bars at -the bottom, etc. +Note that for crossbar devices, adjusting values in this dialog +may be needed at times to toggle between PAL (25 fps) and NTSC (29.97) +input frame rates, sizes, interlacing, etc. Changing these values can +enable different scan rates/frame rates and avoiding green bars at +the bottom, flickering scan lines, etc. +Note that with some devices, changing these properties can also affect future +invocations (sets new defaults) until system reboot occurs. @item show_audio_device_dialog If set to @option{true}, before capture starts, popup a display dialog to the end user, allowing them to change audio filter properties and configurations manually. -@item show_crossbar_connection_dialog +@item show_video_crossbar_connection_dialog If set to @option{true}, before capture starts, popup a display dialog to the end user, allowing them to manually -modify crossbar pin routings. +modify crossbar pin routings, when it opens a video device. + +@item show_audio_crossbar_connection_dialog +If set to @option{true}, before capture starts, popup a display +dialog to the end user, allowing them to manually +modify crossbar pin routings, when it opens an audio device. + +@item show_analog_tv_tuner_dialog +If set to @option{true}, before capture starts, popup a display +dialog to the end user, allowing them to manually +modify TV channels and frequencies. + +@item show_analog_tv_tuner_audio_dialog +If set to @option{true}, before capture starts, popup a display +dialog to the end user, allowing them to manually +modify TV audio (like mono vs. stereo, Language A,B or C). @end table diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index e34b77c084..d03670e36f 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -1044,7 +1044,7 @@ static int dshow_read_header(AVFormatContext *avctx) if (ctx->device_name[AudioDevice]) { if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 || (r = dshow_add_device(avctx, AudioDevice)) < 0) { - av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices %s\n", ctx->device_name[AudioDevice]); + 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) { @@ -1104,7 +1104,7 @@ static int dshow_read_header(AVFormatContext *avctx) 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; } @@ -1199,9 +1199,18 @@ static const AVOption options[] = { { "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_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter", OFFSET(show_crossbar_connection_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_crossbar_connection_dialog" }, - { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_crossbar_connection_dialog" }, - { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_crossbar_connection_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 }, }; diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h index 2e64776563..f258476099 100644 --- a/libavdevice/dshow_capture.h +++ b/libavdevice/dshow_capture.h @@ -303,7 +303,10 @@ struct dshow_ctx { char *audio_pin_name; int show_video_device_dialog; int show_audio_device_dialog; - int show_crossbar_connection_dialog; + int show_video_crossbar_connection_dialog; + int show_audio_crossbar_connection_dialog; + int show_analog_tv_tuner_dialog; + int show_analog_tv_tuner_audio_dialog; IBaseFilter *device_filter[2]; IPin *device_pin[2]; diff --git a/libavdevice/dshow_crossbar.c b/libavdevice/dshow_crossbar.c index 9c6301977b..c0739da318 100644 --- a/libavdevice/dshow_crossbar.c +++ b/libavdevice/dshow_crossbar.c @@ -142,23 +142,55 @@ dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, { struct dshow_ctx *ctx = avctx->priv_data; IAMCrossbar *cross_bar = NULL; - IBaseFilter *cross_bar_filter = NULL; + IBaseFilter *cross_bar_base_filter = NULL; + IAMTVTuner *tv_tuner_filter = NULL; + IBaseFilter *tv_tuner_base_filter = NULL; + IAMAudioInputMixer *tv_audio_filter = NULL; + IBaseFilter *tv_audio_base_filter = NULL; HRESULT hr; hr = ICaptureGraphBuilder2_FindInterface(graph_builder2, &LOOK_UPSTREAM_ONLY, (const GUID *) NULL, - (IBaseFilter *) device_filter, &IID_IAMCrossbar, (void**) &cross_bar); + device_filter, &IID_IAMCrossbar, (void**) &cross_bar); if (hr != S_OK) { /* no crossbar found */ hr = S_OK; goto end; } + /* TODO some TV tuners apparently have multiple crossbars? */ - if (ctx->show_crossbar_connection_dialog) { - hr = IAMCrossbar_QueryInterface(cross_bar, &IID_IBaseFilter, (void **) &cross_bar_filter); + if (devtype == VideoDevice && ctx->show_video_crossbar_connection_dialog || + devtype == AudioDevice && ctx->show_audio_crossbar_connection_dialog) { + hr = IAMCrossbar_QueryInterface(cross_bar, &IID_IBaseFilter, (void **) &cross_bar_base_filter); if (hr != S_OK) goto end; - dshow_show_filter_properties(cross_bar_filter, avctx); + dshow_show_filter_properties(cross_bar_base_filter, avctx); } + + if (devtype == VideoDevice && ctx->show_analog_tv_tuner_dialog) { + hr = ICaptureGraphBuilder2_FindInterface(graph_builder2, &LOOK_UPSTREAM_ONLY, NULL, + device_filter, &IID_IAMTVTuner, (void**) &tv_tuner_filter); + if (hr == S_OK) { + hr = IAMCrossbar_QueryInterface(tv_tuner_filter, &IID_IBaseFilter, (void **) &tv_tuner_base_filter); + if (hr != S_OK) + goto end; + dshow_show_filter_properties(tv_tuner_base_filter, avctx); + } else { + av_log(avctx, AV_LOG_WARNING, "unable to find a tv tuner to display dialog for!"); + } + } + if (devtype == AudioDevice && ctx->show_analog_tv_tuner_audio_dialog) { + hr = ICaptureGraphBuilder2_FindInterface(graph_builder2, &LOOK_UPSTREAM_ONLY, NULL, + device_filter, &IID_IAMTVAudio, (void**) &tv_audio_filter); + if (hr == S_OK) { + hr = IAMCrossbar_QueryInterface(tv_audio_filter, &IID_IBaseFilter, (void **) &tv_audio_base_filter); + if (hr != S_OK) + goto end; + dshow_show_filter_properties(tv_audio_base_filter, avctx); + } else { + av_log(avctx, AV_LOG_WARNING, "unable to find a tv audio tuner to display dialog for!"); + } + } + hr = setup_crossbar_options(cross_bar, devtype, avctx); if (hr != S_OK) goto end; @@ -166,7 +198,11 @@ dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, end: if (cross_bar) IAMCrossbar_Release(cross_bar); - if (cross_bar_filter) - IBaseFilter_Release(cross_bar_filter); + if (cross_bar_base_filter) + IBaseFilter_Release(cross_bar_base_filter); + if (tv_tuner_filter) + IAMTVTuner_Release(tv_tuner_filter); + if (tv_tuner_base_filter) + IBaseFilter_Release(tv_tuner_base_filter); return hr; } diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c index 5904c28b86..4f719a660e 100644 --- a/libavdevice/dshow_pin.c +++ b/libavdevice/dshow_pin.c @@ -304,21 +304,25 @@ libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample) enum dshowDeviceType devtype = pin->filter->type; void *priv_data; uint8_t *buf; - int buf_size; + int buf_size; /* todo should be a long? */ int index; int64_t curtime; + int64_t orig_curtime; + const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; + IReferenceClock *clock = pin->filter->clock; + int64_t dummy; dshowdebug("libAVMemInputPin_Receive(%p)\n", this); if (!sample) return E_POINTER; + IMediaSample_GetTime(sample, &orig_curtime, &dummy); + orig_curtime += pin->filter->start_time; if (devtype == VideoDevice) { /* PTS from video devices is unreliable. */ - IReferenceClock *clock = pin->filter->clock; IReferenceClock_GetTime(clock, &curtime); } else { - int64_t dummy; IMediaSample_GetTime(sample, &curtime, &dummy); if(curtime > 400000000000000000LL) { /* initial frames sometimes start < 0 (shown as a very large number here, @@ -336,6 +340,8 @@ libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample) priv_data = pin->filter->priv_data; index = pin->filter->stream_index; + av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size %6d timestamp %"PRId64" orig timestamp %"PRId64"\n", + devtypename, buf_size, curtime, orig_curtime); pin->filter->callback(priv_data, index, buf, buf_size, curtime, devtype); return S_OK; |