vf_fieldorder.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Mark Himsley
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 /* #define DEBUG */
27 
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include "libavutil/imgutils.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/pixdesc.h"
34 #include "avfilter.h"
35 #include "formats.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 typedef struct
40 {
41  unsigned int dst_tff;
42  int line_size[4];
44 
45 static av_cold int init(AVFilterContext *ctx, const char *args)
46 {
47  FieldOrderContext *fieldorder = ctx->priv;
48 
49  const char *tff = "tff";
50  const char *bff = "bff";
51 
52  if (!args) {
53  fieldorder->dst_tff = 1;
54  } else if (sscanf(args, "%u", &fieldorder->dst_tff) == 1) {
55  fieldorder->dst_tff = !!fieldorder->dst_tff;
56  } else if (!strcmp(tff, args)) {
57  fieldorder->dst_tff = 1;
58  } else if (!strcmp(bff, args)) {
59  fieldorder->dst_tff = 0;
60  } else {
61  av_log(ctx, AV_LOG_ERROR, "Invalid argument '%s'.\n", args);
62  return AVERROR(EINVAL);
63  }
64 
65  av_log(ctx, AV_LOG_VERBOSE, "output field order: %s\n",
66  fieldorder->dst_tff ? tff : bff);
67 
68  return 0;
69 }
70 
72 {
75  int ret;
76 
79  if (ctx->inputs[0]) {
80  formats = NULL;
81  for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) {
82  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
83  if (!(desc->flags & PIX_FMT_HWACCEL ||
84  desc->flags & PIX_FMT_BITSTREAM) &&
85  desc->nb_components && !desc->log2_chroma_h &&
86  (ret = ff_add_format(&formats, pix_fmt)) < 0) {
87  ff_formats_unref(&formats);
88  return ret;
89  }
90  }
91  ff_formats_ref(formats, &ctx->inputs[0]->out_formats);
92  ff_formats_ref(formats, &ctx->outputs[0]->in_formats);
93  }
94 
95  return 0;
96 }
97 
98 static int config_input(AVFilterLink *inlink)
99 {
100  AVFilterContext *ctx = inlink->dst;
101  FieldOrderContext *fieldorder = ctx->priv;
102  int plane;
103 
106  for (plane = 0; plane < 4; plane++) {
107  fieldorder->line_size[plane] = av_image_get_linesize(
108  inlink->format,
109  inlink->w,
110  plane);
111  }
112 
113  return 0;
114 }
115 
116 static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
117 {
118  AVFilterContext *ctx = inlink->dst;
119  AVFilterLink *outlink = ctx->outputs[0];
120 
121  return ff_get_video_buffer(outlink, perms, w, h);
122 }
123 
124 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
125 {
126  AVFilterContext *ctx = inlink->dst;
127  FieldOrderContext *s = ctx->priv;
128  AVFilterLink *outlink = ctx->outputs[0];
129  int h, plane, line_step, line_size, line;
130  uint8_t *data;
131 
132  if (!frame->video->interlaced ||
133  frame->video->top_field_first == s->dst_tff)
134  return ff_filter_frame(outlink, frame);
135 
136  av_dlog(ctx,
137  "picture will move %s one line\n",
138  s->dst_tff ? "up" : "down");
139  h = frame->video->h;
140  for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
141  line_step = frame->linesize[plane];
142  line_size = s->line_size[plane];
143  data = frame->data[plane];
144  if (s->dst_tff) {
150  for (line = 0; line < h; line++) {
151  if (1 + line < frame->video->h) {
152  memcpy(data, data + line_step, line_size);
153  } else {
154  memcpy(data, data - line_step - line_step, line_size);
155  }
156  data += line_step;
157  }
158  } else {
164  data += (h - 1) * line_step;
165  for (line = h - 1; line >= 0 ; line--) {
166  if (line > 0) {
167  memcpy(data, data - line_step, line_size);
168  } else {
169  memcpy(data, data + line_step + line_step, line_size);
170  }
171  data -= line_step;
172  }
173  }
174  }
175  frame->video->top_field_first = s->dst_tff;
176 
177  return ff_filter_frame(outlink, frame);
178 }
179 
181  {
182  .name = "default",
183  .type = AVMEDIA_TYPE_VIDEO,
184  .config_props = config_input,
185  .get_video_buffer = get_video_buffer,
186  .filter_frame = filter_frame,
187  .min_perms = AV_PERM_READ | AV_PERM_WRITE,
188  .rej_perms = AV_PERM_REUSE2 | AV_PERM_PRESERVE,
189  },
190  { NULL }
191 };
192 
194  {
195  .name = "default",
196  .type = AVMEDIA_TYPE_VIDEO,
197  },
198  { NULL }
199 };
200 
202  .name = "fieldorder",
203  .description = NULL_IF_CONFIG_SMALL("Set the field order."),
204  .init = init,
205  .priv_size = sizeof(FieldOrderContext),
207  .inputs = avfilter_vf_fieldorder_inputs,
208  .outputs = avfilter_vf_fieldorder_outputs,
209 };
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane...
Definition: imgutils.c:48
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1435
AVFilterBufferRefVideoProps * video
video buffer specific properties
Definition: avfilter.h:159
int linesize[8]
number of bytes per line
Definition: avfilter.h:157
misc image utilities
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:122
int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:459
static int query_formats(AVFilterContext *ctx)
Definition: vf_fieldorder.c:71
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static enum AVSampleFormat formats[]
#define AV_PERM_READ
can read from the buffer
Definition: avfilter.h:97
const char * name
Pad name.
Definition: internal.h:39
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:426
uint8_t
int top_field_first
field order
Definition: avfilter.h:126
const char data[16]
Definition: mxf.c:66
static const AVFilterPad avfilter_vf_fieldorder_inputs[]
A filter pad used for either input or output.
Definition: internal.h:33
int line_size[4]
bytes of pixel data per line for each plane
Definition: vf_fieldorder.c:42
AVFilterBufferRef * ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:145
int h
image height
Definition: avfilter.h:123
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:75
static av_cold int init(AVFilterContext *ctx, const char *args)
Definition: vf_fieldorder.c:45
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:88
void * priv
private data for use by the filter
Definition: avfilter.h:439
Definition: graph2dot.c:48
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
common internal API header
AVFilter avfilter_vf_fieldorder
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
#define PIX_FMT_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:88
enum AVPixelFormat pix_fmt
Definition: movenc.c:801
A reference to an AVFilterBuffer.
Definition: avfilter.h:139
#define PIX_FMT_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:89
NULL
Definition: eval.c:52
void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:262
uint8_t flags
Definition: pixdesc.h:76
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
Filter definition.
Definition: avfilter.h:371
static const AVFilterPad inputs[]
Definition: af_ashowinfo.c:110
void ff_formats_unref(AVFilterFormats **ref)
If *ref is non-NULL, remove *ref as a reference to the format list it currently points to...
Definition: formats.c:298
const char * name
filter name
Definition: avfilter.h:372
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:433
static const AVFilterPad avfilter_vf_fieldorder_outputs[]
#define AV_PERM_PRESERVE
nobody else can overwrite the buffer
Definition: avfilter.h:99
static AVFilterBufferRef * get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
int interlaced
is frame interlaced
Definition: avfilter.h:125
unsigned int dst_tff
output bff/tff
Definition: vf_fieldorder.c:41
#define AV_PERM_REUSE2
can output the buffer multiple times, modified each time
Definition: avfilter.h:101
static int config_input(AVFilterLink *inlink)
Definition: vf_fieldorder.c:98
#define AV_PERM_WRITE
can write to the buffer
Definition: avfilter.h:98
int ff_add_format(AVFilterFormats **avff, int fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:199
uint8_t * data[8]
picture/audio data for each plane
Definition: avfilter.h:141
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:418
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:181
internal API functions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:63