Re: [Mlt-devel] Affine compositing bug
Brought to you by:
ddennedy,
lilo_booter
From: Dan D. <da...@de...> - 2012-04-11 04:58:35
|
While I have not reproduced it and thereby confirmed this patch, please try it nonetheless. On Tue, Apr 10, 2012 at 8:42 PM, Dan Dennedy <da...@de...> wrote: > On Mon, Apr 9, 2012 at 6:36 AM, j-b-m <j-...@us...> wrote: >> Hi, >> >> Following a bug reported on Kdenlive's forum, I get a strange result when >> requesting mlt_image_rgb24a images from an affine transition. There seems to >> be a problem with the alpha compositing. > > I am trying to reproduce this with the following but not succeeding. > Can you suggest something so I can confirm fixes? > > melt color:blue -track +HELLO.txt -transition affine rotate_x=1 \ > -consumer sdl mlt_image_format=rgb24a > > mlt_image_format property sets the image format used by the > render-ahead in mlt_consumer. > >> You can see the problem here: >> >> http://kdenlive.org/images/affine2.png >> >> The correct result should be: >> >> http://kdenlive.org/images/affine1.png >> >> For some reason, this problem only appears when requesting rgb24a, so it does >> not appear in Kdenlive's SDL monitor. >> >> After some tests, it seems to me that the problem is in the interp routines >> used by the affine transition. >> >> I did some tests with the interpNN_b32 function which is used by default, and >> it seems to me that there is something not correct, since the alpha channel of >> the top layer is copied to the alpha layer of the bottom layer. >> >> Here is the code: >> >> int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, float o, >> unsigned char *v) >> { >> #ifdef TEST_XY_LIMITS >> if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1; >> #endif >> v[3] = sl[(int)rintf(x)*4+(int)rintf(y)*4*w+3]; <--- HERE WE COPY ALPHA >> FROM TOP LAYER >> float alpha = (float) v[3] / 255.0 * o; >> v[0]= v[0] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w] * alpha; >> v[1]= v[1] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+1] * >> alpha; >> v[2]= v[2] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+2] * >> alpha; >> >> return 0; >> } >> >> >> With this patch, the problem disappears: >> >> diff --git a/src/modules/plus/interp.h b/src/modules/plus/interp.h >> index 39e626d..23b447b 100644 >> --- a/src/modules/plus/interp.h >> +++ b/src/modules/plus/interp.h >> @@ -165,8 +165,8 @@ int interpNN_b32(unsigned char *sl, int w, int h, float x, >> float y, float o, uns >> #ifdef TEST_XY_LIMITS >> if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1; >> #endif >> - v[3]= sl[(int)rintf(x)*4+(int)rintf(y)*4*w+3]; >> - float alpha = (float) v[3] / 255.0 * o; >> + float overlayAlpha = sl[(int)rintf(x)*4+(int)rintf(y)*4*w+3]; >> + float alpha = (float) overlayAlpha / 255.0 * o; >> v[0]= v[0] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w] * >> alpha; >> v[1]= v[1] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+1] * >> alpha; >> v[2]= v[2] * (1.0 - alpha) + sl[(int)rintf(x)*4+(int)rintf(y)*4*w+2] * >> alpha; >> >> >> (As a side note, it also seems to me that we should not calculate 4 times >> (int)rintf(x)*4+(int)rintf(y)*4*w, saving it to an int would seem more >> efficient). >> >> Maybe I am completely wrong and the problem is in my QImage conversion of the >> frame, but I would be glad to have your opinion on the subject... >> >> Also, other interpolation methods seem to be affected by the same problem. >> >> >> Thanks, >> >> jb >> |