mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
video: Use GQueue instead of plain GList in a few places
Also not optimal but at least simplifies the code a bit and doesn't require g_list_length() and g_list_append() in a few places. For 2.0 there are some more candidates to change but unfortunately they're currently part of the API. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/683>
This commit is contained in:
parent
4fcc1121e6
commit
caaa5ac864
3 changed files with 94 additions and 63 deletions
|
@ -335,8 +335,10 @@ struct _GstVideoDecoderPrivate
|
||||||
* only available during parsing */
|
* only available during parsing */
|
||||||
GstVideoCodecFrame *current_frame;
|
GstVideoCodecFrame *current_frame;
|
||||||
/* events that should apply to the current frame */
|
/* events that should apply to the current frame */
|
||||||
|
/* FIXME 2.0: Use a GQueue or similar, see GstVideoCodecFrame::events */
|
||||||
GList *current_frame_events;
|
GList *current_frame_events;
|
||||||
/* events that should be pushed before the next frame */
|
/* events that should be pushed before the next frame */
|
||||||
|
/* FIXME 2.0: Use a GQueue or similar, see GstVideoCodecFrame::events */
|
||||||
GList *pending_events;
|
GList *pending_events;
|
||||||
|
|
||||||
/* relative offset of input data */
|
/* relative offset of input data */
|
||||||
|
@ -344,7 +346,7 @@ struct _GstVideoDecoderPrivate
|
||||||
/* relative offset of frame */
|
/* relative offset of frame */
|
||||||
guint64 frame_offset;
|
guint64 frame_offset;
|
||||||
/* tracking ts and offsets */
|
/* tracking ts and offsets */
|
||||||
GList *timestamps;
|
GQueue timestamps;
|
||||||
|
|
||||||
/* last outgoing ts */
|
/* last outgoing ts */
|
||||||
GstClockTime last_timestamp_out;
|
GstClockTime last_timestamp_out;
|
||||||
|
@ -352,6 +354,7 @@ struct _GstVideoDecoderPrivate
|
||||||
GstClockTime pts_delta;
|
GstClockTime pts_delta;
|
||||||
gboolean reordered_output;
|
gboolean reordered_output;
|
||||||
|
|
||||||
|
/* FIXME: Consider using a GQueue or other better fitting data structure */
|
||||||
/* reverse playback */
|
/* reverse playback */
|
||||||
/* collect input */
|
/* collect input */
|
||||||
GList *gather;
|
GList *gather;
|
||||||
|
@ -377,7 +380,7 @@ struct _GstVideoDecoderPrivate
|
||||||
guint32 system_frame_number;
|
guint32 system_frame_number;
|
||||||
guint32 decode_frame_number;
|
guint32 decode_frame_number;
|
||||||
|
|
||||||
GList *frames; /* Protected with OBJECT_LOCK */
|
GQueue frames; /* Protected with OBJECT_LOCK */
|
||||||
GstVideoCodecState *input_state;
|
GstVideoCodecState *input_state;
|
||||||
GstVideoCodecState *output_state; /* OBJECT_LOCK and STREAM_LOCK */
|
GstVideoCodecState *output_state; /* OBJECT_LOCK and STREAM_LOCK */
|
||||||
gboolean output_state_changed;
|
gboolean output_state_changed;
|
||||||
|
@ -617,6 +620,9 @@ gst_video_decoder_init (GstVideoDecoder * decoder, GstVideoDecoderClass * klass)
|
||||||
decoder->priv->packetized = TRUE;
|
decoder->priv->packetized = TRUE;
|
||||||
decoder->priv->needs_format = FALSE;
|
decoder->priv->needs_format = FALSE;
|
||||||
|
|
||||||
|
g_queue_init (&decoder->priv->frames);
|
||||||
|
g_queue_init (&decoder->priv->timestamps);
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
decoder->priv->do_qos = DEFAULT_QOS;
|
decoder->priv->do_qos = DEFAULT_QOS;
|
||||||
|
|
||||||
|
@ -1376,7 +1382,7 @@ gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *frame = l->data;
|
GstVideoCodecFrame *frame = l->data;
|
||||||
|
|
||||||
frame->events = _flush_events (decoder->srcpad, frame->events);
|
frame->events = _flush_events (decoder->srcpad, frame->events);
|
||||||
|
@ -2005,7 +2011,7 @@ gst_video_decoder_add_buffer_info (GstVideoDecoder * decoder,
|
||||||
ts->duration = GST_BUFFER_DURATION (buffer);
|
ts->duration = GST_BUFFER_DURATION (buffer);
|
||||||
ts->flags = GST_BUFFER_FLAGS (buffer);
|
ts->flags = GST_BUFFER_FLAGS (buffer);
|
||||||
|
|
||||||
priv->timestamps = g_list_append (priv->timestamps, ts);
|
g_queue_push_tail (&priv->timestamps, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2024,10 +2030,11 @@ gst_video_decoder_get_buffer_info_at_offset (GstVideoDecoder *
|
||||||
*duration = GST_CLOCK_TIME_NONE;
|
*duration = GST_CLOCK_TIME_NONE;
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
|
|
||||||
g = decoder->priv->timestamps;
|
g = decoder->priv->timestamps.head;
|
||||||
while (g) {
|
while (g) {
|
||||||
ts = g->data;
|
ts = g->data;
|
||||||
if (ts->offset <= offset) {
|
if (ts->offset <= offset) {
|
||||||
|
GList *next = g->next;
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
got_offset = ts->offset;
|
got_offset = ts->offset;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2035,8 +2042,8 @@ gst_video_decoder_get_buffer_info_at_offset (GstVideoDecoder *
|
||||||
*dts = ts->dts;
|
*dts = ts->dts;
|
||||||
*duration = ts->duration;
|
*duration = ts->duration;
|
||||||
*flags = ts->flags;
|
*flags = ts->flags;
|
||||||
g = g->next;
|
g_queue_delete_link (&decoder->priv->timestamps, g);
|
||||||
decoder->priv->timestamps = g_list_remove (decoder->priv->timestamps, ts);
|
g = next;
|
||||||
timestamp_free (ts);
|
timestamp_free (ts);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -2049,6 +2056,18 @@ gst_video_decoder_get_buffer_info_at_offset (GstVideoDecoder *
|
||||||
GST_TIME_ARGS (*pts), GST_TIME_ARGS (*dts), *flags, got_offset, offset);
|
GST_TIME_ARGS (*pts), GST_TIME_ARGS (*dts), *flags, got_offset, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION(2, 60, 0)
|
||||||
|
#define g_queue_clear_full queue_clear_full
|
||||||
|
static void
|
||||||
|
queue_clear_full (GQueue * queue, GDestroyNotify free_func)
|
||||||
|
{
|
||||||
|
gpointer data;
|
||||||
|
|
||||||
|
while ((data = g_queue_pop_head (queue)) != NULL)
|
||||||
|
free_func (data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_video_decoder_clear_queues (GstVideoDecoder * dec)
|
gst_video_decoder_clear_queues (GstVideoDecoder * dec)
|
||||||
{
|
{
|
||||||
|
@ -2067,8 +2086,8 @@ gst_video_decoder_clear_queues (GstVideoDecoder * dec)
|
||||||
g_list_free_full (priv->parse_gather,
|
g_list_free_full (priv->parse_gather,
|
||||||
(GDestroyNotify) gst_video_codec_frame_unref);
|
(GDestroyNotify) gst_video_codec_frame_unref);
|
||||||
priv->parse_gather = NULL;
|
priv->parse_gather = NULL;
|
||||||
g_list_free_full (priv->frames, (GDestroyNotify) gst_video_codec_frame_unref);
|
g_queue_clear_full (&priv->frames,
|
||||||
priv->frames = NULL;
|
(GDestroyNotify) gst_video_codec_frame_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2163,8 +2182,7 @@ gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
|
||||||
priv->frame_offset = 0;
|
priv->frame_offset = 0;
|
||||||
gst_adapter_clear (priv->input_adapter);
|
gst_adapter_clear (priv->input_adapter);
|
||||||
gst_adapter_clear (priv->output_adapter);
|
gst_adapter_clear (priv->output_adapter);
|
||||||
g_list_free_full (priv->timestamps, (GDestroyNotify) timestamp_free);
|
g_queue_clear_full (&priv->timestamps, (GDestroyNotify) timestamp_free);
|
||||||
priv->timestamps = NULL;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (decoder);
|
GST_OBJECT_LOCK (decoder);
|
||||||
priv->bytes_out = 0;
|
priv->bytes_out = 0;
|
||||||
|
@ -2693,7 +2711,7 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
||||||
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
GST_LOG_OBJECT (decoder, "n %d in %" G_GSIZE_FORMAT " out %" G_GSIZE_FORMAT,
|
GST_LOG_OBJECT (decoder, "n %d in %" G_GSIZE_FORMAT " out %" G_GSIZE_FORMAT,
|
||||||
g_list_length (priv->frames),
|
priv->frames.length,
|
||||||
gst_adapter_available (priv->input_adapter),
|
gst_adapter_available (priv->input_adapter),
|
||||||
gst_adapter_available (priv->output_adapter));
|
gst_adapter_available (priv->output_adapter));
|
||||||
#endif
|
#endif
|
||||||
|
@ -2707,7 +2725,7 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
||||||
sync, GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts));
|
sync, GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts));
|
||||||
|
|
||||||
/* Push all pending events that arrived before this frame */
|
/* Push all pending events that arrived before this frame */
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *tmp = l->data;
|
GstVideoCodecFrame *tmp = l->data;
|
||||||
|
|
||||||
if (tmp->events) {
|
if (tmp->events) {
|
||||||
|
@ -2767,7 +2785,7 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
||||||
gboolean seen_none = FALSE;
|
gboolean seen_none = FALSE;
|
||||||
|
|
||||||
/* some maintenance regardless */
|
/* some maintenance regardless */
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *tmp = l->data;
|
GstVideoCodecFrame *tmp = l->data;
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
|
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
|
||||||
|
@ -2801,7 +2819,7 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
||||||
/* some more maintenance, ts2 holds PTS */
|
/* some more maintenance, ts2 holds PTS */
|
||||||
min_ts = GST_CLOCK_TIME_NONE;
|
min_ts = GST_CLOCK_TIME_NONE;
|
||||||
seen_none = FALSE;
|
seen_none = FALSE;
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *tmp = l->data;
|
GstVideoCodecFrame *tmp = l->data;
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts2)) {
|
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts2)) {
|
||||||
|
@ -2897,10 +2915,10 @@ gst_video_decoder_release_frame (GstVideoDecoder * dec,
|
||||||
|
|
||||||
/* unref once from the list */
|
/* unref once from the list */
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (dec);
|
GST_VIDEO_DECODER_STREAM_LOCK (dec);
|
||||||
link = g_list_find (dec->priv->frames, frame);
|
link = g_queue_find (&dec->priv->frames, frame);
|
||||||
if (link) {
|
if (link) {
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
dec->priv->frames = g_list_delete_link (dec->priv->frames, link);
|
g_queue_delete_link (&dec->priv->frames, link);
|
||||||
}
|
}
|
||||||
if (frame->events) {
|
if (frame->events) {
|
||||||
dec->priv->pending_events =
|
dec->priv->pending_events =
|
||||||
|
@ -3492,12 +3510,11 @@ gst_video_decoder_decode_frame (GstVideoDecoder * decoder,
|
||||||
", dist %d", GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts),
|
", dist %d", GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts),
|
||||||
frame->distance_from_sync);
|
frame->distance_from_sync);
|
||||||
|
|
||||||
gst_video_codec_frame_ref (frame);
|
g_queue_push_tail (&priv->frames, gst_video_codec_frame_ref (frame));
|
||||||
priv->frames = g_list_append (priv->frames, frame);
|
|
||||||
|
|
||||||
if (g_list_length (priv->frames) > 10) {
|
if (priv->frames.length > 10) {
|
||||||
GST_DEBUG_OBJECT (decoder, "decoder frame list getting long: %d frames,"
|
GST_DEBUG_OBJECT (decoder, "decoder frame list getting long: %d frames,"
|
||||||
"possible internal leaking?", g_list_length (priv->frames));
|
"possible internal leaking?", priv->frames.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->deadline =
|
frame->deadline =
|
||||||
|
@ -3640,8 +3657,8 @@ gst_video_decoder_get_oldest_frame (GstVideoDecoder * decoder)
|
||||||
GstVideoCodecFrame *frame = NULL;
|
GstVideoCodecFrame *frame = NULL;
|
||||||
|
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||||
if (decoder->priv->frames)
|
if (decoder->priv->frames.head)
|
||||||
frame = gst_video_codec_frame_ref (decoder->priv->frames->data);
|
frame = gst_video_codec_frame_ref (decoder->priv->frames.head->data);
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||||
|
|
||||||
return (GstVideoCodecFrame *) frame;
|
return (GstVideoCodecFrame *) frame;
|
||||||
|
@ -3665,7 +3682,7 @@ gst_video_decoder_get_frame (GstVideoDecoder * decoder, int frame_number)
|
||||||
GST_DEBUG_OBJECT (decoder, "frame_number : %d", frame_number);
|
GST_DEBUG_OBJECT (decoder, "frame_number : %d", frame_number);
|
||||||
|
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||||
for (g = decoder->priv->frames; g; g = g->next) {
|
for (g = decoder->priv->frames.head; g; g = g->next) {
|
||||||
GstVideoCodecFrame *tmp = g->data;
|
GstVideoCodecFrame *tmp = g->data;
|
||||||
|
|
||||||
if (tmp->system_frame_number == frame_number) {
|
if (tmp->system_frame_number == frame_number) {
|
||||||
|
@ -3692,8 +3709,9 @@ gst_video_decoder_get_frames (GstVideoDecoder * decoder)
|
||||||
GList *frames;
|
GList *frames;
|
||||||
|
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||||
frames = g_list_copy (decoder->priv->frames);
|
frames =
|
||||||
g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
|
g_list_copy_deep (decoder->priv->frames.head,
|
||||||
|
(GCopyFunc) gst_video_codec_frame_ref, NULL);
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||||
|
|
||||||
return frames;
|
return frames;
|
||||||
|
@ -3959,7 +3977,7 @@ gst_video_decoder_negotiate_default (GstVideoDecoder * decoder)
|
||||||
|
|
||||||
/* Push all pending pre-caps events of the oldest frame before
|
/* Push all pending pre-caps events of the oldest frame before
|
||||||
* setting caps */
|
* setting caps */
|
||||||
frame = decoder->priv->frames ? decoder->priv->frames->data : NULL;
|
frame = decoder->priv->frames.head ? decoder->priv->frames.head->data : NULL;
|
||||||
if (frame || decoder->priv->current_frame_events) {
|
if (frame || decoder->priv->current_frame_events) {
|
||||||
GList **events, *l;
|
GList **events, *l;
|
||||||
|
|
||||||
|
|
|
@ -132,16 +132,17 @@ struct _GstVideoEncoderPrivate
|
||||||
gint64 min_latency;
|
gint64 min_latency;
|
||||||
gint64 max_latency;
|
gint64 max_latency;
|
||||||
|
|
||||||
|
/* FIXME 2.0: Use a GQueue or similar, see GstVideoCodecFrame::events */
|
||||||
GList *current_frame_events;
|
GList *current_frame_events;
|
||||||
|
|
||||||
GList *headers;
|
GList *headers;
|
||||||
gboolean new_headers; /* Whether new headers were just set */
|
gboolean new_headers; /* Whether new headers were just set */
|
||||||
|
|
||||||
GList *force_key_unit; /* List of pending forced keyunits */
|
GQueue force_key_unit; /* List of pending forced keyunits */
|
||||||
|
|
||||||
guint32 system_frame_number;
|
guint32 system_frame_number;
|
||||||
|
|
||||||
GList *frames; /* Protected with OBJECT_LOCK */
|
GQueue frames; /* Protected with OBJECT_LOCK */
|
||||||
GstVideoCodecState *input_state;
|
GstVideoCodecState *input_state;
|
||||||
GstVideoCodecState *output_state;
|
GstVideoCodecState *output_state;
|
||||||
gboolean output_state_changed;
|
gboolean output_state_changed;
|
||||||
|
@ -386,6 +387,18 @@ _flush_events (GstPad * pad, GList * events)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION(2, 60, 0)
|
||||||
|
#define g_queue_clear_full queue_clear_full
|
||||||
|
static void
|
||||||
|
queue_clear_full (GQueue * queue, GDestroyNotify free_func)
|
||||||
|
{
|
||||||
|
gpointer data;
|
||||||
|
|
||||||
|
while ((data = g_queue_pop_head (queue)) != NULL)
|
||||||
|
free_func (data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
|
gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
|
||||||
{
|
{
|
||||||
|
@ -397,10 +410,8 @@ gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
|
||||||
priv->presentation_frame_number = 0;
|
priv->presentation_frame_number = 0;
|
||||||
priv->distance_from_sync = 0;
|
priv->distance_from_sync = 0;
|
||||||
|
|
||||||
g_list_foreach (priv->force_key_unit, (GFunc) forced_key_unit_event_free,
|
g_queue_clear_full (&priv->force_key_unit,
|
||||||
NULL);
|
(GDestroyNotify) forced_key_unit_event_free);
|
||||||
g_list_free (priv->force_key_unit);
|
|
||||||
priv->force_key_unit = NULL;
|
|
||||||
|
|
||||||
priv->drained = TRUE;
|
priv->drained = TRUE;
|
||||||
|
|
||||||
|
@ -457,7 +468,7 @@ gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
|
||||||
} else {
|
} else {
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *frame = l->data;
|
GstVideoCodecFrame *frame = l->data;
|
||||||
|
|
||||||
frame->events = _flush_events (encoder->srcpad, frame->events);
|
frame->events = _flush_events (encoder->srcpad, frame->events);
|
||||||
|
@ -466,9 +477,8 @@ gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
|
||||||
encoder->priv->current_frame_events);
|
encoder->priv->current_frame_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_foreach (priv->frames, (GFunc) gst_video_codec_frame_unref, NULL);
|
g_queue_clear_full (&priv->frames,
|
||||||
g_list_free (priv->frames);
|
(GDestroyNotify) gst_video_codec_frame_unref);
|
||||||
priv->frames = NULL;
|
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||||||
|
|
||||||
|
@ -532,6 +542,9 @@ gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
|
||||||
priv->headers = NULL;
|
priv->headers = NULL;
|
||||||
priv->new_headers = FALSE;
|
priv->new_headers = FALSE;
|
||||||
|
|
||||||
|
g_queue_init (&priv->frames);
|
||||||
|
g_queue_init (&priv->force_key_unit);
|
||||||
|
|
||||||
priv->min_latency = 0;
|
priv->min_latency = 0;
|
||||||
priv->max_latency = 0;
|
priv->max_latency = 0;
|
||||||
priv->min_pts = GST_CLOCK_TIME_NONE;
|
priv->min_pts = GST_CLOCK_TIME_NONE;
|
||||||
|
@ -1094,8 +1107,7 @@ gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
fevt = forced_key_unit_event_new (running_time, all_headers, count);
|
fevt = forced_key_unit_event_new (running_time, all_headers, count);
|
||||||
encoder->priv->force_key_unit =
|
g_queue_push_tail (&encoder->priv->force_key_unit, fevt);
|
||||||
g_list_append (encoder->priv->force_key_unit, fevt);
|
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (encoder,
|
GST_DEBUG_OBJECT (encoder,
|
||||||
|
@ -1240,8 +1252,7 @@ gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
fevt = forced_key_unit_event_new (running_time, all_headers, count);
|
fevt = forced_key_unit_event_new (running_time, all_headers, count);
|
||||||
encoder->priv->force_key_unit =
|
g_queue_push_tail (&encoder->priv->force_key_unit, fevt);
|
||||||
g_list_append (encoder->priv->force_key_unit, fevt);
|
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (encoder,
|
GST_DEBUG_OBJECT (encoder,
|
||||||
|
@ -1498,7 +1509,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
GST_CLOCK_TIME_NONE, duration);
|
GST_CLOCK_TIME_NONE, duration);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
if (priv->force_key_unit) {
|
if (priv->force_key_unit.head) {
|
||||||
ForcedKeyUnitEvent *fevt = NULL;
|
ForcedKeyUnitEvent *fevt = NULL;
|
||||||
GstClockTime running_time;
|
GstClockTime running_time;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
@ -1507,7 +1518,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
||||||
cstart);
|
cstart);
|
||||||
|
|
||||||
for (l = priv->force_key_unit; l; l = l->next) {
|
for (l = priv->force_key_unit.head; l; l = l->next) {
|
||||||
ForcedKeyUnitEvent *tmp = l->data;
|
ForcedKeyUnitEvent *tmp = l->data;
|
||||||
|
|
||||||
/* Skip pending keyunits */
|
/* Skip pending keyunits */
|
||||||
|
@ -1540,8 +1551,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
gst_video_codec_frame_ref (frame);
|
g_queue_push_tail (&priv->frames, gst_video_codec_frame_ref (frame));
|
||||||
priv->frames = g_list_append (priv->frames, frame);
|
|
||||||
|
|
||||||
/* new data, more finish needed */
|
/* new data, more finish needed */
|
||||||
priv->drained = FALSE;
|
priv->drained = FALSE;
|
||||||
|
@ -1759,7 +1769,7 @@ gst_video_encoder_negotiate_default (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
/* Push all pending pre-caps events of the oldest frame before
|
/* Push all pending pre-caps events of the oldest frame before
|
||||||
* setting caps */
|
* setting caps */
|
||||||
frame = encoder->priv->frames ? encoder->priv->frames->data : NULL;
|
frame = encoder->priv->frames.head ? encoder->priv->frames.head->data : NULL;
|
||||||
if (frame || encoder->priv->current_frame_events) {
|
if (frame || encoder->priv->current_frame_events) {
|
||||||
GList **events, *l;
|
GList **events, *l;
|
||||||
|
|
||||||
|
@ -1984,10 +1994,10 @@ gst_video_encoder_release_frame (GstVideoEncoder * enc,
|
||||||
GList *link;
|
GList *link;
|
||||||
|
|
||||||
/* unref once from the list */
|
/* unref once from the list */
|
||||||
link = g_list_find (enc->priv->frames, frame);
|
link = g_queue_find (&enc->priv->frames, frame);
|
||||||
if (link) {
|
if (link) {
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
enc->priv->frames = g_list_delete_link (enc->priv->frames, link);
|
g_queue_delete_link (&enc->priv->frames, link);
|
||||||
}
|
}
|
||||||
/* unref because this function takes ownership */
|
/* unref because this function takes ownership */
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
@ -2122,7 +2132,7 @@ gst_video_encoder_push_pending_unlocked (GstVideoEncoder * encoder,
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
/* Push all pending events that arrived before this frame */
|
/* Push all pending events that arrived before this frame */
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *tmp = l->data;
|
GstVideoCodecFrame *tmp = l->data;
|
||||||
|
|
||||||
if (tmp->events) {
|
if (tmp->events) {
|
||||||
|
@ -2154,7 +2164,7 @@ gst_video_encoder_infer_dts_unlocked (GstVideoEncoder * encoder,
|
||||||
gboolean seen_none = FALSE;
|
gboolean seen_none = FALSE;
|
||||||
|
|
||||||
/* some maintenance regardless */
|
/* some maintenance regardless */
|
||||||
for (l = priv->frames; l; l = l->next) {
|
for (l = priv->frames.head; l; l = l->next) {
|
||||||
GstVideoCodecFrame *tmp = l->data;
|
GstVideoCodecFrame *tmp = l->data;
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
|
if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
|
||||||
|
@ -2247,14 +2257,14 @@ gst_video_encoder_send_key_unit_unlocked (GstVideoEncoder * encoder,
|
||||||
GstClockTime stream_time, running_time;
|
GstClockTime stream_time, running_time;
|
||||||
GstEvent *ev;
|
GstEvent *ev;
|
||||||
ForcedKeyUnitEvent *fevt = NULL;
|
ForcedKeyUnitEvent *fevt = NULL;
|
||||||
GList *l;
|
GList *l, *fevt_link = NULL;
|
||||||
|
|
||||||
running_time =
|
running_time =
|
||||||
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
||||||
frame->pts);
|
frame->pts);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
for (l = priv->force_key_unit; l; l = l->next) {
|
for (l = priv->force_key_unit.head; l; l = l->next) {
|
||||||
ForcedKeyUnitEvent *tmp = l->data;
|
ForcedKeyUnitEvent *tmp = l->data;
|
||||||
|
|
||||||
/* Skip non-pending keyunits */
|
/* Skip non-pending keyunits */
|
||||||
|
@ -2263,26 +2273,28 @@ gst_video_encoder_send_key_unit_unlocked (GstVideoEncoder * encoder,
|
||||||
|
|
||||||
/* Exact match using the frame id */
|
/* Exact match using the frame id */
|
||||||
if (frame->system_frame_number == tmp->frame_id) {
|
if (frame->system_frame_number == tmp->frame_id) {
|
||||||
|
fevt_link = l;
|
||||||
fevt = tmp;
|
fevt = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simple case, keyunit ASAP */
|
/* Simple case, keyunit ASAP */
|
||||||
if (tmp->running_time == GST_CLOCK_TIME_NONE) {
|
if (tmp->running_time == GST_CLOCK_TIME_NONE) {
|
||||||
|
fevt_link = l;
|
||||||
fevt = tmp;
|
fevt = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Event for before this frame */
|
/* Event for before this frame */
|
||||||
if (tmp->running_time <= running_time) {
|
if (tmp->running_time <= running_time) {
|
||||||
|
fevt_link = l;
|
||||||
fevt = tmp;
|
fevt = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fevt) {
|
if (fevt_link)
|
||||||
priv->force_key_unit = g_list_remove (priv->force_key_unit, fevt);
|
g_queue_delete_link (&priv->force_key_unit, fevt_link);
|
||||||
}
|
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
if (fevt) {
|
if (fevt) {
|
||||||
|
@ -2366,10 +2378,9 @@ gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
|
||||||
|
|
||||||
priv->processed++;
|
priv->processed++;
|
||||||
|
|
||||||
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit)
|
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit.head)
|
||||||
gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
|
gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
|
||||||
|
|
||||||
|
|
||||||
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)
|
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)
|
||||||
&& frame->abidata.ABI.num_subframes == 0) {
|
&& frame->abidata.ABI.num_subframes == 0) {
|
||||||
priv->distance_from_sync = 0;
|
priv->distance_from_sync = 0;
|
||||||
|
@ -2502,7 +2513,7 @@ gst_video_encoder_finish_subframe (GstVideoEncoder * encoder,
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit)
|
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit.head)
|
||||||
gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
|
gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
|
||||||
|
|
||||||
/* Push pending events only for the first subframe ie segment event.
|
/* Push pending events only for the first subframe ie segment event.
|
||||||
|
@ -2708,8 +2719,8 @@ gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
|
||||||
GstVideoCodecFrame *frame = NULL;
|
GstVideoCodecFrame *frame = NULL;
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||||||
if (encoder->priv->frames)
|
if (encoder->priv->frames.head)
|
||||||
frame = gst_video_codec_frame_ref (encoder->priv->frames->data);
|
frame = gst_video_codec_frame_ref (encoder->priv->frames.head->data);
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||||||
|
|
||||||
return (GstVideoCodecFrame *) frame;
|
return (GstVideoCodecFrame *) frame;
|
||||||
|
@ -2733,7 +2744,7 @@ gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
|
||||||
GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
|
GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||||||
for (g = encoder->priv->frames; g; g = g->next) {
|
for (g = encoder->priv->frames.head; g; g = g->next) {
|
||||||
GstVideoCodecFrame *tmp = g->data;
|
GstVideoCodecFrame *tmp = g->data;
|
||||||
|
|
||||||
if (tmp->system_frame_number == frame_number) {
|
if (tmp->system_frame_number == frame_number) {
|
||||||
|
@ -2760,8 +2771,9 @@ gst_video_encoder_get_frames (GstVideoEncoder * encoder)
|
||||||
GList *frames;
|
GList *frames;
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||||||
frames = g_list_copy (encoder->priv->frames);
|
frames =
|
||||||
g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
|
g_list_copy_deep (encoder->priv->frames.head,
|
||||||
|
(GCopyFunc) gst_video_codec_frame_ref, NULL);
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||||||
|
|
||||||
return frames;
|
return frames;
|
||||||
|
|
|
@ -252,6 +252,7 @@ struct _GstVideoCodecFrame
|
||||||
|
|
||||||
/* Events that should be pushed downstream *before*
|
/* Events that should be pushed downstream *before*
|
||||||
* the next output_buffer */
|
* the next output_buffer */
|
||||||
|
/* FIXME 2.0: Use a GQueue or similar */
|
||||||
GList *events; /* ED */
|
GList *events; /* ED */
|
||||||
|
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
|
|
Loading…
Reference in a new issue