amlv4l2: CF1 support local buf pool and drop out of segment buf [1/1]
PD#SWPL-185438
Problem:
res switch hang in hls vmx single ts scene
when different res fragments have different dur
Solution:
1. drop out of segment buf
2. support local buf pool
Verify:
(detail info)
Change-Id: Id834a858e5f226e4f97bb4a2d29f4f49328f0787
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/gstamlv4l2videodec.c b/src/gstamlv4l2videodec.c
index 9d86e05..232fd60 100644
--- a/src/gstamlv4l2videodec.c
+++ b/src/gstamlv4l2videodec.c
@@ -104,6 +104,7 @@
#endif
static GstClockTime gst_aml_v4l2_video_dec_calc_output_buffer_pts(GstAmlVideoDecoder *decoder);
static GstClockTime gst_aml_v4l2_video_dec_calc_duration(GstAmlVideoDecoder *decoder);
+static GstFlowReturn gst_aml_v4l2_video_dec_clip_and_push_frame (GstAmlVideoDecoder * decoder, GstAmlVideoCodecFrame * frame);
static void
gst_aml_v4l2_video_dec_set_property(GObject *object,
@@ -555,7 +556,7 @@
{
GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- if (TRUE == self->v4l2output->is_svp)
+ if (TRUE == decoder->svp)
{
GstStructure *s;
GstEvent *event;
@@ -1011,6 +1012,54 @@
return duration;
}
+static GstFlowReturn
+gst_aml_v4l2_video_dec_clip_and_push_frame (GstAmlVideoDecoder * decoder, GstAmlVideoCodecFrame * frame)
+{
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ gboolean drop = FALSE;
+
+ if ((decoder->input_segment.rate > 0 && GST_CLOCK_TIME_NONE == decoder->input_segment.start) ||
+ (decoder->input_segment.rate < 0 && GST_CLOCK_TIME_NONE == decoder->input_segment.stop))
+ {
+ GST_DEBUG_OBJECT(self, "don't do clip when we have no input segment");
+ goto done;
+ }
+
+ if (decoder->input_segment.rate > 0)
+ {
+ GstClockTime duration = 0;
+
+ if (GST_CLOCK_TIME_NONE != frame->duration)
+ duration = frame->duration;
+
+ if ((frame->pts + duration) < decoder->input_segment.start)
+ {
+ GST_DEBUG_OBJECT(self, "drop frame with pts(dur %" GST_TIME_FORMAT ") %" GST_TIME_FORMAT " < start %" GST_TIME_FORMAT,
+ GST_TIME_ARGS(frame->pts), GST_TIME_ARGS(frame->duration), GST_TIME_ARGS(decoder->input_segment.start));
+ drop = TRUE;
+ goto done;
+ }
+ }
+ else if (decoder->input_segment.rate < 0)
+ {
+ if (frame->pts > decoder->input_segment.stop)
+ {
+ GST_DEBUG_OBJECT(self, "drop frame with pts(dur %" GST_TIME_FORMAT ") %" GST_TIME_FORMAT " > stop %" GST_TIME_FORMAT,
+ GST_TIME_ARGS(frame->pts), GST_TIME_ARGS(frame->duration), GST_TIME_ARGS(decoder->input_segment.stop));
+ drop = TRUE;
+ goto done;
+ }
+ }
+
+done:
+ if (G_LIKELY (!drop))
+ ret = gst_aml_video_decoder_finish_frame(decoder, frame);
+ else
+ ret = gst_aml_video_decoder_drop_frame(decoder, frame);
+ return ret;
+}
+
static void
gst_aml_v4l2_video_dec_loop(GstAmlVideoDecoder *decoder)
{
@@ -1052,7 +1101,7 @@
}
self->v4l2capture->need_wait_event = FALSE;
- if (TRUE == self->v4l2output->is_svp)
+ if (TRUE == decoder->svp)
{
GstPad *peer;
GstStructure *s;
@@ -1297,7 +1346,8 @@
GST_WARNING("bufferlist is empty or no match frame in the bufferlist");
}
}
- ret = gst_aml_video_decoder_finish_frame (decoder, frame);
+
+ ret = gst_aml_v4l2_video_dec_clip_and_push_frame(decoder, frame);
if (ret != GST_FLOW_OK)
goto beach;
@@ -1385,8 +1435,7 @@
if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF) && self->v4l2output->secure_es)
{
GST_DEBUG_OBJECT(self, "Is SVP");
- //TODO:need rm is_svp flag and just using secure_es flag
- self->v4l2output->is_svp = TRUE;
+ decoder->svp = TRUE;
}
GST_DEBUG_OBJECT (self, "Sending header");
@@ -1874,7 +1923,6 @@
gst_aml_v4l2_get_output, gst_aml_v4l2_set_output, NULL);
self->v4l2output->no_initial_format = TRUE;
self->v4l2output->keep_aspect = FALSE;
- self->v4l2output->is_svp = FALSE;
self->v4l2capture = gst_aml_v4l2_object_new (GST_ELEMENT (self),
GST_OBJECT (GST_AML_VIDEO_DECODER_SRC_PAD (self)),