mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
basevideoencoder: Push the downstream force-keyframe event after the next keyframe
Even if the corresponding GstVideoFrame doesn't have the is_sync_point flag set.
This commit is contained in:
parent
209ea84ef4
commit
4501412af3
2 changed files with 17 additions and 12 deletions
|
@ -179,6 +179,7 @@ gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
|
||||||
base_video_encoder->presentation_frame_number = 0;
|
base_video_encoder->presentation_frame_number = 0;
|
||||||
base_video_encoder->distance_from_sync = 0;
|
base_video_encoder->distance_from_sync = 0;
|
||||||
base_video_encoder->force_keyframe = FALSE;
|
base_video_encoder->force_keyframe = FALSE;
|
||||||
|
base_video_encoder->force_keyframe_pending = FALSE;
|
||||||
|
|
||||||
base_video_encoder->drained = TRUE;
|
base_video_encoder->drained = TRUE;
|
||||||
base_video_encoder->min_latency = 0;
|
base_video_encoder->min_latency = 0;
|
||||||
|
@ -782,6 +783,7 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
base_video_encoder->presentation_frame_number++;
|
base_video_encoder->presentation_frame_number++;
|
||||||
frame->force_keyframe = base_video_encoder->force_keyframe;
|
frame->force_keyframe = base_video_encoder->force_keyframe;
|
||||||
base_video_encoder->force_keyframe = FALSE;
|
base_video_encoder->force_keyframe = FALSE;
|
||||||
|
base_video_encoder->force_keyframe_pending = TRUE;
|
||||||
|
|
||||||
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
|
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
|
||||||
g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
|
g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
|
||||||
|
@ -898,11 +900,20 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->force_keyframe) {
|
/* no buffer data means this frame is skipped/dropped */
|
||||||
|
if (!frame->src_buffer) {
|
||||||
|
GST_DEBUG_OBJECT (base_video_encoder, "skipping frame %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (frame->presentation_timestamp));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame->is_sync_point && base_video_encoder->force_keyframe_pending) {
|
||||||
GstClockTime stream_time;
|
GstClockTime stream_time;
|
||||||
GstClockTime running_time;
|
GstClockTime running_time;
|
||||||
GstEvent *ev;
|
GstEvent *ev;
|
||||||
|
|
||||||
|
base_video_encoder->force_keyframe_pending = FALSE;
|
||||||
|
|
||||||
running_time =
|
running_time =
|
||||||
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
||||||
(base_video_encoder)->segment, GST_FORMAT_TIME,
|
(base_video_encoder)->segment, GST_FORMAT_TIME,
|
||||||
|
@ -921,25 +932,18 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
||||||
"running-time", G_TYPE_UINT64, running_time, NULL);
|
"running-time", G_TYPE_UINT64, running_time, NULL);
|
||||||
|
|
||||||
gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder), ev);
|
gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder), ev);
|
||||||
}
|
|
||||||
|
|
||||||
/* no buffer data means this frame is skipped/dropped */
|
|
||||||
if (!frame->src_buffer) {
|
|
||||||
GST_DEBUG_OBJECT (base_video_encoder, "skipping frame %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (frame->presentation_timestamp));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->is_sync_point) {
|
|
||||||
if (base_video_encoder->force_keyframe_headers) {
|
if (base_video_encoder->force_keyframe_headers) {
|
||||||
GST_DEBUG_OBJECT (base_video_encoder, "force_keyframe_headers");
|
GST_DEBUG_OBJECT (base_video_encoder, "force_keyframe_headers");
|
||||||
if (base_video_encoder->headers) {
|
if (base_video_encoder->headers) {
|
||||||
gst_buffer_ref (base_video_encoder->headers);
|
headers = gst_buffer_ref (base_video_encoder->headers);
|
||||||
headers = base_video_encoder->headers;
|
|
||||||
}
|
}
|
||||||
base_video_encoder->force_keyframe_headers = FALSE;
|
base_video_encoder->force_keyframe_headers = FALSE;
|
||||||
}
|
}
|
||||||
GST_LOG_OBJECT (base_video_encoder, "key frame, headers %p", headers);
|
GST_LOG_OBJECT (base_video_encoder, "key frame, headers %p", headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame->is_sync_point) {
|
||||||
base_video_encoder->distance_from_sync = 0;
|
base_video_encoder->distance_from_sync = 0;
|
||||||
GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -85,6 +85,7 @@ struct _GstBaseVideoEncoder
|
||||||
int distance_from_sync;
|
int distance_from_sync;
|
||||||
|
|
||||||
gboolean force_keyframe;
|
gboolean force_keyframe;
|
||||||
|
gboolean force_keyframe_pending;
|
||||||
gboolean force_keyframe_headers;
|
gboolean force_keyframe_headers;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
Loading…
Reference in a new issue