56 #include "libavutil/common.h"
57 #include "libavutil/mem.h"
58 #include "libavutil/opt.h"
59 #include "libavutil/pixdesc.h"
65 #define CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_desc_get(link->format)->log2_chroma_w)
66 #define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_desc_get(link->format)->log2_chroma_h)
68 #define OFFSET(x) offsetof(DeshakeContext, x)
69 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
97 static int cmp(
const double *
a,
const double *
b)
99 return *a < *b ? -1 : ( *a > *b ? 1 : 0 );
111 qsort(values, count,
sizeof(
double), (
void*)
cmp);
113 for (x = cut; x < count - cut; x++) {
117 return mean / (count - cut * 2);
132 int smallest = INT_MAX;
135 #define CMP(i, j) deshake->c.sad[0](deshake, src1 + cy * stride + cx, \
136 src2 + (j) * stride + (i), stride, \
141 for (y = -deshake->
ry; y <= deshake->ry; y++) {
142 for (x = -deshake->
rx; x <= deshake->rx; x++) {
143 diff =
CMP(cx - x, cy - y);
144 if (diff < smallest) {
153 for (y = -deshake->
ry + 1; y < deshake->ry; y += 2) {
154 for (x = -deshake->
rx + 1; x < deshake->rx; x += 2) {
155 diff =
CMP(cx - x, cy - y);
156 if (diff < smallest) {
168 for (y = tmp2 - 1; y <= tmp2 + 1; y++) {
169 for (x = tmp - 1; x <= tmp + 1; x++) {
170 if (x == tmp && y == tmp2)
173 diff =
CMP(cx - x, cy - y);
174 if (diff < smallest) {
183 if (smallest > 512) {
203 for (i = 0; i <= blocksize * 2; i++) {
205 for (j = 0; j <= 15; j++) {
206 pos = (y - i) * stride + (x - j);
207 if (src[pos] < lowest)
209 else if (src[pos] > highest) {
215 return highest - lowest;
225 a1 = atan2(y - cy, x - cx);
226 a2 = atan2(y - cy + shift->
y, x - cx + shift->
x);
230 return (diff >
M_PI) ? diff - 2 *
M_PI :
248 int count_max_value = 0;
252 double *angles =
av_malloc(
sizeof(*angles) * width * height / (16 * deshake->
blocksize));
253 int center_x = 0, center_y = 0;
257 for (x = 0; x < deshake->
rx * 2 + 1; x++) {
258 for (y = 0; y < deshake->
ry * 2 + 1; y++) {
265 for (y = deshake->
ry; y < height - deshake->ry - (deshake->
blocksize * 2); y += deshake->
blocksize * 2) {
267 for (x = deshake->
rx; x < width - deshake->rx - 16; x += 16) {
274 if (mv.
x != -1 && mv.
y != -1) {
275 counts[mv.
x + deshake->
rx][mv.
y + deshake->
ry] += 1;
276 if (x > deshake->
rx && y > deshake->
ry)
290 if (t->
angle < 0.001)
297 for (y = deshake->
ry * 2; y >= 0; y--) {
298 for (x = 0; x < deshake->
rx * 2 + 1; x++) {
300 if (counts[x][y] > count_max_value) {
303 count_max_value = counts[x][
y];
309 p_x = (center_x - width / 2);
310 p_y = (center_y - height / 2);
325 const float *matrix_y,
const float *matrix_uv,
330 const float *matrixs[3];
331 int plane_w[3], plane_h[3];
332 matrixs[0] = matrix_y;
333 matrixs[1] = matrixs[2] = matrix_uv;
335 plane_w[1] = plane_w[2] = cw;
337 plane_h[1] = plane_h[2] = ch;
339 for (i = 0; i < 3; i++) {
342 plane_w[i], plane_h[i], matrixs[i], interpolate, fill);
358 if (deshake->
rx % 16) {
366 fwrite(
"Ori x, Avg x, Fin x, Ori y, Avg y, Fin y, Ori angle, Avg angle, Fin angle, Ori zoom, Avg zoom, Fin zoom\n",
sizeof(
char), 104, deshake->
fp);
370 if (deshake->
cx > 0) {
371 deshake->
cw += deshake->
cx - (deshake->
cx & ~15);
376 av_log(ctx,
AV_LOG_ERROR,
"OpenCL support was not enabled in this build, cannot be selected\n");
386 av_log(ctx,
AV_LOG_VERBOSE,
"cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n",
387 deshake->
cx, deshake->
cy, deshake->
cw, deshake->
ch,
442 float matrix_y[9], matrix_uv[9];
460 if (deshake->
cx < 0 || deshake->
cy < 0 || deshake->
cw < 0 || deshake->
ch < 0) {
470 if ((
unsigned)deshake->
cx + (
unsigned)deshake->
cw > link->
w) deshake->
cw = link->
w - deshake->
cx;
471 if ((
unsigned)deshake->
cy + (
unsigned)deshake->
ch > link->
h) deshake->
ch = link->
h - deshake->
cy;
486 orig.angle = t.
angle;
509 snprintf(tmp, 256,
"%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", orig.vector.x, deshake->
avg.
vector.
x, t.
vector.
x, orig.vector.y, deshake->
avg.
vector.
y, t.
vector.
y, orig.angle, deshake->
avg.
angle, t.
angle, orig.zoom, deshake->
avg.
zoom, t.
zoom);
510 fwrite(tmp,
sizeof(
char), strlen(tmp), deshake->
fp);
579 .priv_class = &deshake_class,
#define AVERROR_PATCHWELCOME
static int shift(int a, int b)
This structure describes decoded (raw) audio or video data.
int ry
Maximum vertical shift.
const char * name
Filter name.
void * priv
private data for use by the filter
static const AVFilterPad outputs[]
int h
agreed upon image height
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVFilter avfilter_vf_deshake
void av_freep(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
const char * name
Pad name.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
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 double clean_mean(double *values, int count)
Cleaned mean (cuts off 20% of values to remove outliers and then averages)
static void interpolate(float *out, float v1, float v2, int size)
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
int blocksize
Size of blocks to compare.
#define AV_LOG_VERBOSE
Detailed information.
A filter pad used for either input or output.
A link between two filters.
int avcodec_close(AVCodecContext *avctx)
Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext its...
int refcount
Number of reference frames (defines averaging window)
int rx
Maximum horizontal shift.
int ff_opencl_transform(AVFilterContext *ctx, int width, int height, int cw, int ch, const float *matrix_y, const float *matrix_uv, enum InterpolateMethod interpolate, enum FillMethod fill, AVFrame *in, AVFrame *out)
static double alpha(void *priv, double x, double y)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);ff_audio_convert_init_arm(ac);ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
char * filename
Motion search detailed log filename.
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range ...
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
static int filter_frame(AVFilterLink *link, AVFrame *in)
double x
Horizontal shift.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static int query_formats(AVFilterContext *ctx)
static const AVFilterPad deshake_inputs[]
int contrast
Contrast threshold.
AVPixelFormat
Pixel format.
int w
agreed upon image width
static double block_angle(int x, int y, int cx, int cy, IntMotionVector *shift)
Find the rotation for a given block.
static int deshake_transform_c(AVFilterContext *ctx, int width, int height, int cw, int ch, const float *matrix_y, const float *matrix_uv, enum InterpolateMethod interpolate, enum FillMethod fill, AVFrame *in, AVFrame *out)
void * av_malloc(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
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...
int edge
Edge fill method.
int search
Motion search method.
DSPContext c
Context providing optimized SAD methods.
#define CHROMA_HEIGHT(link)
static const AVOption deshake_options[]
Main libavfilter public API header.
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_...
AVFilterLink ** outputs
array of pointers to output links
static const int8_t mv[256][2]
Search all possible positions.
int ff_opencl_deshake_process_inout_buf(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
static int block_contrast(uint8_t *src, int x, int y, int stride, int blocksize)
Find the contrast of a given block.
AVFrame * ref
Previous frame.
Search most possible positions (faster)
#define CHROMA_WIDTH(link)
BYTE int const BYTE int int int height
static int config_props(AVFilterLink *link)
static const AVFilterPad inputs[]
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
static av_cold int init(AVFilterContext *ctx)
int(* transform)(AVFilterContext *ctx, int width, int height, int cw, int ch, const float *matrix_y, const float *matrix_uv, enum InterpolateMethod interpolate, enum FillMethod fill, AVFrame *in, AVFrame *out)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
AVFilterContext * dst
dest filter
static int cmp(const double *a, const double *b)
int cw
Crop motion search to this box.
Transform last
Transform from last frame.
int ff_opencl_deshake_init(AVFilterContext *ctx)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);ff_audio_convert_init_arm(ac);ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
static const AVFilterPad deshake_outputs[]
#define AVFILTER_DEFINE_CLASS(fname)
av_cold void avpriv_dsputil_init(DSPContext *c, AVCodecContext *avctx)
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_...
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static av_cold void uninit(AVFilterContext *ctx)
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
void ff_opencl_deshake_uninit(AVFilterContext *ctx)