basevideo: Fix locking, especially if both pads have different streaming threads

This commit is contained in:
Sebastian Dröge 2011-08-18 08:02:50 +00:00
parent a081501a90
commit 8c743fbc0f
4 changed files with 121 additions and 30 deletions

View file

@ -97,6 +97,7 @@ gst_base_video_codec_init (GstBaseVideoCodec * base_video_codec,
gst_segment_init (&base_video_codec->segment, GST_FORMAT_TIME);
g_static_rec_mutex_init (&base_video_codec->stream_lock);
}
static void
@ -106,24 +107,28 @@ gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec)
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)) {
gst_base_video_codec_free_frame ((GstVideoFrame *) g->data);
}
g_list_free (base_video_codec->frames);
base_video_codec->frames = NULL;
GST_OBJECT_UNLOCK (base_video_codec);
base_video_codec->bytes = 0;
base_video_codec->time = 0;
gst_buffer_replace (&base_video_codec->state.codec_data, NULL);
gst_caps_replace (&base_video_codec->state.caps, NULL);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_codec);
}
static void
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);
}
@ -170,8 +175,10 @@ gst_base_video_codec_new_frame (GstBaseVideoCodec * base_video_codec)
frame = g_slice_new0 (GstVideoFrame);
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_codec);
frame->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;
}

View file

@ -79,6 +79,9 @@ G_BEGIN_DECLS
*/
#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 _GstVideoFrame GstVideoFrame;
typedef struct _GstBaseVideoCodec GstBaseVideoCodec;
@ -145,6 +148,11 @@ struct _GstBaseVideoCodec
GstPad *sinkpad;
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;
GList *frames; /* Protected with OBJECT_LOCK */

View file

@ -255,8 +255,10 @@ gst_base_video_decoder_push_src_event (GstBaseVideoDecoder * decoder,
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP)
return gst_pad_push_event (decoder->base_video_codec.srcpad, event);
GST_BASE_VIDEO_CODEC_STREAM_LOCK (decoder);
decoder->current_frame_events =
g_list_prepend (decoder->current_frame_events, event);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (decoder);
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_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
memset (&state, 0, sizeof (state));
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_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
g_object_unref (base_video_decoder);
return ret;
@ -402,7 +407,8 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
case GST_EVENT_EOS:
{
GstFlowReturn flow_ret;
;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
if (!base_video_decoder->packetized) {
do {
flow_ret =
@ -418,8 +424,9 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
if (flow_ret == GST_FLOW_OK)
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
}
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
break;
}
case GST_EVENT_NEWSEGMENT:
{
gboolean update;
@ -430,6 +437,7 @@ gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
gint64 pos;
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,
&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,
GST_FORMAT_TIME, start, stop, pos);
} else {
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
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);
ret = gst_base_video_decoder_push_src_event (base_video_decoder, event);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
break;
}
case GST_EVENT_FLUSH_STOP:
{
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
/* well, this is kind of worse than a DISCONT */
gst_base_video_decoder_flush (base_video_decoder, TRUE);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
}
default:
/* 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_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
if (full) {
gst_segment_init (&GST_BASE_VIDEO_CODEC (base_video_decoder)->segment,
GST_FORMAT_UNDEFINED);
@ -963,6 +977,7 @@ gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder,
GST_CLOCK_TIME_NONE;
GST_BASE_VIDEO_CODEC (base_video_decoder)->proportion = 0.5;
GST_OBJECT_UNLOCK (base_video_decoder);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
}
static GstFlowReturn
@ -1209,6 +1224,7 @@ static GstFlowReturn
gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
{
GstBaseVideoDecoder *base_video_decoder;
GstFlowReturn ret = GST_FLOW_OK;
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_DURATION (buf)), GST_BUFFER_SIZE (buf));
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
/* NOTE:
* requiring the pad to be negotiated makes it impossible to use
* 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);
if (!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)
return gst_base_video_decoder_chain_forward (base_video_decoder, buf);
ret = gst_base_video_decoder_chain_forward (base_video_decoder, buf);
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
@ -1300,11 +1323,14 @@ gst_base_video_decoder_change_state (GstElement * element,
if (base_video_decoder_class->stop) {
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);
g_list_foreach (base_video_decoder->current_frame_events,
(GFunc) gst_event_unref, NULL);
g_list_free (base_video_decoder->current_frame_events);
base_video_decoder->current_frame_events = NULL;
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
break;
default:
break;
@ -1318,6 +1344,7 @@ gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder)
{
GstVideoFrame *frame;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
frame =
gst_base_video_codec_new_frame (GST_BASE_VIDEO_CODEC
(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;
base_video_decoder->current_frame_events = NULL;
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
return frame;
}
@ -1358,13 +1387,13 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
GList *l, *events = NULL;
GST_LOG_OBJECT (base_video_decoder, "finish frame");
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
#ifndef GST_DISABLE_GST_DEBUG
GST_OBJECT_LOCK (base_video_decoder);
GST_LOG_OBJECT (base_video_decoder, "n %d in %d out %d",
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->output_adapter));
GST_OBJECT_UNLOCK (base_video_decoder);
#endif
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));
/* 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) {
GstVideoFrame *tmp = l->data;
@ -1388,7 +1416,6 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
if (tmp == frame)
break;
}
GST_OBJECT_UNLOCK (base_video_decoder);
for (l = g_list_last (events); l; l = l->next)
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->stop), GST_TIME_ARGS (segment->time));
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:
GST_OBJECT_LOCK (base_video_decoder);
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
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_STREAM_UNLOCK (base_video_decoder);
return ret;
}
@ -1587,6 +1615,7 @@ gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder,
if (n_bytes == 0)
return;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
if (gst_adapter_available (base_video_decoder->output_adapter) == 0) {
base_video_decoder->frame_offset = base_video_decoder->input_offset -
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);
gst_adapter_push (base_video_decoder->output_adapter, buf);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
}
static guint64
@ -1668,9 +1698,12 @@ gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder)
int n_available;
GstClockTime timestamp;
GstClockTime duration;
GstFlowReturn ret = GST_FLOW_OK;
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);
if (n_available) {
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,
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
@ -1727,10 +1764,8 @@ gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder)
GST_TIME_ARGS (frame->decode_timestamp));
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 =
g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
GST_OBJECT_UNLOCK (base_video_decoder);
frame->deadline =
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_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) {
gst_adapter_flush (base_video_decoder->input_adapter, 1);
}
base_video_decoder->have_sync = FALSE;
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
}
/* 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_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
base_video_decoder->current_frame->is_sync_point = TRUE;
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;
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);
GST_OBJECT_UNLOCK (base_video_decoder);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
if (g == NULL)
return NULL;
@ -1835,7 +1875,7 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
GList *g;
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);
g; g = g_list_next (g)) {
GstVideoFrame *tmp = g->data;
@ -1845,7 +1885,7 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
break;
}
}
GST_OBJECT_UNLOCK (base_video_decoder);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
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->height != 0, FALSE);
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
/* sanitize */
if (state->fps_n == 0 || state->fps_d == 0) {
state->fps_n = 0;
@ -1896,6 +1938,8 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder)
state->bytes_per_picture =
gst_video_format_get_size (state->format, state->width, state->height);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
return ret;
}
@ -1920,6 +1964,9 @@ gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
GST_DEBUG ("alloc src buffer caps=%" GST_PTR_FORMAT,
GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)));
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
flow_ret =
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
(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_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
return buffer;
}
@ -1960,6 +2008,8 @@ gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *
(base_video_decoder)) != NULL, GST_FLOW_ERROR);
GST_LOG_OBJECT (base_video_decoder, "alloc buffer size %d", num_bytes);
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_decoder);
flow_ret =
gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
(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_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_decoder);
return flow_ret;
}
@ -1993,6 +2045,7 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
GstClockTimeDiff deadline;
GstClockTime earliest_time;
GST_OBJECT_LOCK (base_video_decoder);
earliest_time = GST_BASE_VIDEO_CODEC (base_video_decoder)->earliest_time;
if (GST_CLOCK_TIME_IS_VALID (earliest_time))
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 (deadline));
GST_OBJECT_UNLOCK (base_video_decoder);
return deadline;
}

View file

@ -174,6 +174,8 @@ gst_base_video_encoder_class_init (GstBaseVideoEncoderClass * klass)
static void
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->distance_from_sync = 0;
base_video_encoder->force_keyframe = FALSE;
@ -191,6 +193,8 @@ gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
(GFunc) gst_event_unref, NULL);
g_list_free (base_video_encoder->current_frame_events);
base_video_encoder->current_frame_events = NULL;
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
}
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_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
state = &GST_BASE_VIDEO_CODEC (base_video_encoder)->state;
memset (&tmp_state, 0, sizeof (tmp_state));
@ -349,13 +355,15 @@ gst_base_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
}
exit:
g_object_unref (base_video_encoder);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
if (!ret) {
GST_WARNING_OBJECT (base_video_encoder, "rejected caps %" GST_PTR_FORMAT,
caps);
}
g_object_unref (base_video_encoder);
return ret;
}
@ -450,6 +458,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
{
GstFlowReturn flow_ret;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
base_video_encoder->a.at_eos = TRUE;
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);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
break;
}
case GST_EVENT_NEWSEGMENT:
@ -471,6 +481,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
gint64 stop;
gint64 position;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
&format, &start, &stop, &position);
@ -482,6 +493,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
if (format != GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (base_video_encoder, "received non TIME newsegment");
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
break;
}
@ -490,6 +502,7 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
gst_segment_set_newsegment_full (&GST_BASE_VIDEO_CODEC
(base_video_encoder)->segment, update, rate, applied_rate, format,
start, stop, position);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
break;
}
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) {
ret = gst_pad_push_event (enc->base_video_codec.srcpad, event);
} else {
GST_BASE_VIDEO_CODEC_STREAM_LOCK (enc);
enc->current_frame_events =
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);
GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder);
if (!GST_PAD_CAPS (pad)) {
return GST_FLOW_NOT_NEGOTIATED;
ret = GST_FLOW_NOT_NEGOTIATED;
goto done;
}
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)));
if (base_video_encoder->a.at_eos) {
return GST_FLOW_UNEXPECTED;
ret = GST_FLOW_UNEXPECTED;
goto done;
}
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;
base_video_encoder->force_keyframe = FALSE;
GST_OBJECT_LOCK (base_video_encoder);
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
GST_OBJECT_UNLOCK (base_video_encoder);
/* new data, more finish needed */
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);
done:
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
g_object_unref (base_video_encoder);
return ret;
@ -829,6 +848,8 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
GST_LOG_OBJECT (base_video_encoder,
"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 */
for (l = base_video_encoder->base_video_codec.frames; l; l = l->next) {
GstVideoFrame *tmp = l->data;
@ -943,13 +964,13 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
done:
/* handed out */
GST_OBJECT_LOCK (base_video_encoder);
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
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_STREAM_UNLOCK (base_video_encoder);
return ret;
}
@ -1023,9 +1044,9 @@ gst_base_video_encoder_get_oldest_frame (GstBaseVideoEncoder *
{
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);
GST_OBJECT_UNLOCK (base_video_encoder);
GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder);
if (g == NULL)
return NULL;