summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2016-06-05 11:11:29 +0200
committerAlfred E. Heggestad <aeh@db.org>2016-06-05 11:11:29 +0200
commit162e628b26f712c53c0e5f41f5d721211ddaf1ee (patch)
tree8daf7dd32d62db5c2ae57d2351292eafea25dedd
parentd4e6364e08813dd7dc6dd5609250a1685c82d634 (diff)
video: copy vidframe if decode-filters are used
this is to fix the bug where any pixels overlaying the original image is "smeared" all over the surface, since some video decoders like ffmpeg/vpx keeps the displayed image in memory.
-rw-r--r--src/video.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/video.c b/src/video.c
index 9e299fa..d2587aa 100644
--- a/src/video.c
+++ b/src/video.c
@@ -512,7 +512,8 @@ static int video_stream_decode(struct vrx *vrx, const struct rtp_header *hdr,
struct mbuf *mb)
{
struct video *v = vrx->video;
- struct vidframe frame;
+ struct vidframe *frame_filt = NULL;
+ struct vidframe frame_store, *frame = &frame_store;
struct le *le;
int err = 0;
@@ -527,8 +528,8 @@ static int video_stream_decode(struct vrx *vrx, const struct rtp_header *hdr,
goto out;
}
- frame.data[0] = NULL;
- err = vrx->vc->dech(vrx->dec, &frame, hdr->m, hdr->seq, mb);
+ frame->data[0] = NULL;
+ err = vrx->vc->dech(vrx->dec, frame, hdr->m, hdr->seq, mb);
if (err) {
if (err != EPROTO) {
@@ -547,19 +548,31 @@ static int video_stream_decode(struct vrx *vrx, const struct rtp_header *hdr,
}
/* Got a full picture-frame? */
- if (!vidframe_isvalid(&frame))
+ if (!vidframe_isvalid(frame))
goto out;
+ if (!list_isempty(&vrx->filtl)) {
+
+ err = vidframe_alloc(&frame_filt, frame->fmt, &frame->size);
+ if (err)
+ goto out;
+
+ vidframe_copy(frame_filt, frame);
+
+ frame = frame_filt;
+ }
+
/* Process video frame through all Video Filters */
for (le = vrx->filtl.head; le; le = le->next) {
struct vidfilt_dec_st *st = le->data;
if (st->vf && st->vf->dech)
- err |= st->vf->dech(st, &frame);
+ err |= st->vf->dech(st, frame);
}
- err = vidisp_display(vrx->vidisp, v->peer, &frame);
+ err = vidisp_display(vrx->vidisp, v->peer, frame);
+ frame_filt = mem_deref(frame_filt);
if (err == ENODEV) {
warning("video: video-display was closed\n");
vrx->vidisp = mem_deref(vrx->vidisp);