mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
decklinksrc: Sample the pipeline clock for the timestamps instead of coming up with our own
If we just count the frames and calculate timestamps from that, all frames will arrive late in the sink as we have a live source here. Instead take the pipeline clock at capture time as reference.
This commit is contained in:
parent
ee8766b342
commit
50c4ea54f6
3 changed files with 35 additions and 11 deletions
|
@ -78,6 +78,8 @@ HRESULT
|
|||
videoFrame, IDeckLinkAudioInputPacket * audioFrame)
|
||||
{
|
||||
GstDecklinkSrc *decklinksrc;
|
||||
GstClock *clock;
|
||||
GstClockTime base_time, clock_time, capture_time;
|
||||
const char *timecodeString = NULL;
|
||||
|
||||
g_return_val_if_fail (priv != NULL, S_OK);
|
||||
|
@ -109,9 +111,32 @@ HRESULT
|
|||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (decklinksrc, "Frame received [%s] - %s - Size: %li bytes",
|
||||
timecodeString != NULL ? timecodeString : "No timecode",
|
||||
"Valid Frame", videoFrame->GetRowBytes () * videoFrame->GetHeight ());
|
||||
GST_OBJECT_LOCK (decklinksrc);
|
||||
if ((clock = GST_ELEMENT_CLOCK (decklinksrc))) {
|
||||
base_time = GST_ELEMENT (decklinksrc)->base_time;
|
||||
gst_object_ref (clock);
|
||||
} else {
|
||||
base_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (decklinksrc);
|
||||
if (clock) {
|
||||
clock_time = gst_clock_get_time (clock);
|
||||
gst_object_unref (clock);
|
||||
} else {
|
||||
clock_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
if (base_time != GST_CLOCK_TIME_NONE) {
|
||||
capture_time = clock_time - base_time;
|
||||
} else {
|
||||
capture_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (decklinksrc,
|
||||
"Frame received [%s] - %s - %" GST_TIME_FORMAT "Size: %li bytes",
|
||||
timecodeString != NULL ? timecodeString : "No timecode", "Valid Frame",
|
||||
GST_TIME_ARGS (capture_time),
|
||||
videoFrame->GetRowBytes () * videoFrame->GetHeight ());
|
||||
|
||||
if (timecodeString)
|
||||
FREE_COM_STRING (timecodeString);
|
||||
|
@ -130,6 +155,7 @@ HRESULT
|
|||
audioFrame->AddRef ();
|
||||
decklinksrc->audio_frame = audioFrame;
|
||||
}
|
||||
decklinksrc->capture_time = capture_time;
|
||||
|
||||
/* increment regardless whether frame was dropped or not */
|
||||
decklinksrc->frame_num++;
|
||||
|
|
|
@ -756,6 +756,7 @@ gst_decklink_src_task (void *priv)
|
|||
GstFlowReturn video_flow, audio_flow, flow;
|
||||
const GstDecklinkMode *mode;
|
||||
gboolean discont = FALSE;
|
||||
GstClockTime capture_time;
|
||||
|
||||
GST_DEBUG_OBJECT (decklinksrc, "task");
|
||||
|
||||
|
@ -766,6 +767,7 @@ gst_decklink_src_task (void *priv)
|
|||
}
|
||||
video_frame = decklinksrc->video_frame;
|
||||
audio_frame = decklinksrc->audio_frame;
|
||||
capture_time = decklinksrc->capture_time;
|
||||
decklinksrc->video_frame = NULL;
|
||||
decklinksrc->audio_frame = NULL;
|
||||
g_mutex_unlock (&decklinksrc->mutex);
|
||||
|
@ -846,12 +848,9 @@ gst_decklink_src_task (void *priv)
|
|||
vf->input->AddRef ();
|
||||
}
|
||||
|
||||
GST_BUFFER_TIMESTAMP (buffer) =
|
||||
gst_util_uint64_scale_int (decklinksrc->frame_num * GST_SECOND,
|
||||
GST_BUFFER_TIMESTAMP (buffer) = capture_time;
|
||||
GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (GST_SECOND,
|
||||
mode->fps_d, mode->fps_n);
|
||||
GST_BUFFER_DURATION (buffer) =
|
||||
gst_util_uint64_scale_int ((decklinksrc->frame_num + 1) * GST_SECOND,
|
||||
mode->fps_d, mode->fps_n) - GST_BUFFER_TIMESTAMP (buffer);
|
||||
GST_BUFFER_OFFSET (buffer) = decklinksrc->frame_num;
|
||||
GST_BUFFER_OFFSET_END (buffer) = decklinksrc->frame_num; /* FIXME: +1? */
|
||||
|
||||
|
@ -873,9 +872,7 @@ gst_decklink_src_task (void *priv)
|
|||
audio_buffer = gst_buffer_new_and_alloc (n_samples * 2 * 2);
|
||||
gst_buffer_fill (audio_buffer, 0, data, n_samples * 2 * 2);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (audio_buffer) =
|
||||
gst_util_uint64_scale_int (decklinksrc->num_audio_samples * GST_SECOND,
|
||||
1, 48000);
|
||||
GST_BUFFER_TIMESTAMP (audio_buffer) = capture_time;
|
||||
/* FIXME: should be next_timestamp - timestamp for perfect stream */
|
||||
GST_BUFFER_DURATION (audio_buffer) =
|
||||
gst_util_uint64_scale_int (n_samples * GST_SECOND, 1, 48000);
|
||||
|
|
|
@ -60,6 +60,7 @@ struct _GstDecklinkSrc
|
|||
int dropped_frames;
|
||||
int dropped_frames_old;
|
||||
gboolean stop;
|
||||
GstClockTime capture_time;
|
||||
IDeckLinkVideoInputFrame *video_frame;
|
||||
IDeckLinkAudioInputPacket * audio_frame;
|
||||
|
||||
|
|
Loading…
Reference in a new issue