00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libavutil/internal.h"
00027 #include "libavutil/pixdesc.h"
00028 #include "avfilter.h"
00029 #include "internal.h"
00030 #include "video.h"
00031
00032 typedef struct {
00033 int vsub;
00034 } FlipContext;
00035
00036 static int config_input(AVFilterLink *link)
00037 {
00038 FlipContext *flip = link->dst->priv;
00039
00040 flip->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
00041
00042 return 0;
00043 }
00044
00045 static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
00046 int w, int h)
00047 {
00048 FlipContext *flip = link->dst->priv;
00049 AVFilterBufferRef *picref;
00050 int i;
00051
00052 if (!(perms & AV_PERM_NEG_LINESIZES))
00053 return ff_default_get_video_buffer(link, perms, w, h);
00054
00055 picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
00056 if (!picref)
00057 return NULL;
00058
00059 for (i = 0; i < 4; i ++) {
00060 int vsub = i == 1 || i == 2 ? flip->vsub : 0;
00061
00062 if (picref->data[i]) {
00063 picref->data[i] += (((h + (1<<vsub)-1) >> vsub)-1) * picref->linesize[i];
00064 picref->linesize[i] = -picref->linesize[i];
00065 }
00066 }
00067
00068 return picref;
00069 }
00070
00071 static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
00072 {
00073 FlipContext *flip = link->dst->priv;
00074 AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
00075 int i;
00076
00077 if (!outpicref)
00078 return AVERROR(ENOMEM);
00079
00080 for (i = 0; i < 4; i ++) {
00081 int vsub = i == 1 || i == 2 ? flip->vsub : 0;
00082
00083 if (outpicref->data[i]) {
00084 outpicref->data[i] += (((link->h + (1<<vsub)-1)>> vsub)-1) * outpicref->linesize[i];
00085 outpicref->linesize[i] = -outpicref->linesize[i];
00086 }
00087 }
00088
00089 return ff_start_frame(link->dst->outputs[0], outpicref);
00090 }
00091
00092 static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
00093 {
00094 AVFilterContext *ctx = link->dst;
00095
00096 return ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
00097 }
00098
00099 AVFilter avfilter_vf_vflip = {
00100 .name = "vflip",
00101 .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."),
00102
00103 .priv_size = sizeof(FlipContext),
00104
00105 .inputs = (const AVFilterPad[]) {{ .name = "default",
00106 .type = AVMEDIA_TYPE_VIDEO,
00107 .get_video_buffer = get_video_buffer,
00108 .start_frame = start_frame,
00109 .draw_slice = draw_slice,
00110 .config_props = config_input, },
00111 { .name = NULL}},
00112 .outputs = (const AVFilterPad[]) {{ .name = "default",
00113 .type = AVMEDIA_TYPE_VIDEO, },
00114 { .name = NULL}},
00115 };