4 * Copyright (C) Georg Martius - June 2007
5 * georg dot martius at web dot de
6 * mlt adaption by Marco Gittler marco at gitma dot de 2011
8 * This file is part of transcode, a video stream processing tool
10 * transcode is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
15 * transcode is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with GNU Make; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 * transcode -V -J stabilize=shakiness=5:show=1,preview
28 * -i inp.mpeg -y null,null -o dummy
29 * all parameters are optional
32 #define MOD_NAME "filter_stabilize.so"
33 #define MOD_VERSION "v0.75 (2010-04-07)"
34 #define MOD_CAP "extracts relative transformations of \n\
35 subsequent frames (used for stabilization together with the\n\
36 transform filter in a second pass)"
37 #define MOD_AUTHOR "Georg Martius"
40 - Try OpenCL/Cuda, this should work great
41 - use smoothing on the frames and then use gradient decent!
42 - stepsize could be adapted (maybe to check only one field with large
43 stepsize and use the maximally required for the other fields
46 #define MOD_FEATURES \
47 TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO
49 TC_MODULE_FLAG_RECONFIGURABLE | TC_MODULE_FLAG_DELAY
50 #define MAX(a,b) ((a < b) ? (b) : (a))
51 #define MIN(a,b) ((a < b) ? (a) : (b))
52 #include "stabilize.h"
55 #include <framework/mlt_types.h>
56 #include <framework/mlt_log.h>
58 #include <emmintrin.h>
61 void addTrans(StabData* sd, Transform sl)
64 sd->transs = tlist_new(0);
66 tlist_append(sd->transs, &sl,sizeof(Transform) );
71 /** initialise measurement fields on the frame.
72 The size of the fields and the maxshift is used to
73 calculate an optimal distribution in the frame.
75 int initFields(StabData* sd)
77 int size = sd->field_size;
78 int rows = MAX(3,(sd->height - sd->maxshift*2)/size-1);
79 int cols = MAX(3,(sd->width - sd->maxshift*2)/size-1);
80 // make sure that the remaining rows have the same length
81 sd->field_num = rows*cols;
82 sd->field_rows = rows;
83 mlt_log_debug (NULL,"field setup: rows: %i cols: %i Total: %i fields",
84 rows, cols, sd->field_num);
86 if (!(sd->fields = malloc(sizeof(Field) * sd->field_num))) {
87 mlt_log_error ( NULL, "malloc failed!\n");
91 // the border is the amount by which the field centers
92 // have to be away from the image boundary
93 // (stepsize is added in case shift is increased through stepsize)
94 int border = size/2 + sd->maxshift + sd->stepsize;
95 int step_x = (sd->width - 2*border)/MAX(cols-1,1);
96 int step_y = (sd->height - 2*border) / MAX(rows-1,1);
97 for (j = 0; j < rows; j++) {
98 for (i = 0; i < cols; i++) {
100 sd->fields[idx].x = border + i*step_x;
101 sd->fields[idx].y = border + j*step_y;
102 sd->fields[idx].size = size;
111 compares the two given images and returns the average absolute difference
112 \param d_x shift in x direction
113 \param d_y shift in y direction
115 double compareImg(unsigned char* I1, unsigned char* I2,
116 int width, int height, int bytesPerPixel, int d_x, int d_y)
119 unsigned char* p1 = NULL;
120 unsigned char* p2 = NULL;
122 int effectWidth = width - abs(d_x);
123 int effectHeight = height - abs(d_y);
125 /* DEBUGGING code to export single frames */
126 /* char buffer[100]; */
127 /* sprintf(buffer, "pic_%02ix%02i_1.ppm", d_x, d_y); */
128 /* FILE *pic1 = fopen(buffer, "w"); */
129 /* sprintf(buffer, "pic_%02ix%02i_2.ppm", d_x, d_y); */
130 /* FILE *pic2 = fopen(buffer, "w"); */
131 /* fprintf(pic1, "P6\n%i %i\n255\n", effectWidth, effectHeight); */
132 /* fprintf(pic2, "P6\n%i %i\n255\n", effectWidth, effectHeight); */
134 for (i = 0; i < effectHeight; i++) {
138 p1 += (i + d_y) * width * bytesPerPixel;
139 p2 += i * width * bytesPerPixel;
141 p1 += i * width * bytesPerPixel;
142 p2 += (i - d_y) * width * bytesPerPixel;
145 p1 += d_x * bytesPerPixel;
147 p2 -= d_x * bytesPerPixel;
151 for (j = 0; j < effectWidth * bytesPerPixel - 16; j++) {
153 for (j = 0; j < effectWidth * bytesPerPixel; j++) {
155 /* fwrite(p1,1,1,pic1);fwrite(p1,1,1,pic1);fwrite(p1,1,1,pic1);
156 fwrite(p2,1,1,pic2);fwrite(p2,1,1,pic2);fwrite(p2,1,1,pic2);
159 A= _mm_loadu_si128((__m128i*)p1); //load unaligned data
160 B= _mm_loadu_si128((__m128i*)p2);
161 C= _mm_sad_epu8(A, B);//diff per 8 bit pixel stored in 2 64 byte values
162 D = _mm_srli_si128(C, 8); // shift first 64 byte value to align at the same as C
163 E = _mm_add_epi32(C, D); // add the 2 values (sum of all diffs)
164 sum+= _mm_cvtsi128_si32(E); //convert _m128i to int
170 sum += abs((int)*p1 - (int)*p2);
179 return sum/((double) effectWidth * effectHeight * bytesPerPixel);
183 compares a small part of two given images
184 and returns the average absolute difference.
185 Field center, size and shift have to be choosen,
186 so that no clipping is required
188 \param field Field specifies position(center) and size of subimage
189 \param d_x shift in x direction
190 \param d_y shift in y direction
192 double compareSubImg(unsigned char* const I1, unsigned char* const I2,
194 int width, int height, int bytesPerPixel, int d_x, int d_y)
197 unsigned char* p1 = NULL;
198 unsigned char* p2 = NULL;
199 int s2 = field->size / 2;
202 p1=I1 + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel;
204 p2=I2 + ((field->x - s2 + d_x) + (field->y - s2 + d_y)*width)*bytesPerPixel;
205 // TODO: use some mmx or sse stuff here
209 for (j = 0; j < field->size; j++){
211 for (k = 0; k < (field->size * bytesPerPixel) - 16 ; k++) {
212 A= _mm_loadu_si128((__m128i*)p1); //load unaligned data
213 B= _mm_loadu_si128((__m128i*)p2);
214 C= _mm_sad_epu8(A, B);//abd diff stored in 2 64 byte values
215 D = _mm_srli_si128(C, 8); // shift value 8 byte right
216 E = _mm_add_epi32(C, D); // add the 2 values (sum of all diffs)
217 sum+= _mm_cvtsi128_si32(E); //convert _m128i to int
223 for (k = 0; k < (field->size * bytesPerPixel); k++) {
224 sum += abs((int)*p1 - (int)*p2);
229 p1 += ((width - field->size) * bytesPerPixel);
230 p2 += ((width - field->size) * bytesPerPixel);
232 return sum/((double) field->size *field->size* bytesPerPixel);
235 /** \see contrastSubImg called with bytesPerPixel=1*/
236 double contrastSubImgYUV(StabData* sd, const Field* field){
237 return contrastSubImg(sd->curr,field,sd->width,sd->height,1);
241 \see contrastSubImg three times called with bytesPerPixel=3
244 double contrastSubImgRGB(StabData* sd, const Field* field){
245 unsigned char* const I = sd->curr;
246 return ( contrastSubImg(I, field,sd->width,sd->height,3)
247 + contrastSubImg(I+1,field,sd->width,sd->height,3)
248 + contrastSubImg(I+2,field,sd->width,sd->height,3))/3;
252 calculates Michelson-contrast in the given small part of the given image
254 \param I pointer to framebuffer
255 \param field Field specifies position(center) and size of subimage
256 \param width width of frame
257 \param height height of frame
258 \param bytesPerPixel calc contrast for only for first channel
260 double contrastSubImg(unsigned char* const I, const Field* field,
261 int width, int height, int bytesPerPixel)
265 int s2 = field->size / 2;
266 __m128i mini = _mm_set_epi64(_mm_set1_pi8(255), _mm_set1_pi8(255));
267 __m128i maxi = _mm_set_epi64(_mm_set1_pi8(0) , _mm_set1_pi8(0));
268 unsigned char* p = I + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel;
270 for (j = 0; j < field->size; j++){
271 for (k = 0; k < (field->size * bytesPerPixel)-16 ; k++) {
272 A= _mm_loadu_si128((__m128i*)p); //load unaligned data
274 maxi = _mm_max_epu8(A,maxi);
275 mini = _mm_min_epu8(A,mini);
279 p += (width - field->size) * bytesPerPixel;
297 //printf("max=%d min=%d\n", max,min);
298 return (max-min)/(max+min+0.1); // +0.1 to avoid division by 0
302 unsigned char* p = NULL;
303 int s2 = field->size / 2;
304 unsigned char mini = 255;
305 unsigned char maxi = 0;
306 p = I + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel;
307 // TODO: use some mmx or sse stuff here
309 for (j = 0; j < field->size; j++){
310 for (k = 0; k < field->size * bytesPerPixel; k++) {
311 mini = (mini < *p) ? mini : *p;
312 maxi = (maxi > *p) ? maxi : *p;
315 p += (width - field->size) * bytesPerPixel;
317 return (maxi-mini)/(maxi+mini+0.1); // +0.1 to avoid division by 0
321 /** tries to register current frame onto previous frame.
322 This is the most simple algorithm:
323 shift images to all possible positions and calc summed error
324 Shift with minimal error is selected.
326 Transform calcShiftRGBSimple(StabData* sd)
330 double minerror = 1e20;
331 for (i = -sd->maxshift; i <= sd->maxshift; i++) {
332 for (j = -sd->maxshift; j <= sd->maxshift; j++) {
333 double error = compareImg(sd->curr, sd->prev,
334 sd->width, sd->height, 3, i, j);
335 if (error < minerror) {
342 return new_transform(x, y, 0, 0, 0);
346 /** tries to register current frame onto previous frame.
347 (only the luminance is used)
348 This is the most simple algorithm:
349 shift images to all possible positions and calc summed error
350 Shift with minimal error is selected.
352 Transform calcShiftYUVSimple(StabData* sd)
356 unsigned char *Y_c, *Y_p;// , *Cb, *Cr;
360 tc_snprintf(buffer, sizeof(buffer), "f%04i.dat", sd->t);
361 f = fopen(buffer, "w");
362 fprintf(f, "# splot \"%s\"\n", buffer);
365 // we only use the luminance part of the image
367 // Cb_c = sd->curr + sd->width*sd->height;
368 //Cr_c = sd->curr + 5*sd->width*sd->height/4;
370 //Cb_p = sd->prev + sd->width*sd->height;
371 //Cr_p = sd->prev + 5*sd->width*sd->height/4;
373 double minerror = 1e20;
374 for (i = -sd->maxshift; i <= sd->maxshift; i++) {
375 for (j = -sd->maxshift; j <= sd->maxshift; j++) {
376 double error = compareImg(Y_c, Y_p,
377 sd->width, sd->height, 1, i, j);
379 fprintf(f, "%i %i %f\n", i, j, error);
381 if (error < minerror) {
390 tc_log_msg(MOD_NAME, "Minerror: %f\n", minerror);
392 return new_transform(x, y, 0, 0, 0);
397 /* calculates rotation angle for the given transform and
398 * field with respect to the given center-point
400 double calcAngle(StabData* sd, Field* field, Transform* t,
401 int center_x, int center_y)
403 // we better ignore fields that are to close to the rotation center
404 if (abs(field->x - center_x) + abs(field->y - center_y) < sd->maxshift) {
407 // double r = sqrt(field->x*field->x + field->y*field->y);
408 double a1 = atan2(field->y - center_y, field->x - center_x);
409 double a2 = atan2(field->y - center_y + t->y,
410 field->x - center_x + t->x);
411 double diff = a2 - a1;
412 return (diff>M_PI) ? diff - 2*M_PI
413 : ( (diff<-M_PI) ? diff + 2*M_PI : diff);
418 /* calculates the optimal transformation for one field in YUV frames
421 Transform calcFieldTransYUV(StabData* sd, const Field* field, int fieldnum)
423 Transform t = null_transform();
424 unsigned char *Y_c = sd->curr, *Y_p = sd->prev;
425 // we only use the luminance part of the image
428 /* // check contrast in sub image */
429 /* double contr = contrastSubImg(Y_c, field, sd->width, sd->height, 1); */
430 /* if(contr < sd->contrast_threshold) { */
435 // printf("%i %i %f\n", sd->t, fieldnum, contr);
438 snprintf(buffer, sizeof(buffer), "f%04i_%02i.dat", sd->t, fieldnum);
439 f = fopen(buffer, "w");
440 fprintf(f, "# splot \"%s\"\n", buffer);
443 double minerror = 1e10;
445 for (i = -sd->maxshift; i <= sd->maxshift; i += sd->stepsize) {
446 for (j = -sd->maxshift; j <= sd->maxshift; j += sd->stepsize) {
447 error = compareSubImg(Y_c, Y_p, field,
448 sd->width, sd->height, 1, i, j);
450 fprintf(f, "%i %i %f\n", i, j, error);
452 if (error < minerror) {
460 if (sd->stepsize > 1) { // make fine grain check around the best match
461 int r = sd->stepsize - 1;
462 for (i = t.x - r; i <= t.x + r; i += 1) {
463 for (j = -t.y - r; j <= t.y + r; j += 1) {
464 if (i == t.x && j == t.y)
465 continue; //no need to check this since already done
466 error = compareSubImg(Y_c, Y_p, field,
467 sd->width, sd->height, 1, i, j);
469 fprintf(f, "%i %i %f\n", i, j, error);
471 if (error < minerror){
481 mlt_log_debug ( "Minerror: %f\n", minerror);
484 if (!sd->allowmax && fabs(t.x) == sd->maxshift) {
486 mlt_log_debug ( "maximal x shift ");
490 if (!sd->allowmax && fabs(t.y) == sd->maxshift) {
492 mlt_log_debug ("maximal y shift ");
499 /* calculates the optimal transformation for one field in RGB
500 * slower than the YUV version because it uses all three color channels
502 Transform calcFieldTransRGB(StabData* sd, const Field* field, int fieldnum)
504 Transform t = null_transform();
505 unsigned char *I_c = sd->curr, *I_p = sd->prev;
508 double minerror = 1e20;
509 for (i = -sd->maxshift; i <= sd->maxshift; i += 2) {
510 for (j=-sd->maxshift; j <= sd->maxshift; j += 2) {
511 double error = compareSubImg(I_c, I_p, field,
512 sd->width, sd->height, 3, i, j);
513 if (error < minerror) {
520 for (i = t.x - 1; i <= t.x + 1; i += 2) {
521 for (j = -t.y - 1; j <= t.y + 1; j += 2) {
522 double error = compareSubImg(I_c, I_p, field,
523 sd->width, sd->height, 3, i, j);
524 if (error < minerror) {
531 if (!sd->allowmax && fabs(t.x) == sd->maxshift) {
534 if (!sd->allowmax && fabs(t.y) == sd->maxshift) {
540 /* compares contrast_idx structures respect to the contrast
543 int cmp_contrast_idx(const void *ci1, const void* ci2)
545 double a = ((contrast_idx*)ci1)->contrast;
546 double b = ((contrast_idx*)ci2)->contrast;
547 return a < b ? 1 : ( a > b ? -1 : 0 );
550 /* select only the best 'maxfields' fields
551 first calc contrasts then select from each part of the
554 tlist* selectfields(StabData* sd, contrastSubImgFunc contrastfunc)
557 tlist* goodflds = tlist_new(0);
558 contrast_idx *ci = malloc(sizeof(contrast_idx) * sd->field_num);
560 // we split all fields into row+1 segments and take from each segment
562 int numsegms = (sd->field_rows+1);
563 int segmlen = sd->field_num/(sd->field_rows+1)+1;
564 // split the frame list into rows+1 segments
565 contrast_idx *ci_segms = malloc(sizeof(contrast_idx) * sd->field_num);
567 // calculate contrast for each field
568 for (i = 0; i < sd->field_num; i++) {
569 ci[i].contrast = contrastfunc(sd, &sd->fields[i]);
571 if(ci[i].contrast < sd->contrast_threshold) ci[i].contrast = 0;
572 // else printf("%i %lf\n", ci[i].index, ci[i].contrast);
575 memcpy(ci_segms, ci, sizeof(contrast_idx) * sd->field_num);
576 // get best fields from each segment
577 for(i=0; i<numsegms; i++){
578 int startindex = segmlen*i;
579 int endindex = segmlen*(i+1);
580 endindex = endindex > sd->field_num ? sd->field_num : endindex;
581 //printf("Segment: %i: %i-%i\n", i, startindex, endindex);
583 // sort within segment
584 qsort(ci_segms+startindex, endindex-startindex,
585 sizeof(contrast_idx), cmp_contrast_idx);
586 // take maxfields/numsegms
587 for(j=0; j<sd->maxfields/numsegms; j++){
588 if(startindex+j >= endindex) continue;
589 // printf("%i %lf\n", ci_segms[startindex+j].index,
590 // ci_segms[startindex+j].contrast);
591 if(ci_segms[startindex+j].contrast > 0){
592 tlist_append(goodflds, &ci[ci_segms[startindex+j].index],sizeof(contrast_idx));
593 // don't consider them in the later selection process
594 ci_segms[startindex+j].contrast=0;
598 // check whether enough fields are selected
599 // printf("Phase2: %i\n", tc_list_size(goodflds));
600 remaining = sd->maxfields - tlist_size(goodflds);
602 // take the remaining from the leftovers
603 qsort(ci_segms, sd->field_num,
604 sizeof(contrast_idx), cmp_contrast_idx);
605 for(j=0; j < remaining; j++){
606 if(ci_segms[j].contrast > 0){
607 tlist_append(goodflds, &ci_segms[j], sizeof(contrast_idx));
611 // printf("Ende: %i\n", tc_list_size(goodflds));
619 /* tries to register current frame onto previous frame.
621 * check all fields for vertical and horizontal transformation
622 * use minimal difference of all possible positions
623 * discards fields with low contrast
624 * select maxfields field according to their contrast
625 * calculate shift as cleaned mean of all remaining fields
626 * calculate rotation angle of each field in respect to center of fields
627 * after shift removal
628 * calculate rotation angle as cleaned mean of all angles
629 * compensate for possibly off-center rotation
631 Transform calcTransFields(StabData* sd, calcFieldTransFunc fieldfunc,
632 contrastSubImgFunc contrastfunc)
634 Transform* ts = malloc(sizeof(Transform) * sd->field_num);
635 Field** fs = malloc(sizeof(Field*) * sd->field_num);
636 double *angles = malloc(sizeof(double) * sd->field_num);
637 int i, index=0, num_trans;
642 tc_snprintf(buffer, sizeof(buffer), "k%04i.dat", sd->t);
643 f = fopen(buffer, "w");
644 fprintf(f, "# plot \"%s\" w l, \"\" every 2:1:0\n", buffer);
648 tlist* goodflds = selectfields(sd, contrastfunc);
650 // use all "good" fields and calculate optimal match to previous frame
652 while((f = (contrast_idx*)tlist_pop(goodflds,0) ) != 0){
654 t = fieldfunc(sd, &sd->fields[i], i); // e.g. calcFieldTransYUV
656 fprintf(f, "%i %i\n%f %f %i\n \n\n", sd->fields[i].x, sd->fields[i].y,
657 sd->fields[i].x + t.x, sd->fields[i].y + t.y, t.extra);
659 if (t.extra != -1){ // ignore if extra == -1 (unused at the moment)
661 fs[index] = sd->fields+i;
665 tlist_fini(goodflds);
667 t = null_transform();
668 num_trans = index; // amount of transforms we actually have
670 printf( "too low contrast! No field remains.\n"
671 "(no translations are detected in frame %i)", sd->t);
680 // calc center point of all remaining fields
681 for (i = 0; i < num_trans; i++) {
682 center_x += fs[i]->x;
683 center_y += fs[i]->y;
685 center_x /= num_trans;
686 center_y /= num_trans;
688 if (sd->show){ // draw fields and transforms into frame.
689 // this has to be done one after another to handle possible overlap
691 for (i = 0; i < num_trans; i++)
692 drawFieldScanArea(sd, fs[i], &ts[i]);
694 for (i = 0; i < num_trans; i++)
695 drawField(sd, fs[i], &ts[i]);
696 for (i = 0; i < num_trans; i++)
697 drawFieldTrans(sd, fs[i], &ts[i]);
699 /* median over all transforms
700 t= median_xy_transform(ts, sd->field_num);*/
702 t = cleanmean_xy_transform(ts, num_trans);
705 for (i = 0; i < num_trans; i++) {
706 ts[i] = sub_transforms(&ts[i], &t);
709 if (sd->field_num < 6) {
710 // the angle calculation is inaccurate for 5 and less fields
713 for (i = 0; i < num_trans; i++) {
714 angles[i] = calcAngle(sd, fs[i], &ts[i], center_x, center_y);
717 t.alpha = -cleanmean(angles, num_trans, &min, &max);
718 if(max-min>sd->maxanglevariation){
720 printf( "too large variation in angle(%f)\n",
725 // compensate for off-center rotation
726 double p_x = (center_x - sd->width/2);
727 double p_y = (center_y - sd->height/2);
728 t.x += (cos(t.alpha)-1)*p_x - sin(t.alpha)*p_y;
729 t.y += sin(t.alpha)*p_x + (cos(t.alpha)-1)*p_y;
740 /** draws the field scanning area */
741 void drawFieldScanArea(StabData* sd, const Field* field, const Transform* t)
743 if (sd->pixelformat != mlt_image_yuv420p) {
744 mlt_log_warning (NULL, "format not usable\n");
747 drawBox(sd->curr, sd->width, sd->height, 1, field->x, field->y,
748 field->size+2*sd->maxshift, field->size+2*sd->maxshift, 80);
751 /** draws the field */
752 void drawField(StabData* sd, const Field* field, const Transform* t)
754 if (sd->pixelformat != mlt_image_yuv420p){
755 mlt_log_warning (NULL, "format not usable\n");
758 drawBox(sd->curr, sd->width, sd->height, 1, field->x, field->y,
759 field->size, field->size, t->extra == -1 ? 100 : 40);
762 /** draws the transform data of this field */
763 void drawFieldTrans(StabData* sd, const Field* field, const Transform* t)
765 if (sd->pixelformat != mlt_image_yuv420p){
766 mlt_log_warning (NULL, "format not usable\n");
769 drawBox(sd->curr, sd->width, sd->height, 1,
770 field->x, field->y, 5, 5, 128); // draw center
771 drawBox(sd->curr, sd->width, sd->height, 1,
772 field->x + t->x, field->y + t->y, 8, 8, 250); // draw translation
776 * draws a box at the given position x,y (center) in the given color
777 (the same for all channels)
779 void drawBox(unsigned char* I, int width, int height, int bytesPerPixel,
780 int x, int y, int sizex, int sizey, unsigned char color){
782 unsigned char* p = NULL;
784 p = I + ((x - sizex/2) + (y - sizey/2)*width)*bytesPerPixel;
785 for (j = 0; j < sizey; j++){
786 for (k = 0; k < sizex * bytesPerPixel; k++) {
790 p += (width - sizex) * bytesPerPixel;
799 /*************************************************************************/
801 /* Module interface routines and data. */
803 /*************************************************************************/
806 * stabilize_configure: Configure this instance of the module. See
807 * tcmodule-data.h for function details.
809 int stabilize_configure(StabData* instance
810 /*const char *options,
812 /*TCModuleExtraData *xdata[]*/)
814 StabData *sd = instance;
815 /* sd->framesize = sd->vob->im_v_width * MAX_PLANES *
816 sizeof(char) * 2 * sd->vob->im_v_height * 2; */
817 /*TODO sd->framesize = sd->vob->im_v_size; */
818 sd->prev = calloc(1,sd->framesize);
819 sd->grayimage = calloc(1,sd->width*sd->height);
821 if (!sd->prev || !sd->grayimage) {
822 printf( "malloc failed");
826 sd->hasSeenOneFrame = 0;
829 sd->field_size = MIN(sd->width, sd->height)/12;
830 sd->maxanglevariation = 1;
832 sd->shakiness = MIN(10,MAX(1,sd->shakiness));
833 sd->accuracy = MAX(sd->shakiness,MIN(15,MAX(1,sd->accuracy)));
835 mlt_log_debug (NULL, "Image Stabilization Settings:\n");
836 mlt_log_debug (NULL, " shakiness = %d\n", sd->shakiness);
837 mlt_log_debug (NULL, " accuracy = %d\n", sd->accuracy);
838 mlt_log_debug (NULL, " stepsize = %d\n", sd->stepsize);
839 mlt_log_debug (NULL, " algo = %d\n", sd->algo);
840 mlt_log_debug (NULL, " mincontrast = %f\n", sd->contrast_threshold);
841 mlt_log_debug (NULL, " show = %d\n", sd->show);
845 mlt_log_info(NULL,"No SSE2 support enabled, this will slow down a lot\n");
847 // shift and size: shakiness 1: height/40; 10: height/4
848 sd->maxshift = MIN(sd->width, sd->height)*sd->shakiness/40;
849 sd->field_size = MIN(sd->width, sd->height)*sd->shakiness/40;
851 mlt_log_debug ( NULL, "Fieldsize: %i, Maximal translation: %i pixel\n",
852 sd->field_size, sd->maxshift);
854 // initialize measurement fields. field_num is set here.
855 if (!initFields(sd)) {
858 sd->maxfields = (sd->accuracy) * sd->field_num / 15;
859 mlt_log_debug ( NULL, "Number of used measurement fields: %i out of %i\n",
860 sd->maxfields, sd->field_num);
863 sd->currcopy = calloc(1,sd->framesize);
866 /* load unsharp filter to smooth the frames. This allows larger stepsize.*/
867 char unsharp_param[128];
868 int masksize = MIN(13,sd->stepsize*1.8); // only works up to 13.
869 sprintf(unsharp_param,"luma=-1:luma_matrix=%ix%i:pre=1",
876 * stabilize_filter_video: performs the analysis of subsequent frames
877 * See tcmodule-data.h for function details.
880 int stabilize_filter_video(StabData* instance,
881 unsigned char *frame,mlt_image_format pixelformat)
883 StabData *sd = instance;
884 sd->pixelformat=pixelformat;
885 int l=sd->width*sd->height;
886 unsigned char* tmpgray=sd->grayimage;
887 if (pixelformat == mlt_image_yuv422){
894 if(sd->show) { // save the buffer to restore at the end for prev
895 if (pixelformat == mlt_image_yuv420p){
896 memcpy(sd->currcopy, sd->grayimage, sd->framesize);
899 if (sd->hasSeenOneFrame) {
900 sd->curr = sd->grayimage;
901 if (pixelformat == mlt_image_rgb24) {
903 addTrans(sd, calcShiftRGBSimple(sd));
904 else if (sd->algo == 1)
905 addTrans(sd, calcTransFields(sd, calcFieldTransRGB,
907 } else if (pixelformat == mlt_image_yuv420p ) {
909 addTrans(sd, calcShiftYUVSimple(sd));
910 else if (sd->algo == 1)
911 addTrans(sd, calcTransFields(sd, calcFieldTransYUV,
913 } else if (pixelformat == mlt_image_yuv422 ) {
915 addTrans(sd, calcShiftYUVSimple(sd));
916 else if (sd->algo == 1)
917 addTrans(sd, calcTransFields(sd, calcFieldTransYUV,
920 mlt_log_warning (NULL,"unsupported Codec: %i\n",
925 sd->hasSeenOneFrame = 1;
926 addTrans(sd, null_transform());
929 if(!sd->show) { // copy current frame to prev for next frame comparison
930 memcpy(sd->prev, sd->grayimage, sd->framesize);
931 } else { // use the copy because we changed the original frame
932 memcpy(sd->prev, sd->currcopy, sd->framesize);
939 * stabilize_stop: Reset this instance of the module. See tcmodule-data.h
940 * for function details.
943 int stabilize_stop(StabData* instance)
945 StabData *sd = instance;