mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
basevideo: Fix locking, especially if both pads have different streaming threads
This commit is contained in:
parent
a081501a90
commit
8c743fbc0f
4 changed files with 121 additions and 30 deletions
|
@ -97,6 +97,7 @@ gst_base_video_codec_init (GstBaseVideoCodec * base_video_codec,
|
||||||
|
|
||||||
gst_segment_init (&base_video_codec->segment, GST_FORMAT_TIME);
|
gst_segment_init (&base_video_codec->segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
g_static_rec_mutex_init (&base_video_codec->stream_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -106,24 +107,28 @@ gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_video_codec, "reset");
|
GST_DEBUG_OBJECT (base_video_codec, "reset");
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_codec);
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_codec);
|
||||||
for (g = base_video_codec->frames; g; g = g_list_next (g)) {
|
for (g = base_video_codec->frames; g; g = g_list_next (g)) {
|
||||||
gst_base_video_codec_free_frame ((GstVideoFrame *) g->data);
|
gst_base_video_codec_free_frame ((GstVideoFrame *) g->data);
|
||||||
}
|
}
|
||||||
g_list_free (base_video_codec->frames);
|
g_list_free (base_video_codec->frames);
|
||||||
base_video_codec->frames = NULL;
|
base_video_codec->frames = NULL;
|
||||||
GST_OBJECT_UNLOCK (base_video_codec);
|
|
||||||
|
|
||||||
base_video_codec->bytes = 0;
|
base_video_codec->bytes = 0;
|
||||||
base_video_codec->time = 0;
|
base_video_codec->time = 0;
|
||||||
|
|
||||||
gst_buffer_replace (&base_video_codec->state.codec_data, NULL);
|
gst_buffer_replace (&base_video_codec->state.codec_data, NULL);
|
||||||
gst_caps_replace (&base_video_codec->state.caps, NULL);
|
gst_caps_replace (&base_video_codec->state.caps, NULL);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_video_codec_finalize (GObject * object)
|
gst_base_video_codec_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
GstBaseVideoCodec *base_video_codec = GST_BASE_VIDEO_CODEC (object);
|
||||||
|
|
||||||
|
g_static_rec_mutex_free (&base_video_codec->stream_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +175,10 @@ gst_base_video_codec_new_frame (GstBaseVideoCodec * base_video_codec)
|
||||||
|
|
||||||
frame = g_slice_new0 (GstVideoFrame);
|
frame = g_slice_new0 (GstVideoFrame);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_codec);
|
||||||
frame->system_frame_number = base_video_codec->system_frame_number;
|
frame->system_frame_number = base_video_codec->system_frame_number;
|
||||||
base_video_codec->system_frame_number++;
|
base_video_codec->system_frame_number++;
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_codec);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,9 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#define GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
#define GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
||||||
|
|
||||||
|
#define GST_BASE_VIDEO_CODEC_STREAM_LOCK(codec) g_static_rec_mutex_lock (&GST_BASE_VIDEO_CODEC (codec)->stream_lock)
|
||||||
|
#define GST_BASE_VIDEO_CODEC_STREAM_UNLOCK(codec) g_static_rec_mutex_unlock (&GST_BASE_VIDEO_CODEC (codec)->stream_lock)
|
||||||
|
|
||||||
typedef struct _GstVideoState GstVideoState;
|
typedef struct _GstVideoState GstVideoState;
|
||||||
typedef struct _GstVideoFrame GstVideoFrame;
|
typedef struct _GstVideoFrame GstVideoFrame;
|
||||||
typedef struct _GstBaseVideoCodec GstBaseVideoCodec;
|
typedef struct _GstBaseVideoCodec GstBaseVideoCodec;
|
||||||
|
@ -145,6 +148,11 @@ struct _GstBaseVideoCodec
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
/* protects all data processing, i.e. is locked
|
||||||
|
* in the chain function, finish_frame and when
|
||||||
|
* processing serialized events */
|
||||||
|
GStaticRecMutex stream_lock;
|
||||||
|
|
||||||
guint64 system_frame_number;
|
guint64 system_frame_number;
|
||||||
|
|
||||||
GList *frames; /* Protected with OBJECT_LOCK */
|
GList *frames; /* Protected with OBJECT_LOCK */
|
||||||
|
|
|
@ -255,8 +255,10 @@ gst_base_video_decoder_push_src_event (GstBaseVideoDecoder * decoder,
|
||||||
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP)
|
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP)
|
||||||
return gst_pad_push_event (decoder->base_video_codec.srcpad, event);
|
return gst_pad_push_event (decoder->base_video_codec.srcpad, event);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (decoder);
|
||||||
decoder->current_frame_events =
|
decoder->current_frame_events =
|
||||||
g_list_prepend (decoder->current_frame_events, event);
|
g_list_prepend (decoder->current_frame_events, event);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (decoder);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -277,6 +279,8 @@ gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_video_decoder, "setcaps %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (base_video_decoder, "setcaps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
memset (&state, 0, sizeof (state));
|
memset (&state, 0, sizeof (state));
|
||||||
|
|
||||||
state.caps = gst_caps_ref (caps);
|
state.caps = gst_caps_ref (caps);
|
||||||
|
@ -320,6 +324,7 @@ gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
gst_caps_replace (&state.caps, NULL);
|
gst_caps_replace (&state.caps, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
g_object_unref (base_video_decoder);
|
g_object_unref (base_video_decoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -402,7 +407,8 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
{
|
{
|
||||||
GstFlowReturn flow_ret;
|
GstFlowReturn flow_ret;
|
||||||
;
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
if (!base_video_decoder->packetized) {
|
if (!base_video_decoder->packetized) {
|
||||||
do {
|
do {
|
||||||
flow_ret =
|
flow_ret =
|
||||||
|
@ -418,8 +424,9 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
if (flow_ret == GST_FLOW_OK)
|
if (flow_ret == GST_FLOW_OK)
|
||||||
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
||||||
}
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_NEWSEGMENT:
|
||||||
{
|
{
|
||||||
gboolean update;
|
gboolean update;
|
||||||
|
@ -430,6 +437,7 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
gint64 pos;
|
gint64 pos;
|
||||||
GstSegment *segment = &GST_BASE_VIDEO_CODEC (base_video_decoder)->segment;
|
GstSegment *segment = &GST_BASE_VIDEO_CODEC (base_video_decoder)->segment;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate,
|
gst_event_parse_new_segment_full (event, &update, &rate,
|
||||||
&arate, &format, &start, &stop, &pos);
|
&arate, &format, &start, &stop, &pos);
|
||||||
|
|
||||||
|
@ -466,6 +474,7 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
event = gst_event_new_new_segment_full (update, rate, arate,
|
event = gst_event_new_new_segment_full (update, rate, arate,
|
||||||
GST_FORMAT_TIME, start, stop, pos);
|
GST_FORMAT_TIME, start, stop, pos);
|
||||||
} else {
|
} else {
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
goto newseg_wrong_format;
|
goto newseg_wrong_format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,12 +489,15 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
update, rate, arate, format, start, stop, pos);
|
update, rate, arate, format, start, stop, pos);
|
||||||
|
|
||||||
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
{
|
{
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
/* well, this is kind of worse than a DISCONT */
|
/* well, this is kind of worse than a DISCONT */
|
||||||
gst_base_video_decoder_flush (base_video_decoder, TRUE);
|
gst_base_video_decoder_flush (base_video_decoder, TRUE);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* FIXME this changes the order of events */
|
/* FIXME this changes the order of events */
|
||||||
|
@ -928,6 +940,8 @@ gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder,
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (base_video_decoder, "reset full %d", full);
|
GST_DEBUG_OBJECT (base_video_decoder, "reset full %d", full);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
if (full) {
|
if (full) {
|
||||||
gst_segment_init (&GST_BASE_VIDEO_CODEC (base_video_decoder)->segment,
|
gst_segment_init (&GST_BASE_VIDEO_CODEC (base_video_decoder)->segment,
|
||||||
GST_FORMAT_UNDEFINED);
|
GST_FORMAT_UNDEFINED);
|
||||||
|
@ -963,6 +977,7 @@ gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GST_CLOCK_TIME_NONE;
|
GST_CLOCK_TIME_NONE;
|
||||||
GST_BASE_VIDEO_CODEC (base_video_decoder)->proportion = 0.5;
|
GST_BASE_VIDEO_CODEC (base_video_decoder)->proportion = 0.5;
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -1209,6 +1224,7 @@ static GstFlowReturn
|
||||||
gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstBaseVideoDecoder *base_video_decoder;
|
GstBaseVideoDecoder *base_video_decoder;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
base_video_decoder = GST_BASE_VIDEO_DECODER (GST_PAD_PARENT (pad));
|
base_video_decoder = GST_BASE_VIDEO_DECODER (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
@ -1217,6 +1233,8 @@ gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_SIZE (buf));
|
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_SIZE (buf));
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* requiring the pad to be negotiated makes it impossible to use
|
* requiring the pad to be negotiated makes it impossible to use
|
||||||
* oggdemux or filesrc ! decoder */
|
* oggdemux or filesrc ! decoder */
|
||||||
|
@ -1240,7 +1258,8 @@ gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GST_ERROR_OBJECT (base_video_decoder, "new segment event ret=%d", ret);
|
GST_ERROR_OBJECT (base_video_decoder, "new segment event ret=%d", ret);
|
||||||
return GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1268,9 +1287,13 @@ gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_BASE_VIDEO_CODEC (base_video_decoder)->segment.rate > 0.0)
|
if (GST_BASE_VIDEO_CODEC (base_video_decoder)->segment.rate > 0.0)
|
||||||
return gst_base_video_decoder_chain_forward (base_video_decoder, buf);
|
ret = gst_base_video_decoder_chain_forward (base_video_decoder, buf);
|
||||||
else
|
else
|
||||||
return gst_base_video_decoder_chain_reverse (base_video_decoder, buf);
|
ret = gst_base_video_decoder_chain_reverse (base_video_decoder, buf);
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
@ -1300,11 +1323,14 @@ gst_base_video_decoder_change_state (GstElement * element,
|
||||||
if (base_video_decoder_class->stop) {
|
if (base_video_decoder_class->stop) {
|
||||||
base_video_decoder_class->stop (base_video_decoder);
|
base_video_decoder_class->stop (base_video_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
gst_base_video_decoder_reset (base_video_decoder, TRUE);
|
gst_base_video_decoder_reset (base_video_decoder, TRUE);
|
||||||
g_list_foreach (base_video_decoder->current_frame_events,
|
g_list_foreach (base_video_decoder->current_frame_events,
|
||||||
(GFunc) gst_event_unref, NULL);
|
(GFunc) gst_event_unref, NULL);
|
||||||
g_list_free (base_video_decoder->current_frame_events);
|
g_list_free (base_video_decoder->current_frame_events);
|
||||||
base_video_decoder->current_frame_events = NULL;
|
base_video_decoder->current_frame_events = NULL;
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1318,6 +1344,7 @@ gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder)
|
||||||
{
|
{
|
||||||
GstVideoFrame *frame;
|
GstVideoFrame *frame;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
frame =
|
frame =
|
||||||
gst_base_video_codec_new_frame (GST_BASE_VIDEO_CODEC
|
gst_base_video_codec_new_frame (GST_BASE_VIDEO_CODEC
|
||||||
(base_video_decoder));
|
(base_video_decoder));
|
||||||
|
@ -1333,6 +1360,8 @@ gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder)
|
||||||
frame->events = base_video_decoder->current_frame_events;
|
frame->events = base_video_decoder->current_frame_events;
|
||||||
base_video_decoder->current_frame_events = NULL;
|
base_video_decoder->current_frame_events = NULL;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,13 +1387,13 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GList *l, *events = NULL;
|
GList *l, *events = NULL;
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder, "finish frame");
|
GST_LOG_OBJECT (base_video_decoder, "finish frame");
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
|
||||||
GST_LOG_OBJECT (base_video_decoder, "n %d in %d out %d",
|
GST_LOG_OBJECT (base_video_decoder, "n %d in %d out %d",
|
||||||
g_list_length (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames),
|
g_list_length (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames),
|
||||||
gst_adapter_available (base_video_decoder->input_adapter),
|
gst_adapter_available (base_video_decoder->input_adapter),
|
||||||
gst_adapter_available (base_video_decoder->output_adapter));
|
gst_adapter_available (base_video_decoder->output_adapter));
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder,
|
GST_LOG_OBJECT (base_video_decoder,
|
||||||
|
@ -1372,7 +1401,6 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GST_TIME_ARGS (frame->presentation_timestamp));
|
GST_TIME_ARGS (frame->presentation_timestamp));
|
||||||
|
|
||||||
/* Push all pending events that arrived before this frame */
|
/* Push all pending events that arrived before this frame */
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
|
||||||
for (l = base_video_decoder->base_video_codec.frames; l; l = l->next) {
|
for (l = base_video_decoder->base_video_codec.frames; l; l = l->next) {
|
||||||
GstVideoFrame *tmp = l->data;
|
GstVideoFrame *tmp = l->data;
|
||||||
|
|
||||||
|
@ -1388,7 +1416,6 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
if (tmp == frame)
|
if (tmp == frame)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
|
||||||
|
|
||||||
for (l = g_list_last (events); l; l = l->next)
|
for (l = g_list_last (events); l; l = l->next)
|
||||||
gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder),
|
gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder),
|
||||||
|
@ -1542,7 +1569,8 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GST_TIME_ARGS (segment->start),
|
GST_TIME_ARGS (segment->start),
|
||||||
GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time));
|
GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time));
|
||||||
gst_buffer_unref (src_buffer);
|
gst_buffer_unref (src_buffer);
|
||||||
return GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1560,12 +1588,12 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
|
||||||
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
||||||
g_list_remove (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
g_list_remove (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
|
||||||
gst_base_video_codec_free_frame (frame);
|
gst_base_video_codec_free_frame (frame);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1587,6 +1615,7 @@ gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
if (n_bytes == 0)
|
if (n_bytes == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
if (gst_adapter_available (base_video_decoder->output_adapter) == 0) {
|
if (gst_adapter_available (base_video_decoder->output_adapter) == 0) {
|
||||||
base_video_decoder->frame_offset = base_video_decoder->input_offset -
|
base_video_decoder->frame_offset = base_video_decoder->input_offset -
|
||||||
gst_adapter_available (base_video_decoder->input_adapter);
|
gst_adapter_available (base_video_decoder->input_adapter);
|
||||||
|
@ -1594,6 +1623,7 @@ gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
buf = gst_adapter_take_buffer (base_video_decoder->input_adapter, n_bytes);
|
buf = gst_adapter_take_buffer (base_video_decoder->input_adapter, n_bytes);
|
||||||
|
|
||||||
gst_adapter_push (base_video_decoder->output_adapter, buf);
|
gst_adapter_push (base_video_decoder->output_adapter, buf);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint64
|
static guint64
|
||||||
|
@ -1668,9 +1698,12 @@ gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder)
|
||||||
int n_available;
|
int n_available;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
GstClockTime duration;
|
GstClockTime duration;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder, "have_frame");
|
GST_LOG_OBJECT (base_video_decoder, "have_frame");
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
n_available = gst_adapter_available (base_video_decoder->output_adapter);
|
n_available = gst_adapter_available (base_video_decoder->output_adapter);
|
||||||
if (n_available) {
|
if (n_available) {
|
||||||
buffer = gst_adapter_take_buffer (base_video_decoder->output_adapter,
|
buffer = gst_adapter_take_buffer (base_video_decoder->output_adapter,
|
||||||
|
@ -1691,7 +1724,11 @@ gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder)
|
||||||
"ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT,
|
"ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT,
|
||||||
n_available, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
|
n_available, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
|
||||||
|
|
||||||
return gst_base_video_decoder_have_frame_2 (base_video_decoder);
|
ret = gst_base_video_decoder_have_frame_2 (base_video_decoder);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -1727,10 +1764,8 @@ gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder)
|
||||||
GST_TIME_ARGS (frame->decode_timestamp));
|
GST_TIME_ARGS (frame->decode_timestamp));
|
||||||
GST_LOG_OBJECT (base_video_decoder, "dist %d", frame->distance_from_sync);
|
GST_LOG_OBJECT (base_video_decoder, "dist %d", frame->distance_from_sync);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
|
||||||
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
||||||
g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
|
||||||
|
|
||||||
frame->deadline =
|
frame->deadline =
|
||||||
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
||||||
|
@ -1777,11 +1812,14 @@ gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_video_decoder, "lost_sync");
|
GST_DEBUG_OBJECT (base_video_decoder, "lost_sync");
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) {
|
if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) {
|
||||||
gst_adapter_flush (base_video_decoder->input_adapter, 1);
|
gst_adapter_flush (base_video_decoder->input_adapter, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
base_video_decoder->have_sync = FALSE;
|
base_video_decoder->have_sync = FALSE;
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME not quite exciting; get rid of this ? */
|
/* FIXME not quite exciting; get rid of this ? */
|
||||||
|
@ -1796,8 +1834,10 @@ gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder * base_video_decoder)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (base_video_decoder, "set_sync_point");
|
GST_DEBUG_OBJECT (base_video_decoder, "set_sync_point");
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
base_video_decoder->current_frame->is_sync_point = TRUE;
|
base_video_decoder->current_frame->is_sync_point = TRUE;
|
||||||
base_video_decoder->distance_from_sync = 0;
|
base_video_decoder->distance_from_sync = 0;
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1812,9 +1852,9 @@ gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *
|
||||||
{
|
{
|
||||||
GList *g;
|
GList *g;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
if (g == NULL)
|
if (g == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1835,7 +1875,7 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GList *g;
|
GList *g;
|
||||||
GstVideoFrame *frame = NULL;
|
GstVideoFrame *frame = NULL;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_decoder);
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
for (g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
for (g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
||||||
g; g = g_list_next (g)) {
|
g; g = g_list_next (g)) {
|
||||||
GstVideoFrame *tmp = g->data;
|
GstVideoFrame *tmp = g->data;
|
||||||
|
@ -1845,7 +1885,7 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (base_video_decoder);
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
@ -1869,6 +1909,8 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder)
|
||||||
g_return_val_if_fail (state->width != 0, FALSE);
|
g_return_val_if_fail (state->width != 0, FALSE);
|
||||||
g_return_val_if_fail (state->height != 0, FALSE);
|
g_return_val_if_fail (state->height != 0, FALSE);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
/* sanitize */
|
/* sanitize */
|
||||||
if (state->fps_n == 0 || state->fps_d == 0) {
|
if (state->fps_n == 0 || state->fps_d == 0) {
|
||||||
state->fps_n = 0;
|
state->fps_n = 0;
|
||||||
|
@ -1896,6 +1938,8 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder)
|
||||||
state->bytes_per_picture =
|
state->bytes_per_picture =
|
||||||
gst_video_format_get_size (state->format, state->width, state->height);
|
gst_video_format_get_size (state->format, state->width, state->height);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1920,6 +1964,9 @@ gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
|
||||||
|
|
||||||
GST_DEBUG ("alloc src buffer caps=%" GST_PTR_FORMAT,
|
GST_DEBUG ("alloc src buffer caps=%" GST_PTR_FORMAT,
|
||||||
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)));
|
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)));
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
flow_ret =
|
flow_ret =
|
||||||
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
|
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
|
||||||
(base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes,
|
(base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes,
|
||||||
|
@ -1932,6 +1979,7 @@ gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
|
||||||
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)));
|
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,6 +2008,8 @@ gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *
|
||||||
(base_video_decoder)) != NULL, GST_FLOW_ERROR);
|
(base_video_decoder)) != NULL, GST_FLOW_ERROR);
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder, "alloc buffer size %d", num_bytes);
|
GST_LOG_OBJECT (base_video_decoder, "alloc buffer size %d", num_bytes);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
|
||||||
|
|
||||||
flow_ret =
|
flow_ret =
|
||||||
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
|
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
|
||||||
(base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes,
|
(base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes,
|
||||||
|
@ -1971,6 +2021,8 @@ gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *
|
||||||
gst_flow_get_name (flow_ret));
|
gst_flow_get_name (flow_ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return flow_ret;
|
return flow_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,6 +2045,7 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
|
||||||
GstClockTimeDiff deadline;
|
GstClockTimeDiff deadline;
|
||||||
GstClockTime earliest_time;
|
GstClockTime earliest_time;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (base_video_decoder);
|
||||||
earliest_time = GST_BASE_VIDEO_CODEC (base_video_decoder)->earliest_time;
|
earliest_time = GST_BASE_VIDEO_CODEC (base_video_decoder)->earliest_time;
|
||||||
if (GST_CLOCK_TIME_IS_VALID (earliest_time))
|
if (GST_CLOCK_TIME_IS_VALID (earliest_time))
|
||||||
deadline = GST_CLOCK_DIFF (earliest_time, frame->deadline);
|
deadline = GST_CLOCK_DIFF (earliest_time, frame->deadline);
|
||||||
|
@ -2004,6 +2057,8 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
|
||||||
GST_TIME_ARGS (earliest_time), GST_TIME_ARGS (frame->deadline),
|
GST_TIME_ARGS (earliest_time), GST_TIME_ARGS (frame->deadline),
|
||||||
GST_TIME_ARGS (deadline));
|
GST_TIME_ARGS (deadline));
|
||||||
|
|
||||||
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return deadline;
|
return deadline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,8 @@ gst_base_video_encoder_class_init (GstBaseVideoEncoderClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
|
gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
|
||||||
{
|
{
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (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;
|
||||||
|
@ -191,6 +193,8 @@ gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
|
||||||
(GFunc) gst_event_unref, NULL);
|
(GFunc) gst_event_unref, NULL);
|
||||||
g_list_free (base_video_encoder->current_frame_events);
|
g_list_free (base_video_encoder->current_frame_events);
|
||||||
base_video_encoder->current_frame_events = NULL;
|
base_video_encoder->current_frame_events = NULL;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -283,6 +287,8 @@ gst_base_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_video_encoder, "setcaps %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (base_video_encoder, "setcaps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
|
|
||||||
state = &GST_BASE_VIDEO_CODEC (base_video_encoder)->state;
|
state = &GST_BASE_VIDEO_CODEC (base_video_encoder)->state;
|
||||||
memset (&tmp_state, 0, sizeof (tmp_state));
|
memset (&tmp_state, 0, sizeof (tmp_state));
|
||||||
|
|
||||||
|
@ -349,13 +355,15 @@ gst_base_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
g_object_unref (base_video_encoder);
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GST_WARNING_OBJECT (base_video_encoder, "rejected caps %" GST_PTR_FORMAT,
|
GST_WARNING_OBJECT (base_video_encoder, "rejected caps %" GST_PTR_FORMAT,
|
||||||
caps);
|
caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_unref (base_video_encoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,6 +458,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
||||||
{
|
{
|
||||||
GstFlowReturn flow_ret;
|
GstFlowReturn flow_ret;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
base_video_encoder->a.at_eos = TRUE;
|
base_video_encoder->a.at_eos = TRUE;
|
||||||
|
|
||||||
if (base_video_encoder_class->finish) {
|
if (base_video_encoder_class->finish) {
|
||||||
|
@ -459,6 +468,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (flow_ret == GST_BASE_VIDEO_ENCODER_FLOW_DROPPED);
|
ret = (flow_ret == GST_BASE_VIDEO_ENCODER_FLOW_DROPPED);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_NEWSEGMENT:
|
||||||
|
@ -471,6 +481,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
||||||
gint64 stop;
|
gint64 stop;
|
||||||
gint64 position;
|
gint64 position;
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
|
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
|
||||||
&format, &start, &stop, &position);
|
&format, &start, &stop, &position);
|
||||||
|
|
||||||
|
@ -482,6 +493,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
||||||
|
|
||||||
if (format != GST_FORMAT_TIME) {
|
if (format != GST_FORMAT_TIME) {
|
||||||
GST_DEBUG_OBJECT (base_video_encoder, "received non TIME newsegment");
|
GST_DEBUG_OBJECT (base_video_encoder, "received non TIME newsegment");
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +502,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
|
||||||
gst_segment_set_newsegment_full (&GST_BASE_VIDEO_CODEC
|
gst_segment_set_newsegment_full (&GST_BASE_VIDEO_CODEC
|
||||||
(base_video_encoder)->segment, update, rate, applied_rate, format,
|
(base_video_encoder)->segment, update, rate, applied_rate, format,
|
||||||
start, stop, position);
|
start, stop, position);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
||||||
|
@ -554,8 +567,10 @@ gst_base_video_encoder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
||||||
ret = gst_pad_push_event (enc->base_video_codec.srcpad, event);
|
ret = gst_pad_push_event (enc->base_video_codec.srcpad, event);
|
||||||
} else {
|
} else {
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (enc);
|
||||||
enc->current_frame_events =
|
enc->current_frame_events =
|
||||||
g_list_prepend (enc->current_frame_events, event);
|
g_list_prepend (enc->current_frame_events, event);
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (enc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,8 +712,11 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
|
g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
|
|
||||||
if (!GST_PAD_CAPS (pad)) {
|
if (!GST_PAD_CAPS (pad)) {
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_encoder,
|
GST_LOG_OBJECT (base_video_encoder,
|
||||||
|
@ -708,7 +726,8 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
||||||
|
|
||||||
if (base_video_encoder->a.at_eos) {
|
if (base_video_encoder->a.at_eos) {
|
||||||
return GST_FLOW_UNEXPECTED;
|
ret = GST_FLOW_UNEXPECTED;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_video_encoder->sink_clipping) {
|
if (base_video_encoder->sink_clipping) {
|
||||||
|
@ -744,10 +763,8 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
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;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_encoder);
|
|
||||||
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);
|
||||||
GST_OBJECT_UNLOCK (base_video_encoder);
|
|
||||||
|
|
||||||
/* new data, more finish needed */
|
/* new data, more finish needed */
|
||||||
base_video_encoder->drained = FALSE;
|
base_video_encoder->drained = FALSE;
|
||||||
|
@ -758,6 +775,8 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
ret = klass->handle_frame (base_video_encoder, frame);
|
ret = klass->handle_frame (base_video_encoder, frame);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
|
|
||||||
g_object_unref (base_video_encoder);
|
g_object_unref (base_video_encoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -829,6 +848,8 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
||||||
GST_LOG_OBJECT (base_video_encoder,
|
GST_LOG_OBJECT (base_video_encoder,
|
||||||
"finish frame fpn %d", frame->presentation_frame_number);
|
"finish frame fpn %d", frame->presentation_frame_number);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
|
|
||||||
/* Push all pending events that arrived before this frame */
|
/* Push all pending events that arrived before this frame */
|
||||||
for (l = base_video_encoder->base_video_codec.frames; l; l = l->next) {
|
for (l = base_video_encoder->base_video_codec.frames; l; l = l->next) {
|
||||||
GstVideoFrame *tmp = l->data;
|
GstVideoFrame *tmp = l->data;
|
||||||
|
@ -943,13 +964,13 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* handed out */
|
/* handed out */
|
||||||
GST_OBJECT_LOCK (base_video_encoder);
|
|
||||||
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
|
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
|
||||||
g_list_remove (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
|
g_list_remove (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
|
||||||
GST_OBJECT_UNLOCK (base_video_encoder);
|
|
||||||
|
|
||||||
gst_base_video_codec_free_frame (frame);
|
gst_base_video_codec_free_frame (frame);
|
||||||
|
|
||||||
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,9 +1044,9 @@ gst_base_video_encoder_get_oldest_frame (GstBaseVideoEncoder *
|
||||||
{
|
{
|
||||||
GList *g;
|
GList *g;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (base_video_encoder);
|
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
|
||||||
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames);
|
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames);
|
||||||
GST_OBJECT_UNLOCK (base_video_encoder);
|
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
|
||||||
|
|
||||||
if (g == NULL)
|
if (g == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue