#include "avfilter.h"
#include "formats.h"
#include "video.h"
#include "libavutil/common.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "libavcodec/dsputil.h"
#include "transform.h"
Go to the source code of this file.
Data Structures | |
struct | IntMotionVector |
struct | MotionVector |
struct | Transform |
struct | DeshakeContext |
Defines | |
#define | CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w) |
#define | CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h) |
#define | CMP(i, j) |
Enumerations | |
enum | SearchMethod { EXHAUSTIVE, SMART_EXHAUSTIVE, SEARCH_COUNT } |
Functions | |
static int | cmp (const double *a, const double *b) |
static double | clean_mean (double *values, int count) |
Cleaned mean (cuts off 20% of values to remove outliers and then averages). | |
static void | find_block_motion (DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, int cx, int cy, int stride, IntMotionVector *mv) |
Find the most likely shift in motion between two frames for a given macroblock. | |
static int | block_contrast (uint8_t *src, int x, int y, int stride, int blocksize) |
Find the contrast of a given block. | |
static double | block_angle (int x, int y, int cx, int cy, IntMotionVector *shift) |
Find the rotation for a given block. | |
static void | find_motion (DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, int width, int height, int stride, Transform *t) |
Find the estimated global motion for a scene given the most likely shift for each block in the frame. | |
static av_cold int | init (AVFilterContext *ctx, const char *args) |
static int | query_formats (AVFilterContext *ctx) |
static int | config_props (AVFilterLink *link) |
static av_cold void | uninit (AVFilterContext *ctx) |
static int | end_frame (AVFilterLink *link) |
static int | draw_slice (AVFilterLink *link, int y, int h, int slice_dir) |
Variables | |
AVFilter | avfilter_vf_deshake |
SAD block-matching motion compensation to fix small changes in horizontal and/or vertical shift. This filter helps remove camera shake from hand-holding a camera, bumping a tripod, moving on a vehicle, etc.
Algorithm:
TODO:
Dark Shikari links to http://wiki.videolan.org/SoC_x264_2010#GPU_Motion_Estimation_2 for an algorithm similar to what could be used here to get the gmv It requires only a couple diamond searches + fast downscaling
Special thanks to Jason Kotenko for his help with the algorithm and my inability to see simple errors in C code.
Definition in file vf_deshake.c.
#define CHROMA_HEIGHT | ( | link | ) | -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h) |
#define CHROMA_WIDTH | ( | link | ) | -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w) |
#define CMP | ( | i, | |||
j | ) |
Value:
deshake->c.sad[0](deshake, src1 + cy * stride + cx, \ src2 + (j) * stride + (i), stride, \ deshake->blocksize)
Referenced by find_block_motion().
enum SearchMethod |
EXHAUSTIVE | Search all possible positions. |
SMART_EXHAUSTIVE | Search most possible positions (faster). |
SEARCH_COUNT |
Definition at line 65 of file vf_deshake.c.
static double block_angle | ( | int | x, | |
int | y, | |||
int | cx, | |||
int | cy, | |||
IntMotionVector * | shift | |||
) | [static] |
Find the rotation for a given block.
Definition at line 232 of file vf_deshake.c.
Referenced by find_motion().
Find the contrast of a given block.
When searching for global motion we really only care about the high contrast blocks, so using this method we can actually skip blocks we don't care much about.
Definition at line 208 of file vf_deshake.c.
Referenced by find_motion().
static double clean_mean | ( | double * | values, | |
int | count | |||
) | [static] |
Cleaned mean (cuts off 20% of values to remove outliers and then averages).
Definition at line 116 of file vf_deshake.c.
Referenced by find_motion().
static int cmp | ( | const double * | a, | |
const double * | b | |||
) | [static] |
Definition at line 108 of file vf_deshake.c.
static int config_props | ( | AVFilterLink * | link | ) | [static] |
Definition at line 400 of file vf_deshake.c.
static int draw_slice | ( | AVFilterLink * | link, | |
int | y, | |||
int | h, | |||
int | slice_dir | |||
) | [static] |
Definition at line 536 of file vf_deshake.c.
static int end_frame | ( | AVFilterLink * | link | ) | [static] |
Definition at line 428 of file vf_deshake.c.
static void find_block_motion | ( | DeshakeContext * | deshake, | |
uint8_t * | src1, | |||
uint8_t * | src2, | |||
int | cx, | |||
int | cy, | |||
int | stride, | |||
IntMotionVector * | mv | |||
) | [static] |
Find the most likely shift in motion between two frames for a given macroblock.
Test each block against several shifts given by the rx and ry attributes. Searches using a simple matrix of those shifts and chooses the most likely shift by the smallest difference in blocks.
Definition at line 137 of file vf_deshake.c.
Referenced by find_motion().
static void find_motion | ( | DeshakeContext * | deshake, | |
uint8_t * | src1, | |||
uint8_t * | src2, | |||
int | width, | |||
int | height, | |||
int | stride, | |||
Transform * | t | |||
) | [static] |
Find the estimated global motion for a scene given the most likely shift for each block in the frame.
The global motion is estimated to be the same as the motion from most blocks in the frame, so if most blocks move one pixel to the right and two pixels down, this would yield a motion vector (1, -2).
Definition at line 253 of file vf_deshake.c.
Referenced by end_frame().
static av_cold int init | ( | AVFilterContext * | ctx, | |
const char * | args | |||
) | [static] |
Definition at line 334 of file vf_deshake.c.
static int query_formats | ( | AVFilterContext * | ctx | ) | [static] |
Definition at line 387 of file vf_deshake.c.
static av_cold void uninit | ( | AVFilterContext * | ctx | ) | [static] |
Definition at line 416 of file vf_deshake.c.
Initial value:
{ .name = "deshake", .description = NULL_IF_CONFIG_SMALL("Stabilize shaky video."), .priv_size = sizeof(DeshakeContext), .init = init, .uninit = uninit, .query_formats = query_formats, .inputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .draw_slice = draw_slice, .end_frame = end_frame, .config_props = config_props, .min_perms = AV_PERM_READ | AV_PERM_PRESERVE, }, { .name = NULL}}, .outputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, }, { .name = NULL}}, }
Definition at line 541 of file vf_deshake.c.