* 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>tags/n2.6
| @@ -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 | |||
| @@ -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 }, | |||
| }; | |||
| @@ -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]; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||