[MEncoder-users] Re: field order mysteriously changing

Scott W. Larson scowl at pacifier.com
Wed Mar 15 06:46:01 CET 2006


Dieter wrote:

>I was hoping the top_field_first flag would be useful for automagically
>correcting field order, so I tried watching it in ffmpeg, converting
>mpeg2ts to dv:
>
>In libavcodec/mpeg12.c mpeg_decode_picture_coding_extension()
>I turned on the printf for top_field_first.  Some files have
>top_field_first all 0, some have it all 1, and some have
>*interesting* changes, like being 1 for awhile, then changing
>to an alternating pattern, with 1, 2 and 3 samples:
>
>top field first=1
>:
>top field first=0
>top field first=0
>top field first=0
>
>I have trouble believing that the field order is supposed to be
>changing this frequently.
>
>  
>
I came across this while adding hardware deinterlacing to the XvMC code. 
I don't recall seeing the flag change that often during 1080i ATSC 
programs. The field order would be correct for maybe an hour, then it 
would switch creating the ugliness of displaying fields in the wrong order.

To fix this I had to add a couple of lines to XVMC_field_start() in 
libavcodec/xvmcvideo.c to mark that the frame was interlaced and which 
order the fields were in:

    if (!s->progressive_frame)  render->display_flags |= INTERLACED;
    if (s->top_field_first) render->display_flags |= TOP_FIELD_FIRST;

Then I added some logic to put_xvmc_image()  in  libvo/vo_xvmc.c to have 
two XvMCPutSurface() calls to display the two fields in the right order 
if the INTERLACED flag was set:

    if (p_render_surface->display_flags & TOP_FIELD_FIRST) {
                first_field = XVMC_TOP_FIELD;
                second_field = XVMC_BOTTOM_FIELD;
    } else {
                first_field = XVMC_BOTTOM_FIELD;
                second_field = XVMC_TOP_FIELD;
    }
                                                                                                                        

    rez = XvMCPutSurface(mDisplay, p_render_surface_to_show->p_surface,
      vo_window, 0, 0, image_width, image_height,
      clipX, clipY, clipW, clipH, first_field);
                                                                                                                        

    rez = XvMCPutSurface(mDisplay, p_render_surface_to_show->p_surface,
       vo_window, 0, 0, image_width, image_height,
       clipX, clipY, clipW, clipH, second_field | XVMC_SECOND_FIELD);

And somehow that will give you some kind of deinterlacing (at the proper 
field rate) if your hardware supports it.




More information about the MEncoder-users mailing list