[PATCH] Fix vflip+DR crash.
Stefano Sabatini
stefano.sabatini-lala
Sun Dec 5 03:37:06 CET 2010
---
ffplay.c | 8 +++++-
libavfilter/avfilter.c | 6 ++--
libavfilter/avfilter.h | 11 +++++---
libavfilter/defaults.c | 8 +++---
libavfilter/vf_aspect.c | 4 +-
libavfilter/vf_crop.c | 4 +-
libavfilter/vf_fifo.c | 4 +-
libavfilter/vf_frei0r.c | 2 +-
libavfilter/vf_overlay.c | 6 ++--
libavfilter/vf_pad.c | 6 ++--
libavfilter/vf_pixdesctest.c | 4 +-
libavfilter/vf_scale.c | 4 +-
libavfilter/vf_setpts.c | 4 +-
libavfilter/vf_settb.c | 4 +-
libavfilter/vf_slicify.c | 4 +-
libavfilter/vf_transpose.c | 4 +-
libavfilter/vf_vflip.c | 62 +++++++++++++++++++++++++++++++++++++----
libavfilter/vf_yadif.c | 6 ++--
libavfilter/vsink_nullsink.c | 2 +-
libavfilter/vsrc_buffer.c | 2 +-
20 files changed, 107 insertions(+), 48 deletions(-)
diff --git a/ffplay.c b/ffplay.c
index 38a2fe1..005fe2f 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -1606,6 +1606,7 @@ typedef struct {
VideoState *is;
AVFrame *frame;
int use_dr1;
+ int start_frame_flags;
} FilterPriv;
static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
@@ -1616,6 +1617,9 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
int i, w, h, stride[4];
unsigned edge;
+ if (!(codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES))
+ perms |= AV_PERM_POS_LINESIZES;
+
if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
@@ -1691,6 +1695,8 @@ static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
codec->get_buffer = input_get_buffer;
codec->release_buffer = input_release_buffer;
codec->reget_buffer = input_reget_buffer;
+ if (!(codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES))
+ priv->start_frame_flags = AVFILTER_START_FRAME_FLAG_INVERTED_BUFFER;
}
priv->frame = avcodec_alloc_frame();
@@ -1730,7 +1736,7 @@ static int input_request_frame(AVFilterLink *link)
picref->pts = pts;
picref->pos = pkt.pos;
picref->video->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
- avfilter_start_frame(link, picref);
+ avfilter_start_frame(link, picref, priv->start_frame_flags);
avfilter_draw_slice(link, 0, link->h, 1);
avfilter_end_frame(link);
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index db254d6..96f1090 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -356,9 +356,9 @@ int avfilter_poll_frame(AVFilterLink *link)
/* XXX: should we do the duplicating of the picture ref here, instead of
* forcing the source filter to do it? */
-void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
- void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
+ void (*start_frame)(AVFilterLink *, AVFilterBufferRef *, int);
AVFilterPad *dst = link->dstpad;
FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_ref(NULL, picref, 1);
@@ -381,7 +381,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
else
link->cur_buf = picref;
- start_frame(link, link->cur_buf);
+ start_frame(link, link->cur_buf, flags);
}
void avfilter_end_frame(AVFilterLink *link)
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 5d34bee..a8b0285 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -86,6 +86,7 @@ typedef struct AVFilterBuffer {
#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer
#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time
#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time
+#define AV_PERM_POS_LINESIZES 0x20 ///< the buffer requested cannot have negative linesizes
/**
* Audio specific properties in a reference to an AVFilterBuffer. Since
@@ -349,7 +350,7 @@ struct AVFilterPad {
*
* Input video pads only.
*/
- void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
+ void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref, int flags);
/**
* Callback function to get a video buffer. If NULL, the filter system will
@@ -432,7 +433,7 @@ struct AVFilterPad {
};
/** default handler for start_frame() for video inputs */
-void avfilter_default_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
+void avfilter_default_start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags);
/** default handler for draw_slice() for video inputs */
void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
@@ -469,7 +470,7 @@ void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
int avfilter_default_query_formats(AVFilterContext *ctx);
/** start_frame() handler for filters which simply pass video along */
-void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
+void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags);
/** draw_slice() handler for filters which simply pass video along */
void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
@@ -697,6 +698,8 @@ int avfilter_request_frame(AVFilterLink *link);
*/
int avfilter_poll_frame(AVFilterLink *link);
+#define AVFILTER_START_FRAME_FLAG_INVERTED_BUFFER 0x01
+
/**
* Notifie the next filter of the start of a frame.
*
@@ -706,7 +709,7 @@ int avfilter_poll_frame(AVFilterLink *link);
* portion. The receiving filter will free this reference when
* it no longer needs it.
*/
-void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
+void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags);
/**
* Notifie the next filter that the current frame has finished.
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index aa3739c..59b7198 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -134,7 +134,7 @@ fail:
return NULL;
}
-void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref, int flags)
{
AVFilterLink *outlink = NULL;
@@ -144,7 +144,7 @@ void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picre
if (outlink) {
outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
- avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
+ avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0), flags);
}
}
@@ -266,9 +266,9 @@ int avfilter_default_query_formats(AVFilterContext *ctx)
return 0;
}
-void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
- avfilter_start_frame(link->dst->outputs[0], picref);
+ avfilter_start_frame(link->dst->outputs[0], picref, flags);
}
void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 6f86bf2..fb95fd4 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -61,12 +61,12 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
return 0;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
AspectContext *aspect = link->dst->priv;
picref->video->pixel_aspect = aspect->aspect;
- avfilter_start_frame(link->dst->outputs[0], picref);
+ avfilter_start_frame(link->dst->outputs[0], picref, flags);
}
#if CONFIG_SETDAR_FILTER
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 311ee30..caf0dad 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -233,7 +233,7 @@ static int config_output(AVFilterLink *link)
return 0;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
AVFilterContext *ctx = link->dst;
CropContext *crop = ctx->priv;
@@ -284,7 +284,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
ref2->data[3] += crop->x * crop->max_step[3];
}
- avfilter_start_frame(link->dst->outputs[0], ref2);
+ avfilter_start_frame(link->dst->outputs[0], ref2, flags);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
diff --git a/libavfilter/vf_fifo.c b/libavfilter/vf_fifo.c
index 32199ed..2c5b14a 100644
--- a/libavfilter/vf_fifo.c
+++ b/libavfilter/vf_fifo.c
@@ -56,7 +56,7 @@ static av_cold void uninit(AVFilterContext *ctx)
}
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref, int flags)
{
FifoContext *fifo = inlink->dst->priv;
@@ -82,7 +82,7 @@ static int request_frame(AVFilterLink *outlink)
/* by doing this, we give ownership of the reference to the next filter,
* so we don't have to worry about dereferencing it ourselves. */
- avfilter_start_frame(outlink, fifo->root.next->picref);
+ avfilter_start_frame(outlink, fifo->root.next->picref, 0);
avfilter_draw_slice (outlink, 0, outlink->h, 1);
avfilter_end_frame (outlink);
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 03d4f28..750e9f5 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -434,7 +434,7 @@ static int source_request_frame(AVFilterLink *outlink)
picref->pts = frei0r->pts++;
picref->pos = -1;
- avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0), 0);
frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
NULL, (uint32_t *)picref->data[0]);
avfilter_draw_slice(outlink, 0, outlink->h, 1);
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index a170e81..92d7087 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -205,7 +205,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w,
return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref, int flags)
{
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
AVFilterContext *ctx = inlink->dst;
@@ -226,10 +226,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
over->overpicref = old;
}
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ avfilter_start_frame(inlink->dst->outputs[0], outpicref, flags);
}
-static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref, int flags)
{
AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv;
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index a661b9c..083b0bb 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -243,7 +243,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
return picref;
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref, int flags)
{
PadContext *pad = inlink->dst->priv;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
@@ -259,7 +259,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
(pad->y >> vsub) * outpicref->linesize[plane];
}
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ avfilter_start_frame(inlink->dst->outputs[0], outpicref, flags);
}
static void end_frame(AVFilterLink *link)
@@ -434,7 +434,7 @@ static int color_request_frame(AVFilterLink *link)
picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q);
picref->pos = 0;
- avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
+ avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0), 0);
draw_rectangle(picref,
color->line, color->line_step, color->hsub, color->vsub,
0, 0, color->w, color->h);
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index 1fb577e..e70eafa 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -49,7 +49,7 @@ static int config_props(AVFilterLink *inlink)
return 0;
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref, int flags)
{
PixdescTestContext *priv = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
@@ -75,7 +75,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
if (priv->pix_desc->flags & PIX_FMT_PAL)
memcpy(outpicref->data[1], outpicref->data[1], 256*4);
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0), flags);
}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 100ba2b..6e38435 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -142,7 +142,7 @@ static int config_props(AVFilterLink *outlink)
return !scale->sws;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
ScaleContext *scale = link->dst->priv;
AVFilterLink *outlink = link->dst->outputs[0];
@@ -164,7 +164,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
INT_MAX);
scale->slice_y = 0;
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0), flags);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c
index 0921df7..1f2c947 100644
--- a/libavfilter/vf_setpts.c
+++ b/libavfilter/vf_setpts.c
@@ -98,7 +98,7 @@ static int config_input(AVFilterLink *inlink)
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref, int flags)
{
SetPTSContext *setpts = inlink->dst->priv;
double d;
@@ -127,7 +127,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
setpts->var_values[VAR_N] += 1.0;
setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ avfilter_start_frame(inlink->dst->outputs[0], outpicref, flags);
}
static av_cold void uninit(AVFilterContext *ctx)
diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c
index 3e48ac4..f99ef42 100644
--- a/libavfilter/vf_settb.c
+++ b/libavfilter/vf_settb.c
@@ -102,7 +102,7 @@ static int config_output_props(AVFilterLink *outlink)
return 0;
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref, int flags)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
@@ -117,7 +117,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
avfilter_unref_buffer(picref);
}
- avfilter_start_frame(outlink, picref2);
+ avfilter_start_frame(outlink, picref2, flags);
}
AVFilter avfilter_vf_settb = {
diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c
index 177ac1f..f958d46 100644
--- a/libavfilter/vf_slicify.c
+++ b/libavfilter/vf_slicify.c
@@ -57,7 +57,7 @@ static int config_props(AVFilterLink *link)
return 0;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
SliceContext *slice = link->dst->priv;
@@ -72,7 +72,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h);
- avfilter_start_frame(link->dst->outputs[0], picref);
+ avfilter_start_frame(link->dst->outputs[0], picref, flags);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 970c381..b8dff0e 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -109,7 +109,7 @@ static int config_props_output(AVFilterLink *outlink)
return 0;
}
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref, int flags)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
@@ -124,7 +124,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num;
}
- avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
+ avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0), flags);
}
static void end_frame(AVFilterLink *inlink)
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index 95d90d3..4206fc9 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -24,10 +24,13 @@
*/
#include "libavutil/pixdesc.h"
+#include "libavcore/imgutils.h"
#include "avfilter.h"
typedef struct {
int vsub; ///< vertical chroma subsampling
+ int linesizes[4];
+ int flip_image;
} FlipContext;
static int config_input(AVFilterLink *link)
@@ -35,6 +38,7 @@ static int config_input(AVFilterLink *link)
FlipContext *flip = link->dst->priv;
flip->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
+ av_image_fill_linesizes(flip->linesizes, link->format, link->w);
return 0;
}
@@ -43,11 +47,13 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
int w, int h)
{
FlipContext *flip = link->dst->priv;
+ AVFilterBufferRef *picref;
int i;
- AVFilterBufferRef *picref = avfilter_get_video_buffer(link->dst->outputs[0],
- perms, w, h);
+ if (perms & AV_PERM_POS_LINESIZES)
+ return avfilter_default_get_video_buffer(link, perms, w, h);
+ picref = avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
for (i = 0; i < 4; i ++) {
int vsub = i == 1 || i == 2 ? flip->vsub : 0;
@@ -60,11 +66,18 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
return picref;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
FlipContext *flip = link->dst->priv;
int i;
+ if (flags & AVFILTER_START_FRAME_FLAG_INVERTED_BUFFER) {
+ flags = flags & ~AVFILTER_START_FRAME_FLAG_INVERTED_BUFFER;
+ flip->flip_image = 1;
+ avfilter_default_start_frame(link, picref, flags);
+ return;
+ }
+
for (i = 0; i < 4; i ++) {
int vsub = i == 1 || i == 2 ? flip->vsub : 0;
@@ -74,14 +87,51 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
}
}
- avfilter_start_frame(link->dst->outputs[0], picref);
+ avfilter_start_frame(link->dst->outputs[0], picref, flags);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
AVFilterContext *ctx = link->dst;
+ FlipContext *flip = ctx->priv;
+
+ if (!flip->flip_image)
+ avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ FlipContext *flip = inlink->dst->priv;
+ AVFilterLink *outlink = inlink->dst->outputs[0];
+ AVFilterBufferRef *inpic = inlink->cur_buf;
+ AVFilterBufferRef *outpic = outlink->out_buf;
+ uint8_t *inrow, *outrow;
+ int plane, i, h;
+
+ if (!flip->flip_image) {
+ avfilter_null_end_frame(inlink);
+ return;
+ }
+
+ /* vflip image */
+ for (plane = 0; plane < 4 && inpic->data[plane]; plane++) {
+ h = plane == 1 || plane == 2 ? inlink->h>>flip->vsub : inlink->h;
+
+ inrow = inpic ->data[plane];
+ outrow = outpic->data[plane] + outpic->linesize[plane] * (h-1);
+
+ for (i = 0; i < h; i++) {
+ memcpy(outrow, inrow, flip->linesizes[plane]);
+ inrow += inpic ->linesize[plane];
+ outrow -= outpic->linesize[plane];
+ }
+ }
- avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
+ flip->flip_image = 0;
+ avfilter_unref_buffer(inpic);
+ avfilter_draw_slice(outlink, 0, inlink->h, 1);
+ avfilter_end_frame(outlink);
+ avfilter_unref_buffer(outpic);
}
AVFilter avfilter_vf_vflip = {
@@ -95,7 +145,7 @@ AVFilter avfilter_vf_vflip = {
.get_video_buffer = get_video_buffer,
.start_frame = start_frame,
.draw_slice = draw_slice,
- .end_frame = avfilter_null_end_frame,
+ .end_frame = end_frame,
.config_props = config_input, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index d96e587..b89204c 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -184,7 +184,7 @@ static void return_frame(AVFilterContext *ctx, int is_second)
} else {
yadif->out->pts = AV_NOPTS_VALUE;
}
- avfilter_start_frame(ctx->outputs[0], yadif->out);
+ avfilter_start_frame(ctx->outputs[0], yadif->out, 0);
}
avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
avfilter_end_frame(ctx->outputs[0]);
@@ -192,7 +192,7 @@ static void return_frame(AVFilterContext *ctx, int is_second)
yadif->frame_pending = (yadif->mode&1) && !is_second;
}
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
AVFilterContext *ctx = link->dst;
YADIFContext *yadif = ctx->priv;
@@ -217,7 +217,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0;
- avfilter_start_frame(ctx->outputs[0], yadif->out);
+ avfilter_start_frame(ctx->outputs[0], yadif->out, flags);
}
static void end_frame(AVFilterLink *link)
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index 0998bd0..2d8406a 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -18,7 +18,7 @@
#include "avfilter.h"
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref, int flags)
{
}
diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c
index 74d9bf6..81da3a3 100644
--- a/libavfilter/vsrc_buffer.c
+++ b/libavfilter/vsrc_buffer.c
@@ -130,7 +130,7 @@ static int request_frame(AVFilterLink *link)
picref->video->pixel_aspect = c->pixel_aspect;
picref->video->interlaced = c->frame.interlaced_frame;
picref->video->top_field_first = c->frame.top_field_first;
- avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
+ avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0), 0);
avfilter_draw_slice(link, 0, link->h, 1);
avfilter_end_frame(link);
avfilter_unref_buffer(picref);
--
1.7.2.3
--zYM0uCDKw75PZbzx--
More information about the ffmpeg-devel
mailing list