FFmpeg
Loading...
Searching...
No Matches
yadif_common.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at>
3 * 2010 James Darnley <james.darnley@gmail.com>
4
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/avassert.h"
23#include "libavutil/imgutils.h"
24#include "filters.h"
25#include "video.h"
26#include "yadif.h"
27
28static int return_frame(AVFilterContext *ctx, int is_second)
29{
30 YADIFContext *yadif = ctx->priv;
31 AVFilterLink *link = ctx->outputs[0];
32 int tff, ret;
33
34 if (yadif->parity == -1) {
35 tff = (yadif->cur->flags & AV_FRAME_FLAG_INTERLACED) ?
36 !!(yadif->cur->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1;
37 } else {
38 tff = yadif->parity ^ 1;
39 }
40
41 if (is_second) {
42 yadif->out = ff_get_video_buffer(link, link->w, link->h);
43 if (!yadif->out)
44 return AVERROR(ENOMEM);
45
46 av_frame_copy_props(yadif->out, yadif->cur);
50 }
51
52 yadif->filter(ctx, yadif->out, tff ^ !is_second, tff);
53
54 if (is_second) {
55 int64_t cur_pts = yadif->cur->pts;
56 int64_t next_pts = yadif->next->pts;
57
58 if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {
59 yadif->out->pts = cur_pts + next_pts;
60 if (yadif->pts_multiplier == 1) {
61 yadif->out->pts >>= 1;
62 yadif->out->duration >>= 1;
63 }
64 } else {
65 yadif->out->pts = AV_NOPTS_VALUE;
66 }
67 }
68
69 ff_ccfifo_inject(&yadif->cc_fifo, yadif->out);
70 ret = ff_filter_frame(ctx->outputs[0], yadif->out);
71
72 yadif->frame_pending = (yadif->mode&1) && !is_second;
73 return ret;
74}
75
76static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b)
77{
78 int i;
79 for (i = 0; i < yadif->csp->nb_components; i++)
80 if (a->linesize[i] != b->linesize[i])
81 return 1;
82 return 0;
83}
84
85static void fixstride(AVFilterLink *link, AVFrame *f)
86{
87 AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height);
88 if(!dst)
89 return;
91 av_image_copy2(dst->data, dst->linesize,
92 f->data, f->linesize,
93 dst->format, dst->width, dst->height);
97}
98
100{
101 AVFilterContext *ctx = link->dst;
102 YADIFContext *yadif = ctx->priv;
103
105
107
108 if (yadif->frame_pending)
109 return_frame(ctx, 1);
110
111 if (yadif->prev)
112 av_frame_free(&yadif->prev);
113 yadif->prev = yadif->cur;
114 yadif->cur = yadif->next;
115 yadif->next = frame;
116
117 if (!yadif->cur) {
118 yadif->cur = av_frame_clone(yadif->next);
119 if (!yadif->cur)
120 return AVERROR(ENOMEM);
122 }
123
124 if (checkstride(yadif, yadif->next, yadif->cur)) {
125 av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n");
126 fixstride(link, yadif->next);
127 }
128 if (checkstride(yadif, yadif->next, yadif->cur))
129 fixstride(link, yadif->cur);
130 if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))
131 fixstride(link, yadif->prev);
132 if (checkstride(yadif, yadif->next, yadif->cur) || (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))) {
133 av_log(ctx, AV_LOG_ERROR, "Failed to reallocate frame\n");
134 return -1;
135 }
136
137 if (!yadif->prev)
138 return 0;
139
140 if ((yadif->deint && !(yadif->cur->flags & AV_FRAME_FLAG_INTERLACED)) ||
141 ctx->is_disabled ||
142 (yadif->deint && !(yadif->prev->flags & AV_FRAME_FLAG_INTERLACED) && yadif->prev->repeat_pict) ||
143 (yadif->deint && !(yadif->next->flags & AV_FRAME_FLAG_INTERLACED) && yadif->next->repeat_pict)
144 ) {
145 yadif->out = av_frame_clone(yadif->cur);
146 if (!yadif->out)
147 return AVERROR(ENOMEM);
148
149 ff_ccfifo_inject(&yadif->cc_fifo, yadif->out);
150 av_frame_free(&yadif->prev);
151 if (yadif->out->pts != AV_NOPTS_VALUE)
152 yadif->out->pts *= yadif->pts_multiplier;
153 yadif->out->duration *= yadif->pts_multiplier;
154 return ff_filter_frame(ctx->outputs[0], yadif->out);
155 }
156
157 yadif->out = ff_get_video_buffer(ctx->outputs[0], link->w, link->h);
158 if (!yadif->out)
159 return AVERROR(ENOMEM);
160
161 av_frame_copy_props(yadif->out, yadif->cur);
163
164 if (yadif->out->pts != AV_NOPTS_VALUE)
165 yadif->out->pts *= yadif->pts_multiplier;
166 if (!(yadif->mode & 1))
167 yadif->out->duration *= yadif->pts_multiplier;
168 else if (yadif->pts_multiplier == 1)
169 yadif->out->duration >>= 1;
170
171 return return_frame(ctx, 0);
172}
173
175{
176 AVFilterContext *ctx = link->src;
177 YADIFContext *yadif = ctx->priv;
178 int ret;
179
180 if (yadif->frame_pending) {
181 return_frame(ctx, 1);
182 return 0;
183 }
184
185 if (yadif->eof)
186 return AVERROR_EOF;
187
188 ret = ff_request_frame(ctx->inputs[0]);
189
190 if (ret == AVERROR_EOF && yadif->cur) {
191 AVFrame *next = av_frame_clone(yadif->next);
192
193 if (!next)
194 return AVERROR(ENOMEM);
195
197 next->pts = yadif->next->pts * 2 - yadif->cur->pts;
198
199 ff_yadif_filter_frame(ctx->inputs[0], next);
200 yadif->eof = 1;
201 } else if (ret < 0) {
202 return ret;
203 }
204
205 return 0;
206}
207
209{
210 AVFilterContext *ctx = outlink->src;
211 FilterLink *il = ff_filter_link(ctx->inputs[0]);
212 FilterLink *ol = ff_filter_link(outlink);
213 YADIFContext *yadif = ctx->priv;
214 AVRational tb = ctx->inputs[0]->time_base;
215 int ret;
216
217 if (av_reduce(&outlink->time_base.num, &outlink->time_base.den, tb.num, tb.den * 2LL, INT_MAX)) {
218 yadif->pts_multiplier = 2;
219 } else {
220 av_log(ctx, AV_LOG_WARNING, "Cannot use exact output timebase\n");
221 outlink->time_base = tb;
222 yadif->pts_multiplier = 1;
223 }
224
225 outlink->w = ctx->inputs[0]->w;
226 outlink->h = ctx->inputs[0]->h;
227
228 if (outlink->w < 3 || outlink->h < 3) {
229 av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");
230 return AVERROR(EINVAL);
231 }
232
233 if(yadif->mode & 1)
235 (AVRational){2, 1});
236 else
237 ol->frame_rate = il->frame_rate;
238
239 ret = ff_ccfifo_init(&yadif->cc_fifo, ol->frame_rate, ctx);
240 if (ret < 0) {
241 av_log(ctx, AV_LOG_ERROR, "Failure to setup CC FIFO queue\n");
242 return ret;
243 }
244
245 return 0;
246}
247
249{
250 YADIFContext *yadif = ctx->priv;
251
252 av_frame_free(&yadif->prev);
253 av_frame_free(&yadif->cur );
254 av_frame_free(&yadif->next);
255 ff_ccfifo_uninit(&yadif->cc_fifo);
256}
257
258#define OFFSET(x) offsetof(YADIFContext, x)
259#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
260
261#define CONST(name, help, val, u) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, .unit = u }
262
264 { "mode", "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=YADIF_MODE_SEND_FRAME}, 0, 3, FLAGS, .unit = "mode"},
265 CONST("send_frame", "send one frame for each frame", YADIF_MODE_SEND_FRAME, "mode"),
266 CONST("send_field", "send one frame for each field", YADIF_MODE_SEND_FIELD, "mode"),
267 CONST("send_frame_nospatial", "send one frame for each frame, but skip spatial interlacing check", YADIF_MODE_SEND_FRAME_NOSPATIAL, "mode"),
268 CONST("send_field_nospatial", "send one frame for each field, but skip spatial interlacing check", YADIF_MODE_SEND_FIELD_NOSPATIAL, "mode"),
269
270 { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=YADIF_PARITY_AUTO}, -1, 1, FLAGS, .unit = "parity" },
271 CONST("tff", "assume top field first", YADIF_PARITY_TFF, "parity"),
272 CONST("bff", "assume bottom field first", YADIF_PARITY_BFF, "parity"),
273 CONST("auto", "auto detect parity", YADIF_PARITY_AUTO, "parity"),
274
275 { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=YADIF_DEINT_ALL}, 0, 1, FLAGS, .unit = "deint" },
276 CONST("all", "deinterlace all frames", YADIF_DEINT_ALL, "deint"),
277 CONST("interlaced", "only deinterlace frames marked as interlaced", YADIF_DEINT_INTERLACED, "deint"),
278
279 { NULL }
280};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition avfilter.c:483
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVFrame * frame
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:695
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:700
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition frame.c:483
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition imgutils.h:184
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
int a
misc image utilities
#define b
Definition input.c:43
int ff_ccfifo_inject(CCFifo *ccf, AVFrame *frame)
Insert CC data from the FIFO into an AVFrame (as side data)
Definition ccfifo.c:133
int ff_ccfifo_init(CCFifo *ccf, AVRational framerate, void *log_ctx)
Initialize a CCFifo.
Definition ccfifo.c:53
void ff_ccfifo_uninit(CCFifo *ccf)
Free all memory allocated in a CCFifo and clear the context.
Definition ccfifo.c:46
int ff_ccfifo_extract(CCFifo *ccf, AVFrame *frame)
Extract CC data from an AVFrame.
Definition ccfifo.c:183
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
An instance of a filter.
Definition avfilter.h:273
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
int64_t duration
Duration of the frame, in the same units as pts.
Definition frame.h:820
int repeat_pict
Number of fields in this frame which should be repeated, i.e.
Definition frame.h:630
AVOption.
Definition opt.h:428
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVFrame * prev
Definition yadif.h:62
int deint
YADIFDeint.
Definition yadif.h:56
AVFrame * cur
Definition yadif.h:60
AVFrame * next
Definition yadif.h:61
void(* filter)(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff)
Definition yadif.h:65
int mode
YADIFMode.
Definition yadif.h:54
int pts_multiplier
Definition yadif.h:90
int current_field
YADIFCurrentField.
Definition yadif.h:88
const AVPixFmtDescriptor * csp
Definition yadif.h:76
int frame_pending
Definition yadif.h:58
int eof
Definition yadif.h:77
AVFrame * out
Definition yadif.h:63
CCFifo cc_fifo
Definition yadif.h:80
int parity
YADIFParity.
Definition yadif.h:55
Definition swscale.c:71
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
mcdeint parity
Definition vf_mcdeint.c:293
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89
AVFrame * ff_default_get_video_buffer(AVFilterLink *link, int w, int h)
Definition video.c:84
@ YADIF_DEINT_INTERLACED
only deinterlace frames marked as interlaced
Definition yadif.h:42
@ YADIF_DEINT_ALL
deinterlace all frames
Definition yadif.h:41
@ YADIF_PARITY_TFF
top field first
Definition yadif.h:35
@ YADIF_PARITY_BFF
bottom field first
Definition yadif.h:36
@ YADIF_PARITY_AUTO
auto detection
Definition yadif.h:37
@ YADIF_FIELD_BACK_END
The last frame in a sequence.
Definition yadif.h:46
@ YADIF_FIELD_END
The first or last field in a sequence.
Definition yadif.h:47
@ YADIF_MODE_SEND_FIELD_NOSPATIAL
send 1 frame for each field but skips spatial interlacing check
Definition yadif.h:31
@ YADIF_MODE_SEND_FIELD
send 1 frame for each field
Definition yadif.h:29
@ YADIF_MODE_SEND_FRAME_NOSPATIAL
send 1 frame for each frame but skips spatial interlacing check
Definition yadif.h:30
@ YADIF_MODE_SEND_FRAME
send 1 frame for each frame
Definition yadif.h:28
const AVOption ff_yadif_options[]
static int return_frame(AVFilterContext *ctx, int is_second)
static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b)
int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
static void fixstride(AVFilterLink *link, AVFrame *f)
#define CONST(name, help, val, u)
int ff_yadif_request_frame(AVFilterLink *link)
void ff_yadif_uninit(AVFilterContext *ctx)
#define OFFSET(x)
int ff_yadif_config_output_common(AVFilterLink *outlink)