mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
basevideoencoder: Add initial support for the all-headers field of the force-keyframe event
See bug #607742.
This commit is contained in:
parent
135239605f
commit
54cb226009
2 changed files with 52 additions and 2 deletions
|
@ -188,6 +188,7 @@ gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
|
|||
gst_event_unref (base_video_encoder->force_keyunit_event);
|
||||
base_video_encoder->force_keyunit_event = NULL;
|
||||
}
|
||||
gst_buffer_replace (&base_video_encoder->headers, NULL);
|
||||
|
||||
g_list_foreach (base_video_encoder->current_frame_events,
|
||||
(GFunc) gst_event_unref, NULL);
|
||||
|
@ -226,11 +227,20 @@ gst_base_video_encoder_init (GstBaseVideoEncoder * base_video_encoder,
|
|||
GST_DEBUG_FUNCPTR (gst_base_video_encoder_src_event));
|
||||
|
||||
base_video_encoder->a.at_eos = FALSE;
|
||||
base_video_encoder->headers = NULL;
|
||||
|
||||
/* encoder is expected to do so */
|
||||
base_video_encoder->sink_clipping = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_base_video_encoder_set_headers (GstBaseVideoEncoder * base_video_encoder,
|
||||
GstBuffer * headers)
|
||||
{
|
||||
GST_DEBUG_OBJECT (base_video_encoder, "new headers %p", headers);
|
||||
gst_buffer_replace (&base_video_encoder->headers, headers);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_base_video_encoder_drain (GstBaseVideoEncoder * enc)
|
||||
{
|
||||
|
@ -439,8 +449,13 @@ done:
|
|||
static void
|
||||
gst_base_video_encoder_finalize (GObject * object)
|
||||
{
|
||||
GstBaseVideoEncoder *base_video_encoder;
|
||||
|
||||
GST_DEBUG_OBJECT (object, "finalize");
|
||||
|
||||
base_video_encoder = GST_BASE_VIDEO_ENCODER (object);
|
||||
gst_buffer_replace (&base_video_encoder->headers, NULL);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -515,9 +530,15 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
|||
if (gst_structure_has_name (s, "GstForceKeyUnit")) {
|
||||
GST_OBJECT_LOCK (base_video_encoder);
|
||||
base_video_encoder->force_keyframe = TRUE;
|
||||
if (!gst_structure_get_boolean (s, "all-headers",
|
||||
&base_video_encoder->force_keyframe_headers))
|
||||
base_video_encoder->force_keyframe_headers = FALSE;
|
||||
|
||||
if (base_video_encoder->force_keyunit_event)
|
||||
gst_event_unref (base_video_encoder->force_keyunit_event);
|
||||
base_video_encoder->force_keyunit_event = gst_event_copy (event);
|
||||
GST_DEBUG_OBJECT (base_video_encoder, "GstForceKeyUnit, all-headers %d",
|
||||
base_video_encoder->force_keyframe_headers);
|
||||
GST_OBJECT_UNLOCK (base_video_encoder);
|
||||
gst_event_unref (event);
|
||||
ret = TRUE;
|
||||
|
@ -602,9 +623,14 @@ gst_base_video_encoder_src_event (GstPad * pad, GstEvent * event)
|
|||
if (gst_structure_has_name (s, "GstForceKeyUnit")) {
|
||||
GST_OBJECT_LOCK (base_video_encoder);
|
||||
base_video_encoder->force_keyframe = TRUE;
|
||||
if (!gst_structure_get_boolean (s, "all-headers",
|
||||
&base_video_encoder->force_keyframe_headers))
|
||||
base_video_encoder->force_keyframe_headers = FALSE;
|
||||
GST_OBJECT_UNLOCK (base_video_encoder);
|
||||
|
||||
gst_event_unref (event);
|
||||
GST_DEBUG_OBJECT (base_video_encoder, "GstForceKeyUnit, all-headers %d",
|
||||
base_video_encoder->force_keyframe_headers);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
ret =
|
||||
|
@ -851,6 +877,7 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstBaseVideoEncoderClass *base_video_encoder_class;
|
||||
GList *l;
|
||||
GstBuffer *headers = NULL;
|
||||
|
||||
base_video_encoder_class =
|
||||
GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder);
|
||||
|
@ -920,7 +947,15 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
|||
}
|
||||
|
||||
if (frame->is_sync_point) {
|
||||
GST_LOG_OBJECT (base_video_encoder, "key frame");
|
||||
if (base_video_encoder->force_keyframe_headers) {
|
||||
GST_DEBUG_OBJECT (base_video_encoder, "force_keyframe_headers");
|
||||
if (base_video_encoder->headers) {
|
||||
gst_buffer_ref (base_video_encoder->headers);
|
||||
headers = base_video_encoder->headers;
|
||||
}
|
||||
base_video_encoder->force_keyframe_headers = FALSE;
|
||||
}
|
||||
GST_LOG_OBJECT (base_video_encoder, "key frame, headers %p", headers);
|
||||
base_video_encoder->distance_from_sync = 0;
|
||||
GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
} else {
|
||||
|
@ -943,6 +978,12 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
|||
GST_BUFFER_DURATION (frame->src_buffer) = frame->presentation_duration;
|
||||
GST_BUFFER_OFFSET (frame->src_buffer) = frame->decode_timestamp;
|
||||
|
||||
if (G_UNLIKELY (headers)) {
|
||||
GST_BUFFER_TIMESTAMP (headers) = frame->presentation_timestamp;
|
||||
GST_BUFFER_DURATION (headers) = 0;
|
||||
GST_BUFFER_OFFSET (headers) = frame->decode_timestamp;
|
||||
}
|
||||
|
||||
/* update rate estimate */
|
||||
GST_BASE_VIDEO_CODEC (base_video_encoder)->bytes +=
|
||||
GST_BUFFER_SIZE (frame->src_buffer);
|
||||
|
@ -963,6 +1004,12 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
|||
gst_buffer_set_caps (GST_BUFFER (frame->src_buffer),
|
||||
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder)));
|
||||
|
||||
if (G_UNLIKELY (headers)) {
|
||||
gst_buffer_set_caps (headers,
|
||||
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder)));
|
||||
gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder), headers);
|
||||
}
|
||||
|
||||
if (base_video_encoder_class->shape_output) {
|
||||
ret = base_video_encoder_class->shape_output (base_video_encoder, frame);
|
||||
} else {
|
||||
|
|
|
@ -85,6 +85,7 @@ struct _GstBaseVideoEncoder
|
|||
int distance_from_sync;
|
||||
|
||||
gboolean force_keyframe;
|
||||
gboolean force_keyframe_headers;
|
||||
|
||||
/*< private >*/
|
||||
/* FIXME move to real private part ?
|
||||
|
@ -96,6 +97,7 @@ struct _GstBaseVideoEncoder
|
|||
|
||||
GstEvent *force_keyunit_event;
|
||||
GList *current_frame_events;
|
||||
GstBuffer *headers;
|
||||
|
||||
union {
|
||||
void *padding;
|
||||
|
@ -178,7 +180,8 @@ void gst_base_video_encoder_set_latency (GstBaseVideoEncoder *
|
|||
GstClockTime min_latency, GstClockTime max_latency);
|
||||
void gst_base_video_encoder_set_latency_fields (GstBaseVideoEncoder *base_video_encoder,
|
||||
int n_fields);
|
||||
|
||||
void gst_base_video_encoder_set_headers (GstBaseVideoEncoder *base_video_encoder,
|
||||
GstBuffer *headers);
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue