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>
This commit is contained in:
Michael Niedermayer 2015-01-26 14:39:22 +01:00
commit fcb18ab8d0
5 changed files with 98 additions and 22 deletions

View File

@ -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

View File

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

View File

@ -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];

View File

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

View File

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