mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
ffenc: Make keyframe forcing thread-safe
Make the keyframe forcing thread-safe, also emit a downstream event to allow muxers or payloaders to react appropriately. https://bugzilla.gnome.org/show_bug.cgi?id=602556
This commit is contained in:
parent
08160ac0ef
commit
b69fcc471e
2 changed files with 29 additions and 2 deletions
|
@ -686,11 +686,20 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf)
|
||||||
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) (GST_PAD_PARENT (pad));
|
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) (GST_PAD_PARENT (pad));
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
gint ret_size = 0, frame_size;
|
gint ret_size = 0, frame_size;
|
||||||
|
gboolean force_keyframe;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegenc,
|
GST_DEBUG_OBJECT (ffmpegenc,
|
||||||
"Received buffer of time %" GST_TIME_FORMAT,
|
"Received buffer of time %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)));
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (ffmpegenc);
|
||||||
|
force_keyframe = ffmpegenc->force_keyframe;
|
||||||
|
ffmpegenc->force_keyframe = FALSE;
|
||||||
|
GST_OBJECT_UNLOCK (ffmpegenc);
|
||||||
|
|
||||||
|
if (force_keyframe)
|
||||||
|
ffmpegenc->picture->pict_type = FF_I_TYPE;
|
||||||
|
|
||||||
frame_size = gst_ffmpeg_avpicture_fill ((AVPicture *) ffmpegenc->picture,
|
frame_size = gst_ffmpeg_avpicture_fill ((AVPicture *) ffmpegenc->picture,
|
||||||
GST_BUFFER_DATA (inbuf),
|
GST_BUFFER_DATA (inbuf),
|
||||||
ffmpegenc->context->pix_fmt,
|
ffmpegenc->context->pix_fmt,
|
||||||
|
@ -751,6 +760,14 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf)
|
||||||
if (ffmpegenc->picture->pict_type)
|
if (ffmpegenc->picture->pict_type)
|
||||||
ffmpegenc->picture->pict_type = 0;
|
ffmpegenc->picture->pict_type = 0;
|
||||||
|
|
||||||
|
if (force_keyframe) {
|
||||||
|
gst_pad_push_event (ffmpegenc->srcpad,
|
||||||
|
gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
|
||||||
|
gst_structure_new ("GstForceKeyUnit",
|
||||||
|
"timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (outbuf),
|
||||||
|
NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
return gst_pad_push (ffmpegenc->srcpad, outbuf);
|
return gst_pad_push (ffmpegenc->srcpad, outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,13 +1045,18 @@ static gboolean
|
||||||
gst_ffmpegenc_event_src (GstPad * pad, GstEvent * event)
|
gst_ffmpegenc_event_src (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) (GST_PAD_PARENT (pad));
|
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) (GST_PAD_PARENT (pad));
|
||||||
|
gboolean forward = TRUE;
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_CUSTOM_UPSTREAM:{
|
case GST_EVENT_CUSTOM_UPSTREAM:{
|
||||||
const GstStructure *s;
|
const GstStructure *s;
|
||||||
s = gst_event_get_structure (event);
|
s = gst_event_get_structure (event);
|
||||||
if (gst_structure_has_name (s, "GstForceKeyUnit")) {
|
if (gst_structure_has_name (s, "GstForceKeyUnit")) {
|
||||||
ffmpegenc->picture->pict_type = FF_I_TYPE;
|
GST_OBJECT_LOCK (ffmpegenc);
|
||||||
|
ffmpegenc->force_keyframe = TRUE;
|
||||||
|
GST_OBJECT_UNLOCK (ffmpegenc);
|
||||||
|
forward = FALSE;
|
||||||
|
gst_event_unref (event);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1065,10 @@ gst_ffmpegenc_event_src (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gst_pad_push_event (ffmpegenc->sinkpad, event);
|
if (forward)
|
||||||
|
return gst_pad_push_event (ffmpegenc->sinkpad, event);
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -74,6 +74,8 @@ struct _GstFFMpegEnc
|
||||||
/* other settings are copied over straight,
|
/* other settings are copied over straight,
|
||||||
* include a context here, rather than copy-and-past it from avcodec.h */
|
* include a context here, rather than copy-and-past it from avcodec.h */
|
||||||
AVCodecContext config;
|
AVCodecContext config;
|
||||||
|
|
||||||
|
gboolean force_keyframe;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstFFMpegEncClass GstFFMpegEncClass;
|
typedef struct _GstFFMpegEncClass GstFFMpegEncClass;
|
||||||
|
|
Loading…
Reference in a new issue