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