Commit 881a0867 authored by Sebastian Dröge's avatar Sebastian Dröge 🍵

decklinksrc: Stop using the "hardware" timestamps and directly use the pipeline clock

The hardware timestamps have no relation to when frames were produced,
only when frames arrived somewhere in the hardware. Especially there is
no guarantee that audio and video will have the same hardware timestamps
although they belong together, and even more important: the rate with
which the hardware timestamps increase is completely unrelated to the
rate with which the frames are captured!

As such we can as well use the pipeline clock directly and stop doing
complicated calculations. Also as a side effect this allows now running
without any pipeline clock, by directly making use of the stream times
as reported by the driver.

https://bugzilla.gnome.org/show_bug.cgi?id=774850
parent 423e4593
This diff is collapsed.
......@@ -196,25 +196,21 @@ struct _GstDecklinkInput {
IDeckLinkInput *input;
IDeckLinkConfiguration *config;
IDeckLinkAttributes *attributes;
GstClock *clock;
GstClockTime clock_start_time, clock_offset, clock_last_time, clock_epoch;
gboolean started, clock_restart;
/* Everything below protected by mutex */
GMutex lock;
/* Set by the video source */
void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime capture_duration, guint hours, guint minutes, guint seconds, guint frames, BMDTimecodeFlags bflags);
void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, guint hours, guint minutes, guint seconds, guint frames, BMDTimecodeFlags bflags);
/* Configured mode or NULL */
const GstDecklinkMode *mode;
BMDPixelFormat format;
/* Set by the audio source */
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, gboolean discont);
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime packet_time);
GstElement *audiosrc;
gboolean audio_enabled;
gboolean audio_discont;
GstElement *videosrc;
gboolean video_enabled;
void (*start_streams) (GstElement *videosrc);
......
......@@ -57,7 +57,6 @@ typedef struct
{
IDeckLinkAudioInputPacket *packet;
GstClockTime capture_time;
gboolean discont;
} CapturePacket;
static void
......@@ -422,27 +421,13 @@ gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
static void
gst_decklink_audio_src_got_packet (GstElement * element,
IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
gboolean discont)
GstClockTime packet_time)
{
GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
GstDecklinkVideoSrc *videosrc = NULL;
GST_LOG_OBJECT (self, "Got audio packet at %" GST_TIME_FORMAT,
GST_TIME_ARGS (capture_time));
g_mutex_lock (&self->input->lock);
if (self->input->videosrc)
videosrc =
GST_DECKLINK_VIDEO_SRC_CAST (gst_object_ref (self->input->videosrc));
g_mutex_unlock (&self->input->lock);
if (videosrc) {
gst_decklink_video_src_convert_to_external_clock (videosrc, &capture_time,
NULL);
gst_object_unref (videosrc);
GST_LOG_OBJECT (self, "Actual timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (capture_time));
}
GST_LOG_OBJECT (self,
"Got audio packet at %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT,
GST_TIME_ARGS (capture_time), GST_TIME_ARGS (packet_time));
g_mutex_lock (&self->lock);
if (!self->flushing) {
......@@ -457,8 +442,8 @@ gst_decklink_audio_src_got_packet (GstElement * element,
p = (CapturePacket *) g_malloc0 (sizeof (CapturePacket));
p->packet = packet;
p->capture_time = capture_time;
p->discont = discont;
p->capture_time =
capture_time != GST_CLOCK_TIME_NONE ? capture_time : packet_time;
packet->AddRef ();
g_queue_push_tail (&self->current_packets, p);
g_cond_signal (&self->cond);
......@@ -523,7 +508,6 @@ retry:
ap->input->AddRef ();
timestamp = p->capture_time;
discont = p->discont;
// Jitter and discontinuity handling, based on audiobasesrc
start_time = timestamp;
......@@ -538,7 +522,7 @@ retry:
duration = end_time - start_time;
if (discont || self->next_offset == (guint64) - 1) {
if (self->next_offset == (guint64) - 1) {
discont = TRUE;
} else {
guint64 diff, max_sample_diff;
......
......@@ -955,7 +955,8 @@ gst_decklink_video_sink_change_state (GstElement * element,
gst_decklink_video_sink_stop (self);
break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{
if (gst_decklink_video_sink_stop_scheduled_playback (self) == GST_STATE_CHANGE_FAILURE)
if (gst_decklink_video_sink_stop_scheduled_playback (self) ==
GST_STATE_CHANGE_FAILURE)
ret = GST_STATE_CHANGE_FAILURE;
break;
}
......
This diff is collapsed.
......@@ -69,9 +69,6 @@ struct _GstDecklinkVideoSrc
gboolean no_signal;
guint buffer_size;
GstClockTime internal_base_time;
GstClockTime external_base_time;
};
struct _GstDecklinkVideoSrcClass
......@@ -80,8 +77,6 @@ struct _GstDecklinkVideoSrcClass
};
GType gst_decklink_video_src_get_type (void);
void gst_decklink_video_src_convert_to_external_clock (GstDecklinkVideoSrc * self,
GstClockTime * timestamp, GstClockTime * duration);
G_END_DECLS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment