1 /*
2 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * FFmpeg 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 /**
22 * @file
23 * Motion Compensation Deinterlacer
24 * Ported from MPlayer libmpcodecs/vf_mcdeint.c.
25 *
26 * Known Issues:
27 *
28 * The motion estimation is somewhat at the mercy of the input, if the
29 * input frames are created purely based on spatial interpolation then
30 * for example a thin black line or another random and not
31 * interpolateable pattern will cause problems.
32 * Note: completely ignoring the "unavailable" lines during motion
33 * estimation did not look any better, so the most obvious solution
34 * would be to improve tfields or penalize problematic motion vectors.
35 *
36 * If non iterative ME is used then snow currently ignores the OBMC
37 * window and as a result sometimes creates artifacts.
38 *
39 * Only past frames are used, we should ideally use future frames too,
40 * something like filtering the whole movie in forward and then
41 * backward direction seems like an interesting idea but the current
42 * filter framework is FAR from supporting such things.
43 *
44 * Combining the motion compensated image with the input image also is
45 * not as trivial as it seems, simple blindly taking even lines from
46 * one and odd ones from the other does not work at all as ME/MC
47 * sometimes has nothing in the previous frames which matches the
48 * current. The current algorithm has been found by trial and error
49 * and almost certainly can be improved...
50 */
51
58
65 };
66
70 };
71
79
80 #define OFFSET(x) offsetof(MCDeintContext, x)
81 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
82 #define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit }
83
90
94
97 };
98
100
102 {
108 int ret;
109
113 }
114
119 enc_ctx->
width = inlink->
w;
132
133 switch (mcdeint->
mode) {
143 }
144
147 if (ret < 0)
148 return ret;
149
150 return 0;
151 }
152
154 {
156
158 }
159
161 {
164 };
166 if (!fmts_list)
169 }
170
172 {
177 int x, y, i, ret, got_frame = 0;
178
180 if (!outpic) {
183 }
186
188
190 if (ret < 0)
192
194
195 for (i = 0; i < 3; i++) {
196 int is_chroma = !!i;
202
203 for (y = 0; y <
h; y++) {
204 if ((y ^ mcdeint->
parity) & 1) {
205 for (x = 0; x <
w; x++) {
209
210 if (y > 0 && y < h-1){
211 int is_edge = x < 3 || x > w-4;
212 int diff0 = filp[-fils] - srcp[-srcs];
213 int diff1 = filp[+fils] - srcp[+srcs];
215
216 #define DELTA(j) av_clip(j, -x, w-1-x)
217
218 #define GET_SCORE_EDGE(j)\
219 FFABS(srcp[-srcs+DELTA(-1+(j))] - srcp[+srcs+DELTA(-1-(j))])+\
220 FFABS(srcp[-srcs+DELTA(j) ] - srcp[+srcs+DELTA( -(j))])+\
221 FFABS(srcp[-srcs+DELTA(1+(j)) ] - srcp[+srcs+DELTA( 1-(j))])
222
223 #define GET_SCORE(j)\
224 FFABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])+\
225 FFABS(srcp[-srcs +(j)] - srcp[+srcs -(j)])+\
226 FFABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)])
227
228 #define CHECK_EDGE(j)\
229 { int score = GET_SCORE_EDGE(j);\
230 if (score < spatial_score){\
231 spatial_score = score;\
232 diff0 = filp[-fils+DELTA(j)] - srcp[-srcs+DELTA(j)];\
233 diff1 = filp[+fils+DELTA(-(j))] - srcp[+srcs+DELTA(-(j))];\
234
235 #define CHECK(j)\
236 { int score = GET_SCORE(j);\
237 if (score < spatial_score){\
238 spatial_score= score;\
239 diff0 = filp[-fils+(j)] - srcp[-srcs+(j)];\
240 diff1 = filp[+fils-(j)] - srcp[+srcs-(j)];\
241
242 if (is_edge) {
246 } else {
250 }
251
252
253 if (diff0 + diff1 > 0)
260 }
261 }
262 }
263 }
264
265 for (y = 0; y <
h; y++) {
266 if (!((y ^ mcdeint->parity) & 1)) {
267 for (x = 0; x <
w; x++) {
268 frame_dec->data[i][x + y*fils] =
269 outpic ->data[i][x + y*dsts] =
inpic->data[i][x + y*srcs];
270 }
271 }
272 }
273 }
274 mcdeint->parity ^= 1;
275
281 return ret;
282 }
284 }
285
287 {
292 },
294 };
295
297 {
300 },
302 };
303
312 .priv_class = &mcdeint_class,
313 };
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
static const AVFilterPad mcdeint_inputs[]
This structure describes decoded (raw) audio or video data.
AVCodec * avcodec_find_encoder(enum AVCodecID id)
Find a registered encoder with a matching codec ID.
Main libavfilter public API header.
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
int h
agreed upon image height
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
BYTE int const BYTE * srcp
const char * name
Pad name.
#define GET_SCORE_EDGE(j)
static av_cold int end(AVCodecContext *avctx)
#define AV_CODEC_FLAG_LOW_DELAY
Force low delay.
int me_cmp
motion estimation comparison function
static const AVFilterPad mcdeint_outputs[]
AVFILTER_DEFINE_CLASS(mcdeint)
#define CONST(name, help, val, unit)
A filter pad used for either input or output.
A link between two filters.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define AV_CODEC_FLAG_4MV
4 MV per MB allowed / advanced prediction for H.263.
return ff_filter_frame(outlink, outpic)
static int config_props(AVFilterLink *inlink)
int me_sub_cmp
subpixel motion estimation comparison function
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
int flags
AV_CODEC_FLAG_*.
int w
agreed upon image width
static av_cold void uninit(AVFilterContext *ctx)
int refs
number of reference frames
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
int width
picture width / height.
static const AVOption mcdeint_options[]
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
int quality
quality (between 1 (good) and FF_LAMBDA_MAX (bad))
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
Libavcodec external API header.
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer...
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
static int query_formats(AVFilterContext *ctx)
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Describe the class of an AVClass context structure.
Rational number (pair of numerator and denominator).
attribute_deprecated int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Encode a frame of video.
const char * name
Filter name.
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
AVFilterLink ** outputs
array of pointers to output links
static enum AVPixelFormat pix_fmts[]
int global_quality
Global quality for codecs which cannot change it per frame.
#define AV_CODEC_FLAG_QPEL
Use qpel MC.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
int mb_cmp
macroblock comparison function (not supported yet)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
int dia_size
ME diamond size & shape.
AVFilterContext * dst
dest filter
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
AVPixelFormat
Pixel format.
This structure stores compressed data.
mode
Use these values in ebur128_init (or'ed).
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_CEIL_RSHIFT(a, b)