From 91123307c8f934a867cf70b9ae6b27373311b8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 5 Sep 2013 03:41:10 -0600 Subject: [PATCH 04/11] gstomxvideoenc: simplify _find_nearest_frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just the same as we did with the decoder. Also give the function a gst_omx_video_enc prefix to distinct it from the decoder function. Signed-off-by: Christian König --- omx/gstomxvideoenc.c | 102 ++++++++------------------------------------------ 1 file changed, 15 insertions(+), 87 deletions(-) diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index a85e815..3a139bb 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -55,18 +55,6 @@ gst_omx_video_enc_control_rate_get_type (void) return qtype; } -typedef struct _BufferIdentification BufferIdentification; -struct _BufferIdentification -{ - guint64 timestamp; -}; - -static void -buffer_identification_free (BufferIdentification * id) -{ - g_slice_free (BufferIdentification, id); -} - /* prototypes */ static void gst_omx_video_enc_finalize (GObject * object); static void gst_omx_video_enc_set_property (GObject * object, guint prop_id, @@ -551,88 +539,34 @@ gst_omx_video_enc_change_state (GstElement * element, GstStateChange transition) return ret; } -#define MAX_FRAME_DIST_TICKS (5 * OMX_TICKS_PER_SECOND) -#define MAX_FRAME_DIST_FRAMES (100) - static GstVideoCodecFrame * -_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) +gst_omx_video_enc_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) { - GList *l, *best_l = NULL; - GList *finish_frames = NULL; GstVideoCodecFrame *best = NULL; - guint64 best_timestamp = 0; - guint64 best_diff = G_MAXUINT64; - BufferIdentification *best_id = NULL; + GstClockTimeDiff best_diff = G_MAXINT64; + GstClockTime timestamp; GList *frames; + GList *l; + + if (buf->omx_buf->nTimeStamp) + timestamp = + gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, + OMX_TICKS_PER_SECOND); + else + timestamp = GST_CLOCK_TIME_NONE; frames = gst_video_encoder_get_frames (GST_VIDEO_ENCODER (self)); for (l = frames; l; l = l->next) { GstVideoCodecFrame *tmp = l->data; - BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); - guint64 timestamp, diff; - - /* This happens for frames that were just added but - * which were not passed to the component yet. Ignore - * them here! - */ - if (!id) - continue; - - timestamp = id->timestamp; + GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts)); - if (timestamp > buf->omx_buf->nTimeStamp) - diff = timestamp - buf->omx_buf->nTimeStamp; - else - diff = buf->omx_buf->nTimeStamp - timestamp; - - if (best == NULL || diff < best_diff) { + if (diff < best_diff) { best = tmp; - best_timestamp = timestamp; best_diff = diff; - best_l = l; - best_id = id; - - /* For frames without timestamp we simply take the first frame */ - if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) - break; - } - } - - if (best_id) { - for (l = frames; l && l != best_l; l = l->next) { - GstVideoCodecFrame *tmp = l->data; - BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); - guint64 diff_ticks, diff_frames; - - /* This happens for frames that were just added but - * which were not passed to the component yet. Ignore - * them here! - */ - if (!id) - continue; - if (id->timestamp > best_timestamp) + if (diff == 0) break; - - if (id->timestamp == 0 || best_timestamp == 0) - diff_ticks = 0; - else - diff_ticks = best_timestamp - id->timestamp; - diff_frames = best->system_frame_number - tmp->system_frame_number; - - if (diff_ticks > MAX_FRAME_DIST_TICKS - || diff_frames > MAX_FRAME_DIST_FRAMES) { - finish_frames = - g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); - } - } - } - - if (finish_frames) { - g_warning ("Too old frames, bug in encoder -- please file a bug"); - for (l = finish_frames; l; l = l->next) { - gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (self), l->data); } } @@ -851,7 +785,7 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); GST_VIDEO_ENCODER_STREAM_LOCK (self); - frame = _find_nearest_frame (self, buf); + frame = gst_omx_video_enc_find_nearest_frame (self, buf); g_assert (klass->handle_output_frame); flow_ret = klass->handle_output_frame (self, self->enc_out_port, buf, frame); @@ -1559,7 +1493,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, port = self->enc_in_port; while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { - BufferIdentification *id; GstClockTime timestamp, duration; /* Make sure to release the base class stream lock, otherwise @@ -1683,11 +1616,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, self->last_upstream_ts += duration; } - id = g_slice_new0 (BufferIdentification); - id->timestamp = buf->omx_buf->nTimeStamp; - gst_video_codec_frame_set_user_data (frame, id, - (GDestroyNotify) buffer_identification_free); - self->started = TRUE; err = gst_omx_port_release_buffer (port, buf); if (err != OMX_ErrorNone) -- 1.7.9.5