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 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
00040
00041 flip->vsub = desc->log2_chroma_h;
00042
00043 return 0;
00044 }
00045
00046 static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
00047 int w, int h)
00048 {
00049 FlipContext *flip = link->dst->priv;
00050 AVFilterBufferRef *picref;
00051 int i;
00052
00053 if (!(perms & AV_PERM_NEG_LINESIZES))
00054 return ff_default_get_video_buffer(link, perms, w, h);
00055
00056 picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
00057 if (!picref)
00058 return NULL;
00059
00060 for (i = 0; i < 4; i ++) {
00061 int vsub = i == 1 || i == 2 ? flip->vsub : 0;
00062
00063 if (picref->data[i]) {
00064 picref->data[i] += (((h + (1<<vsub)-1) >> vsub)-1) * picref->linesize[i];
00065 picref->linesize[i] = -picref->linesize[i];
00066 }
00067 }
00068
00069 return picref;
00070 }
00071
00072 static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
00073 {
00074 FlipContext *flip = link->dst->priv;
00075 int i;
00076
00077 for (i = 0; i < 4; i ++) {
00078 int vsub = i == 1 || i == 2 ? flip->vsub : 0;
00079
00080 if (frame->data[i]) {
00081 frame->data[i] += (((link->h + (1<<vsub)-1)>> vsub)-1) * frame->linesize[i];
00082 frame->linesize[i] = -frame->linesize[i];
00083 }
00084 }
00085
00086 return ff_filter_frame(link->dst->outputs[0], frame);
00087 }
00088 static const AVFilterPad avfilter_vf_vflip_inputs[] = {
00089 {
00090 .name = "default",
00091 .type = AVMEDIA_TYPE_VIDEO,
00092 .get_video_buffer = get_video_buffer,
00093 .filter_frame = filter_frame,
00094 .config_props = config_input,
00095 },
00096 { NULL }
00097 };
00098
00099 static const AVFilterPad avfilter_vf_vflip_outputs[] = {
00100 {
00101 .name = "default",
00102 .type = AVMEDIA_TYPE_VIDEO,
00103 },
00104 { NULL }
00105 };
00106
00107 AVFilter avfilter_vf_vflip = {
00108 .name = "vflip",
00109 .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."),
00110
00111 .priv_size = sizeof(FlipContext),
00112
00113 .inputs = avfilter_vf_vflip_inputs,
00114 .outputs = avfilter_vf_vflip_outputs,
00115 };