Commit 6c1973f1 authored by Steve Lhomme's avatar Steve Lhomme
Browse files

mmal/deinterlace: implement draining of extra pictures in deinterlacer

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().
parent 1b658e10
......@@ -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;
goto fail;
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 = {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment