[FFmpeg-soc] [RFC] Frame rotation by 90 degree

Bobby Bingham uhmmmm at gmail.com
Mon Dec 3 16:38:23 CET 2007


On 3 Dec 2007 07:18:11 -0000
"Tilak Adhya" <tilakadhya at rediffmail.com> wrote:

>   
> Hi All,
> 
> I am new to this mailing list. My problem is to rotate a frame by 90,
> 180 and 270 degrees by adding/changing in FFMPEG code. For 180 degree
> rotation, I got the vf_vflip.c file under the libavfilter folder,
> which does the flipping, that means 180 degree rotation. But for 90

No. vf_vflip mirrors the image, which is not the same as a 180 degree
rotation.  In a rotation, the top-left corner would end up in the
bottom-right.  With vf_vflip, it ends up in the bottom-left.

This is a very special case and can be accomplished simply by changing
the pointer to the beginning of the frame data, and by negating the
linesize.  This does not generalize to other rotations, which will
require that you copy data around.

> and 270 degree rotation we need to add in the ffmpeg code base. For
> this purpose, I thought that vf_vflip.c would be the starting point
> to proceed. And I got that, the fliping part is done inside the
> start_frame() function of the vf_Vflip.c (am I wrong...?).

Yes, it is.  But that will not work for true rotation because the image
data is not available at that point.  You need to process it either in
draw_slice() (preferred) or in end_frame().

> 
> static void start_frame(AVFilterLink *link, AVFilterPicRef *picref)
> {
>     FlipContext *flip = link->dst->priv;
>     AVFilterPicRef *ref2 = avfilter_ref_pic(picref, ~0);
>     int i;
> 
>     ref2->data[0] += (ref2->h-1) * ref2->linesize[0];
>     ref2->linesize[0] = -ref2->linesize[0];
>     for(i = 1; i < 4; i ++) {
>         if(ref2->data[i]) {
>             ref2->data[i] += ((ref2->h >> flip->vsub)-1) *
> ref2->linesize[i]; ref2->linesize[i] = -ref2->linesize[i];
>         }
>     }
> 
>     avfilter_start_frame(link->dst->outputs[0], ref2);
> }
> 
> In the above code width becomes the negative of of the existing
> width, but what's the use of the two lines below ...
> 
> if(ref2->data[i]) {
>             ref2->data[i] += ((ref2->h >> flip->vsub)-1) *
> ref2->linesize[i]; ref2->linesize[i] = -ref2->linesize[i];
>         }
> 
> This algorithm is not clear to me.

This changes the pointer to the image data to point to the last row of
the original image.  This, along with the negated width causes the
image to be flipped.

> 
> So my understanding for implementing rotation, is to add code in the
> start_frame() function. I need to rotate the frame in Y,U and V plane
> separately. But I saw that linesize[1] and linesize[2] does not
> represent the width of the frame exactly and I am confused about the
> exact rotation algorithm. For rotation in the Y plane, according to
> my understanding the rotation algorithm will be as follows ---
> 
> void rotatePicture(AVFrame *fPicture, int w, int h, AVCodecContext
> *enc){ int i = 0, index, ai = 0, wi, hi ;
>   uint8_t *arr = av_malloc(w*h * sizeof(uint8_t));
>   uint8_t *arr1 = NULL;
>   uint8_t *arr2 = NULL;
>   memset(arr, 0, w*h*sizeof(uint8_t));
>  
>   // this is ONLY for the Y component
>   for(wi = 0; wi <= w-1; wi++){
>     for(hi = h - 1; hi >= 0; hi--){
>       //arr[ai++] = fPicture->data[0][hi*w + wi];
>       arr[ai++] = 0;
>     }
>   }

There are functions already available for allocating a new frame.  In
particular, if you are implementing this as a libavfilter, just make
sure your output dimensions are set right, and you can call
avfilter_get_video_buffer()

> 
> What do you think - is it correct... ? And then what will be for U
> and V plane...? 

I believe someone on ffmpeg-devel already answered this ...

> 
> Please suggest...
> 
> Thanks in Advance...
> 
> Thanks and Regards
> Tilak
> 
> 
> 
> 
> *--
> tilak


-- 
Bobby Bingham
Never trust atoms.  Or anything made of atoms.
このメールは再利用されたバイトでできている。



More information about the FFmpeg-soc mailing list