summaryrefslogtreecommitdiff
path: root/libavfilter/vf_yadif.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-09-03 04:40:04 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-09-03 05:14:29 +0200
commit92b7e7b31817cd470c38f84bac2053cd565ae521 (patch)
tree044309851c74932bbd8b26c8485af267175afeb1 /libavfilter/vf_yadif.c
parentcc84f304026122713a215a42598ecc18160ca66d (diff)
downloadffmpeg-92b7e7b31817cd470c38f84bac2053cd565ae521.tar.gz
avfilter/vf_yadif: reallocate frames if strides differ
Fixes Ticket2896 An alternative to this would be to change the code to support any stride. The condition of differing strides should be rare. If theres no speedloss supporting any stride would be better Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/vf_yadif.c')
-rw-r--r--libavfilter/vf_yadif.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 5789da6c89..71165535d9 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -22,6 +22,7 @@
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
@@ -285,6 +286,29 @@ static int return_frame(AVFilterContext *ctx, int is_second)
return ret;
}
+static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b)
+{
+ int i;
+ for (i = 0; i < yadif->csp->nb_components; i++)
+ if (a->linesize[i] != b->linesize[i])
+ return 1;
+ return 0;
+}
+
+static void fixstride(AVFilterLink *link, AVFrame *f)
+{
+ AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height);
+ if(!dst)
+ return;
+ av_frame_copy_props(dst, f);
+ av_image_copy(dst->data, dst->linesize,
+ f->data, f->linesize,
+ dst->format, dst->width, dst->height);
+ av_frame_unref(f);
+ av_frame_move_ref(f, dst);
+ av_frame_free(&dst);
+}
+
static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
AVFilterContext *ctx = link->dst;
@@ -304,6 +328,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
if (!yadif->cur)
return 0;
+ if (checkstride(yadif, yadif->next, yadif->cur)) {
+ av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n");
+ fixstride(link, yadif->next);
+ }
+ if (checkstride(yadif, yadif->next, yadif->cur))
+ fixstride(link, yadif->cur);
+ if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))
+ fixstride(link, yadif->prev);
+ if (checkstride(yadif, yadif->next, yadif->cur) || (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to reallocate frame\n");
+ return -1;
+ }
+
if ((yadif->deint && !yadif->cur->interlaced_frame) || ctx->is_disabled) {
yadif->out = av_frame_clone(yadif->cur);
if (!yadif->out)