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