45#define OFFSET(x) offsetof(MEContext, x)
46#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
47#define CONST(name, help, val, u) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, .unit = u }
85 s->mb_size = 1 <<
s->log2_mb_size;
87 s->b_width = inlink->
w >>
s->log2_mb_size;
88 s->b_height = inlink->
h >>
s->log2_mb_size;
89 s->b_count =
s->b_width *
s->b_height;
94 for (
i = 0;
i < 3;
i++) {
95 s->mv_table[
i] =
av_calloc(
s->b_count,
sizeof(*
s->mv_table[0]));
100 ff_me_init_context(&
s->me_ctx,
s->mb_size,
s->search_param, inlink->
w, inlink->
h, 0, (
s->b_width - 1) <<
s->log2_mb_size, 0, (
s->b_height - 1) <<
s->log2_mb_size);
106 int x,
int y,
int x_mv,
int y_mv,
int dir)
110 mv->dst_x = x + (mb_size >> 1);
111 mv->dst_y = y + (mb_size >> 1);
112 mv->src_x = x_mv + (mb_size >> 1);
113 mv->src_y = y_mv + (mb_size >> 1);
114 mv->source = dir ? 1 : -1;
118#define SEARCH_MV(method)\
120 for (mb_y = 0; mb_y < s->b_height; mb_y++)\
121 for (mb_x = 0; mb_x < s->b_width; mb_x++) {\
122 const int x_mb = mb_x << s->log2_mb_size;\
123 const int y_mb = mb_y << s->log2_mb_size;\
124 int mv[2] = {x_mb, y_mb};\
125 ff_me_search_##method(me_ctx, x_mb, y_mb, mv);\
126 add_mv_data(((AVMotionVector *) sd->data) + mv_count++, me_ctx->mb_size, x_mb, y_mb, mv[0], mv[1], dir);\
130#define ADD_PRED(preds, px, py)\
132 preds.mvs[preds.nb][0] = px;\
133 preds.mvs[preds.nb][1] = py;\
158 s->mv_table[2] = memcpy(
s->mv_table[2],
s->mv_table[1],
sizeof(*
s->mv_table[1]) *
s->b_count);
159 s->mv_table[1] = memcpy(
s->mv_table[1],
s->mv_table[0],
sizeof(*
s->mv_table[0]) *
s->b_count);
177 const int nb_dirs =
s->next ? 2 : 1;
189 for (dir = 0; dir < nb_dirs; dir++) {
207 for (mb_y = 0; mb_y <
s->b_height; mb_y++)
208 for (mb_x = 0; mb_x <
s->b_width; mb_x++) {
209 const int mb_i = mb_x + mb_y *
s->b_width;
210 const int x_mb = mb_x <<
s->log2_mb_size;
211 const int y_mb = mb_y <<
s->log2_mb_size;
212 int mv[2] = {x_mb, y_mb};
221 ADD_PRED(preds[0],
s->mv_table[0][mb_i - 1][dir][0],
s->mv_table[0][mb_i - 1][dir][1]);
225 ADD_PRED(preds[0],
s->mv_table[0][mb_i -
s->b_width][dir][0],
s->mv_table[0][mb_i -
s->b_width][dir][1]);
228 if (mb_x + 1 <
s->b_width)
229 ADD_PRED(preds[0],
s->mv_table[0][mb_i -
s->b_width + 1][dir][0],
s->mv_table[0][mb_i -
s->b_width + 1][dir][1]);
232 ADD_PRED(preds[0],
s->mv_table[0][mb_i -
s->b_width - 1][dir][0],
s->mv_table[0][mb_i -
s->b_width - 1][dir][1]);
236 if (preds[0].nb == 4) {
237 me_ctx->
pred_x =
mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
238 me_ctx->
pred_y =
mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
239 }
else if (preds[0].nb == 3) {
240 me_ctx->
pred_x =
mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
241 me_ctx->
pred_y =
mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
242 }
else if (preds[0].nb == 2) {
252 s->mv_table[0][mb_i][dir][0] =
mv[0] - x_mb;
253 s->mv_table[0][mb_i][dir][1] =
mv[1] - y_mb;
259 for (mb_y = 0; mb_y <
s->b_height; mb_y++)
260 for (mb_x = 0; mb_x <
s->b_width; mb_x++) {
261 const int mb_i = mb_x + mb_y *
s->b_width;
262 const int x_mb = mb_x <<
s->log2_mb_size;
263 const int y_mb = mb_y <<
s->log2_mb_size;
264 int mv[2] = {x_mb, y_mb};
274 ADD_PRED(preds[0],
s->mv_table[0][mb_i - 1][dir][0],
s->mv_table[0][mb_i - 1][dir][1]);
278 ADD_PRED(preds[0],
s->mv_table[0][mb_i -
s->b_width][dir][0],
s->mv_table[0][mb_i -
s->b_width][dir][1]);
281 if (mb_y > 0 && mb_x + 1 <
s->b_width)
282 ADD_PRED(preds[0],
s->mv_table[0][mb_i -
s->b_width + 1][dir][0],
s->mv_table[0][mb_i -
s->b_width + 1][dir][1]);
285 if (preds[0].nb == 4) {
286 me_ctx->
pred_x =
mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
287 me_ctx->
pred_y =
mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
288 }
else if (preds[0].nb == 3) {
289 me_ctx->
pred_x =
mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
290 me_ctx->
pred_y =
mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
291 }
else if (preds[0].nb == 2) {
300 ADD_PRED(preds[0],
s->mv_table[1][mb_i][dir][0],
s->mv_table[1][mb_i][dir][1]);
303 ADD_PRED(preds[1],
s->mv_table[1][mb_i][dir][0] + (
s->mv_table[1][mb_i][dir][0] -
s->mv_table[2][mb_i][dir][0]),
304 s->mv_table[1][mb_i][dir][1] + (
s->mv_table[1][mb_i][dir][1] -
s->mv_table[2][mb_i][dir][1]));
308 ADD_PRED(preds[1],
s->mv_table[1][mb_i - 1][dir][0],
s->mv_table[1][mb_i - 1][dir][1]);
312 ADD_PRED(preds[1],
s->mv_table[1][mb_i -
s->b_width][dir][0],
s->mv_table[1][mb_i -
s->b_width][dir][1]);
315 if (mb_x + 1 <
s->b_width)
316 ADD_PRED(preds[1],
s->mv_table[1][mb_i + 1][dir][0],
s->mv_table[1][mb_i + 1][dir][1]);
319 if (mb_y + 1 <
s->b_height)
320 ADD_PRED(preds[1],
s->mv_table[1][mb_i +
s->b_width][dir][0],
s->mv_table[1][mb_i +
s->b_width][dir][1]);
324 s->mv_table[0][mb_i][dir][0] =
mv[0] - x_mb;
325 s->mv_table[0][mb_i][dir][1] =
mv[1] - y_mb;
356 for (
i = 0;
i < 3;
i++)
378 .p.name =
"mestimate",
380 .p.priv_class = &mestimate_class,
static int config_input(AVFilterLink *inlink)
static int request_frame(AVFilterLink *outlink)
const FFFilter ff_vf_mestimate
static AVFormatContext * ctx
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
common internal and external API header
static av_always_inline av_const int av_ceil_log2_c(int x)
Compute ceil(log2(x)).
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
@ AV_OPT_TYPE_INT
Underlying C type is int.
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
#define AVERROR_EOF
End of file.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrameSideData * av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, size_t size)
Add a new side data to a frame.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
@ AV_FRAME_DATA_MOTION_VECTORS
Motion vectors exported by some codecs (on demand through the export_mvs flag set in the libavcodec A...
#define AV_NOPTS_VALUE
Undefined timestamp value.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static const int8_t mv[256][2]
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FILTER_PIXFMTS_ARRAY(array)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
uint64_t ff_me_search_epzs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
void ff_me_init_context(AVMotionEstContext *me_ctx, int mb_size, int search_param, int width, int height, int x_min, int x_max, int y_min, int y_max)
uint64_t ff_me_search_umh(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
#define AV_ME_METHOD_NTSS
#define AV_ME_METHOD_HEXBS
#define AV_ME_METHOD_EPZS
#define AV_ME_METHOD_ESA
Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
#define AV_ME_METHOD_TDLS
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Describe the class of an AVClass context structure.
void * priv
private data for use by the filter
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
AVMotionEstPredictor preds[2]
int pred_y
median predictor y
int pred_x
median predictor x
Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
int search_param
search parameter
int(*[3] mv_table)[2][2]
motion vectors of current & prev 2 frames
AVMotionEstContext me_ctx
int mb_size
macroblock size
int method
motion estimation method
#define SEARCH_MV(method)
static const AVOption mestimate_options[]
#define ADD_PRED(preds, px, py)
static const AVFilterPad mestimate_inputs[]
static int config_input(AVFilterLink *inlink)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
static void add_mv_data(AVMotionVector *mv, int mb_size, int x, int y, int x_mv, int y_mv, int dir)
static int request_frame(AVFilterLink *outlink)
#define CONST(name, help, val, u)
static const AVFilterPad mestimate_outputs[]
static av_cold void uninit(AVFilterContext *ctx)