Skip to content

Commit

Permalink
avdevice/dshow: implement option to use device video timestamps
Browse files Browse the repository at this point in the history
The dshow avdevice ignores timestamps for video frames provided by the
DirectShow device, instead using wallclock time, apparently because the
implementer of this code had a device that provided unreliable
timestamps. Me (and others) would like to use the device's timestamps.
The new use_video_device_timestamps option for dshow device enables them
to do so. Since the majority of video devices out there probably provide
fine timestamps, this patch sets the default to using the device
timestamps, which means best fidelity timestamps are used by default.
Using the new option, the user can switch this off and revert to the old
behavior, so a fall back remains available in case the device provides
broken timestamps.

add use_video_device_timestamps to docs.

Closes: #8620

Signed-off-by: Diederick Niehorster <[email protected]>
Reviewed-by: Roger Pack <[email protected]>
  • Loading branch information
dcnieho authored and GyanD committed Dec 24, 2021
1 parent 7b21841 commit 7dc33aa
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 5 deletions.
6 changes: 6 additions & 0 deletions doc/indevs.texi
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,12 @@ Save the currently used video capture filter device and its
parameters (if the filter supports it) to a file.
If a file with the same name exists it will be overwritten.

@item use_video_device_timestamps
If set to @option{false}, the timestamp for video frames will be
derived from the wallclock instead of the timestamp provided by
the capture device. This allows working around devices that
provide unreliable timestamps.

@end table

@subsection Examples
Expand Down
1 change: 1 addition & 0 deletions libavdevice/dshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ static const AVOption options[] = {
{ "audio_device_save", "save audio capture filter device (and properties) to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ "video_device_load", "load video capture filter device (and properties) from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ "video_device_save", "save video capture filter device (and properties) to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ "use_video_device_timestamps", "use device instead of wallclock timestamps for video frames", OFFSET(use_video_device_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
{ NULL },
};

Expand Down
1 change: 1 addition & 0 deletions libavdevice/dshow_capture.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ struct dshow_ctx {
char *audio_filter_save_file;
char *video_filter_load_file;
char *video_filter_save_file;
int use_video_device_timestamps;

IBaseFilter *device_filter[2];
IPin *device_pin[2];
Expand Down
11 changes: 6 additions & 5 deletions libavdevice/dshow_pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,14 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, IMediaSample *sample)
if (!sample)
return E_POINTER;

priv_data = pin->filter->priv_data;
s = priv_data;
ctx = s->priv_data;

IMediaSample_GetTime(sample, &orig_curtime, &dummy);
orig_curtime += pin->filter->start_time;
IReferenceClock_GetTime(clock, &graphtime);
if (devtype == VideoDevice) {
if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
/* PTS from video devices is unreliable. */
IReferenceClock_GetTime(clock, &curtime);
} else {
Expand All @@ -322,17 +326,14 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, IMediaSample *sample)
like 437650244077016960 which FFmpeg doesn't like.
TODO figure out math. For now just drop them. */
av_log(NULL, AV_LOG_DEBUG,
"dshow dropping initial (or ending) audio frame with odd PTS too high %"PRId64"\n", curtime);
"dshow dropping initial (or ending) frame with odd PTS too high %"PRId64"\n", curtime);
return S_OK;
}
curtime += pin->filter->start_time;
}

buf_size = IMediaSample_GetActualDataLength(sample);
IMediaSample_GetPointer(sample, &buf);
priv_data = pin->filter->priv_data;
s = priv_data;
ctx = s->priv_data;
index = pin->filter->stream_index;

av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size %8d "
Expand Down

0 comments on commit 7dc33aa

Please sign in to comment.