[vlc-devel] [PATCH 11/19] mmal/deinterlace: implement draining of extra pictures in deinterlacer
Steve Lhomme
robux4 at ycbcr.xyz
Tue Oct 13 15:51:54 CEST 2020
Fix the source picture was released after turning it into a MMAL_BUFFER_HEADER_T.
Not sure how this could work.
The while loop to create output picture is turned into single calls. One in the
filter function and others in the drain calls.
The assert done before returning a valid picture is moved up in the Filter
callback.
We no longer return pictures chained using vlc_picture_chain_AppendChain().
---
modules/hw/mmal/deinterlace.c | 35 ++++++++++++++++++++---------------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/modules/hw/mmal/deinterlace.c b/modules/hw/mmal/deinterlace.c
index 70814303bb6..d696ce9ecd3 100644
--- a/modules/hw/mmal/deinterlace.c
+++ b/modules/hw/mmal/deinterlace.c
@@ -215,7 +215,6 @@ static picture_t *but_to_pic(filter_t * p_filter, MMAL_BUFFER_HEADER_T *out_buf)
static picture_t *deinterlace(filter_t * p_filter, picture_t * p_pic)
{
filter_sys_t * const sys = p_filter->p_sys;
- picture_t *ret_pics = NULL;
MMAL_STATUS_T err;
MMAL_BUFFER_HEADER_T * out_buf = NULL;
@@ -262,8 +261,6 @@ static picture_t *deinterlace(filter_t * p_filter, picture_t * p_pic)
goto fail;
}
- picture_Release(p_pic);
-
// Add a sequence to the flags so we can track what we have actually
// deinterlaced
pic_buf->flags = (pic_buf->flags & ~(0xfU * MMAL_BUFFER_HEADER_FLAG_USER0)) | (sys->seq_in * (MMAL_BUFFER_HEADER_FLAG_USER0));
@@ -277,9 +274,6 @@ static picture_t *deinterlace(filter_t * p_filter, picture_t * p_pic)
}
}
- // Return anything that is in the out Q
- picture_t * chain_tail = ret_pics;
-
// Advanced di has a 3 frame latency, so if the seq delta is greater
// than that then we are expecting at least two frames of output. Wait
// for one of those.
@@ -287,21 +281,16 @@ static picture_t *deinterlace(filter_t * p_filter, picture_t * p_pic)
// seq_out is last frame we removed from Q
// So after 4 frames sent (1st time we want to wait), 0 rx seq_in=5, seq_out=15, delta=5
- while ((out_buf = (seq_delta(sys->seq_in, sys->seq_out) >= 5 ? mmal_queue_timedwait(sys->out_q, 1000) : mmal_queue_get(sys->out_q))) != NULL)
+ out_buf = seq_delta(sys->seq_in, sys->seq_out) >= 5 ? mmal_queue_timedwait(sys->out_q, 1000) : mmal_queue_get(sys->out_q);
+ if (out_buf == NULL)
+ goto fail;
{
picture_t * out_pic = but_to_pic(p_filter, out_buf);
if (unlikely(out_pic == NULL))
break;
-
- vlc_picture_chain_AppendChain( chain_tail, out_pic );
- chain_tail = out_pic;
+ return out_pic;
}
- // Crash on lockup
- assert(ret_pics != NULL || seq_delta(sys->seq_in, sys->seq_out) < 5);
-
- return ret_pics;
-
fail:
if (out_buf != NULL)
mmal_buffer_header_release(out_buf);
@@ -309,6 +298,21 @@ fail:
return NULL;
}
+static picture_t *drain(filter_t * p_filter)
+{
+ filter_sys_t * const sys = p_filter->p_sys;
+ MMAL_BUFFER_HEADER_T * out_buf;
+ out_buf = seq_delta(sys->seq_in, sys->seq_out) >= 5 ? mmal_queue_timedwait(sys->out_q, 1000) : mmal_queue_get(sys->out_q);
+ if (out_buf == NULL)
+ return NULL;
+
+ picture_t * out_pic = but_to_pic(p_filter, out_buf);
+ if (unlikely(out_pic == NULL))
+ mmal_buffer_header_release(out_buf);
+
+ return out_pic;
+}
+
static void di_flush(filter_t *p_filter)
{
filter_sys_t * const sys = p_filter->p_sys;
@@ -417,6 +421,7 @@ static bool is_fmt_valid_in(const vlc_fourcc_t fmt)
static const struct vlc_filter_operations filter_ops = {
.filter_video = deinterlace, .flush = di_flush, .close = CloseMmalDeinterlace,
+ .drain_video = drain,
};
static const struct vlc_filter_operations filter_pass_ops = {
--
2.26.2
More information about the vlc-devel
mailing list