textoverlay: Synchronize video/text based on the running time
Instead of simply using the buffer timestamps.
This commit is contained in:
parent
8ed8d5e414
commit
45cefdefa6
@ -1850,16 +1850,6 @@ gst_text_overlay_pop_text (GstTextOverlay * overlay)
|
|||||||
g_return_if_fail (GST_IS_TEXT_OVERLAY (overlay));
|
g_return_if_fail (GST_IS_TEXT_OVERLAY (overlay));
|
||||||
|
|
||||||
if (overlay->text_buffer) {
|
if (overlay->text_buffer) {
|
||||||
/* update text_segment's last stop */
|
|
||||||
if (overlay->text_segment.format == GST_FORMAT_TIME &&
|
|
||||||
GST_BUFFER_TIMESTAMP_IS_VALID (overlay->text_buffer)) {
|
|
||||||
overlay->text_segment.last_stop =
|
|
||||||
GST_BUFFER_TIMESTAMP (overlay->text_buffer);
|
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (overlay->text_buffer)) {
|
|
||||||
overlay->text_segment.last_stop +=
|
|
||||||
GST_BUFFER_DURATION (overlay->text_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GST_DEBUG_OBJECT (overlay, "releasing text buffer %p",
|
GST_DEBUG_OBJECT (overlay, "releasing text buffer %p",
|
||||||
overlay->text_buffer);
|
overlay->text_buffer);
|
||||||
gst_buffer_unref (overlay->text_buffer);
|
gst_buffer_unref (overlay->text_buffer);
|
||||||
@ -2067,8 +2057,12 @@ wait_for_text_buf:
|
|||||||
} else {
|
} else {
|
||||||
/* Text pad linked, check if we have a text buffer queued */
|
/* Text pad linked, check if we have a text buffer queued */
|
||||||
if (overlay->text_buffer) {
|
if (overlay->text_buffer) {
|
||||||
gboolean pop_text = FALSE;
|
gboolean pop_text = FALSE, valid_text_time = TRUE;
|
||||||
gint64 text_start, text_end;
|
GstClockTime text_start = GST_CLOCK_TIME_NONE;
|
||||||
|
GstClockTime text_end = GST_CLOCK_TIME_NONE;
|
||||||
|
GstClockTime text_running_time = GST_CLOCK_TIME_NONE;
|
||||||
|
GstClockTime text_running_time_end = GST_CLOCK_TIME_NONE;
|
||||||
|
GstClockTime vid_running_time, vid_running_time_end;
|
||||||
|
|
||||||
/* if the text buffer isn't stamped right, pop it off the
|
/* if the text buffer isn't stamped right, pop it off the
|
||||||
* queue and display it for the current video frame only */
|
* queue and display it for the current video frame only */
|
||||||
@ -2076,28 +2070,46 @@ wait_for_text_buf:
|
|||||||
!GST_BUFFER_DURATION_IS_VALID (overlay->text_buffer)) {
|
!GST_BUFFER_DURATION_IS_VALID (overlay->text_buffer)) {
|
||||||
GST_WARNING_OBJECT (overlay,
|
GST_WARNING_OBJECT (overlay,
|
||||||
"Got text buffer with invalid timestamp or duration");
|
"Got text buffer with invalid timestamp or duration");
|
||||||
text_start = start;
|
|
||||||
text_end = stop;
|
|
||||||
pop_text = TRUE;
|
pop_text = TRUE;
|
||||||
|
valid_text_time = FALSE;
|
||||||
} else {
|
} else {
|
||||||
text_start = GST_BUFFER_TIMESTAMP (overlay->text_buffer);
|
text_start = GST_BUFFER_TIMESTAMP (overlay->text_buffer);
|
||||||
text_end = text_start + GST_BUFFER_DURATION (overlay->text_buffer);
|
text_end = text_start + GST_BUFFER_DURATION (overlay->text_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vid_running_time =
|
||||||
|
gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
|
||||||
|
start);
|
||||||
|
vid_running_time_end =
|
||||||
|
gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
|
||||||
|
stop);
|
||||||
|
|
||||||
|
/* If timestamp and duration are valid */
|
||||||
|
if (valid_text_time) {
|
||||||
|
text_running_time =
|
||||||
|
gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
|
||||||
|
text_start);
|
||||||
|
text_running_time_end =
|
||||||
|
gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
|
||||||
|
text_end);
|
||||||
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (overlay, "T: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (overlay, "T: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (text_start), GST_TIME_ARGS (text_end));
|
GST_TIME_ARGS (text_running_time),
|
||||||
|
GST_TIME_ARGS (text_running_time_end));
|
||||||
GST_LOG_OBJECT (overlay, "V: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (overlay, "V: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
|
GST_TIME_ARGS (vid_running_time),
|
||||||
|
GST_TIME_ARGS (vid_running_time_end));
|
||||||
|
|
||||||
/* Text too old or in the future */
|
/* Text too old or in the future */
|
||||||
if (text_end <= start) {
|
if (valid_text_time && text_running_time_end <= vid_running_time) {
|
||||||
/* text buffer too old, get rid of it and do nothing */
|
/* text buffer too old, get rid of it and do nothing */
|
||||||
GST_LOG_OBJECT (overlay, "text buffer too old, popping");
|
GST_LOG_OBJECT (overlay, "text buffer too old, popping");
|
||||||
pop_text = FALSE;
|
pop_text = FALSE;
|
||||||
gst_text_overlay_pop_text (overlay);
|
gst_text_overlay_pop_text (overlay);
|
||||||
GST_OBJECT_UNLOCK (overlay);
|
GST_OBJECT_UNLOCK (overlay);
|
||||||
goto wait_for_text_buf;
|
goto wait_for_text_buf;
|
||||||
} else if (stop <= text_start) {
|
} else if (valid_text_time && vid_running_time_end <= text_running_time) {
|
||||||
GST_LOG_OBJECT (overlay, "text in future, pushing video buf");
|
GST_LOG_OBJECT (overlay, "text in future, pushing video buf");
|
||||||
GST_OBJECT_UNLOCK (overlay);
|
GST_OBJECT_UNLOCK (overlay);
|
||||||
/* Push the video frame */
|
/* Push the video frame */
|
||||||
@ -2148,7 +2160,7 @@ wait_for_text_buf:
|
|||||||
GST_OBJECT_UNLOCK (overlay);
|
GST_OBJECT_UNLOCK (overlay);
|
||||||
ret = gst_text_overlay_push_frame (overlay, buffer);
|
ret = gst_text_overlay_push_frame (overlay, buffer);
|
||||||
|
|
||||||
if (text_end <= stop) {
|
if (valid_text_time && text_running_time_end <= vid_running_time_end) {
|
||||||
GST_LOG_OBJECT (overlay, "text buffer not needed any longer");
|
GST_LOG_OBJECT (overlay, "text buffer not needed any longer");
|
||||||
pop_text = TRUE;
|
pop_text = TRUE;
|
||||||
}
|
}
|
||||||
@ -2169,8 +2181,23 @@ wait_for_text_buf:
|
|||||||
|
|
||||||
/* Text pad linked, but no text buffer available - what now? */
|
/* Text pad linked, but no text buffer available - what now? */
|
||||||
if (overlay->text_segment.format == GST_FORMAT_TIME) {
|
if (overlay->text_segment.format == GST_FORMAT_TIME) {
|
||||||
if (GST_BUFFER_TIMESTAMP (buffer) < overlay->text_segment.start ||
|
GstClockTime text_start_running_time, text_last_stop_running_time;
|
||||||
GST_BUFFER_TIMESTAMP (buffer) < overlay->text_segment.last_stop) {
|
GstClockTime vid_running_time;
|
||||||
|
|
||||||
|
vid_running_time =
|
||||||
|
gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer));
|
||||||
|
text_start_running_time =
|
||||||
|
gst_segment_to_running_time (&overlay->text_segment,
|
||||||
|
GST_FORMAT_TIME, overlay->text_segment.start);
|
||||||
|
text_last_stop_running_time =
|
||||||
|
gst_segment_to_running_time (&overlay->text_segment,
|
||||||
|
GST_FORMAT_TIME, overlay->text_segment.last_stop);
|
||||||
|
|
||||||
|
if ((GST_CLOCK_TIME_IS_VALID (text_start_running_time) &&
|
||||||
|
vid_running_time < text_start_running_time) ||
|
||||||
|
(GST_CLOCK_TIME_IS_VALID (text_last_stop_running_time) &&
|
||||||
|
vid_running_time < text_last_stop_running_time)) {
|
||||||
wait_for_text_buf = FALSE;
|
wait_for_text_buf = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user