mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-05 18:22:23 +00:00
decklinksink: Schedule video frames according to their timestamps, not according to a frame counter
This commit is contained in:
parent
b4695f60e5
commit
d191fb4476
2 changed files with 30 additions and 1 deletions
|
@ -413,6 +413,8 @@ gst_decklink_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
|
gst_segment_init (&decklinksink->audio_segment, GST_FORMAT_TIME);
|
||||||
|
gst_segment_init (&decklinksink->video_segment, GST_FORMAT_TIME);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
break;
|
break;
|
||||||
|
@ -449,6 +451,9 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstObject * parent,
|
||||||
GstFlowReturn flow_ret;
|
GstFlowReturn flow_ret;
|
||||||
const GstDecklinkMode *mode;
|
const GstDecklinkMode *mode;
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
|
GstClockTime timestamp, duration;
|
||||||
|
GstClockTime running_time;
|
||||||
|
GstClockTime running_time_duration;
|
||||||
|
|
||||||
decklinksink = GST_DECKLINK_SINK (parent);
|
decklinksink = GST_DECKLINK_SINK (parent);
|
||||||
|
|
||||||
|
@ -478,6 +483,13 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstObject * parent,
|
||||||
|
|
||||||
frame->GetBytes (&data);
|
frame->GetBytes (&data);
|
||||||
gst_buffer_extract (buffer, 0, data, gst_buffer_get_size (buffer));
|
gst_buffer_extract (buffer, 0, data, gst_buffer_get_size (buffer));
|
||||||
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
duration = GST_BUFFER_DURATION (buffer);
|
||||||
|
if (duration == GST_CLOCK_TIME_NONE) {
|
||||||
|
duration = gst_util_uint64_scale_int (GST_SECOND, mode->fps_d, mode->fps_n);
|
||||||
|
}
|
||||||
|
running_time = gst_segment_to_running_time (&decklinksink->video_segment, GST_FORMAT_TIME, timestamp);
|
||||||
|
running_time_duration = gst_segment_to_running_time (&decklinksink->video_segment, GST_FORMAT_TIME, timestamp + duration) - running_time;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
g_mutex_lock (&decklinksink->mutex);
|
g_mutex_lock (&decklinksink->mutex);
|
||||||
|
@ -495,7 +507,7 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstObject * parent,
|
||||||
|
|
||||||
if (!decklinksink->stop) {
|
if (!decklinksink->stop) {
|
||||||
ret = decklinksink->output->ScheduleVideoFrame (frame,
|
ret = decklinksink->output->ScheduleVideoFrame (frame,
|
||||||
decklinksink->num_frames * mode->fps_d, mode->fps_d, mode->fps_n);
|
running_time, running_time_duration, GST_SECOND);
|
||||||
if (ret != S_OK) {
|
if (ret != S_OK) {
|
||||||
GST_ELEMENT_ERROR (decklinksink, STREAM, FAILED,
|
GST_ELEMENT_ERROR (decklinksink, STREAM, FAILED,
|
||||||
(NULL), ("Failed to schedule frame: 0x%08x", ret));
|
(NULL), ("Failed to schedule frame: 0x%08x", ret));
|
||||||
|
@ -571,6 +583,14 @@ gst_decklink_sink_videosink_event (GstPad * pad, GstObject * parent,
|
||||||
}
|
}
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
|
case GST_EVENT_SEGMENT:
|
||||||
|
gst_event_copy_segment (event, &decklinksink->video_segment);
|
||||||
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
break;
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
gst_segment_init (&decklinksink->video_segment, GST_FORMAT_TIME);
|
||||||
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
|
@ -665,6 +685,14 @@ gst_decklink_sink_audiosink_event (GstPad * pad, GstObject * parent,
|
||||||
decklinksink->audio_seqnum = gst_event_get_seqnum (event);
|
decklinksink->audio_seqnum = gst_event_get_seqnum (event);
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
|
case GST_EVENT_SEGMENT:
|
||||||
|
gst_event_copy_segment (event, &decklinksink->audio_segment);
|
||||||
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
break;
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
gst_segment_init (&decklinksink->audio_segment, GST_FORMAT_TIME);
|
||||||
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct _GstDecklinkSink
|
||||||
gboolean audio_eos;
|
gboolean audio_eos;
|
||||||
int video_seqnum;
|
int video_seqnum;
|
||||||
int audio_seqnum;
|
int audio_seqnum;
|
||||||
|
GstSegment audio_segment, video_segment;
|
||||||
|
|
||||||
IDeckLink *decklink;
|
IDeckLink *decklink;
|
||||||
IDeckLinkOutput *output;
|
IDeckLinkOutput *output;
|
||||||
|
|
Loading…
Reference in a new issue