Hello,

I improved the DirectFB output driver :
- added support for hardware blitting (if the videocard supports this)
- improved format handling : I420 -> YV12 and I420 -> I420 are now perfectly
supported. The output driver looks for a video layer that supports I420, when
it doesn't find it, it falls back to YV12 with software format conversion.
- improved I420->YV12 software conversion, supporting different pitches (this
was a bug, see http://www.gossamer-threads.com/perl/mailarc/gforum.cgi?
post=113868) - in fact, DirectFB should handle this conversion, but it is not
yet implemented :-(
- improved buffering : all buffers are now DirectFB surfaces with the
appropriate width, height and format - maybe this buffering should turn into a
real DirectFBVideoProvider some day...
- implemented aspect change, remind to set the FRAMEBUFFER environment variable
when your framebuffer device is different from /dev/fb0. I need to access the
framebuffer directly in order to determine the screen width and height.
Hopefully DirectFB will offer some method to do determine this...

Still to do :
- support for zoom
- support for osd : it would be nice to render the osd as a seperate surface
and let DirectFB combine them using alpha blending : you would get a nice
transparant osd display :-)
- look at those pause and scratch frames

Some questions :
- When I look at the format of the vbuffers that I receive, they seem to be
I420. However, I explicitely set vbuffers[i].codec = FMT_YV12 ? Can the input
format change ?
- Can someone take a look at the cleanup for my data struct ? I'm getting a
warning from DirectFB that a few bytes are not freed. (You can see this when
you compiled DirectFB with debug and tracing options) Don't worry : the video
buffers are properly closed !
- Is it necessary to have 31 buffers ? This was taken from the xv output...
- I think I read somewhere that there is a DirectFB port of QT Embedded, it
would be nice to run this for the ui stuff :-)

I include patches against the latest cvs versions.

Kind regards,

Kristof
15a16,21
> #include <linux/fb.h>
> #include <sys/ioctl.h>
> #include <fcntl.h>
> #include <unistd.h>
> 
> 
243a250,251
>       int screen_width;
>       int screen_height;
259c267
<       ClearSurface();
---
>       ClearSurface(data->surface);
303,306c311,331
<     VideoOutput::InitBuffers(kNumBuffers, true, kNeedFreeFrames,
<                              kPrebufferFrames, kKeepPrebuffer);
<     VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh,
<                       embedid);
---
>       //determine screen size
>       char *fb_dev_name = NULL;
>       int fb_dev_fd;
>       struct fb_var_screeninfo fb_vinfo;
> 
>       if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
>                       fb_dev_name = strdup("/dev/fb0");
> 
>       if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {
>         DirectFBError("Couldn't open framebuffer", ret);
>       }
>       if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
>         DirectFBError("Couldn't get screeninfo", ret);
>       }
>       close(fb_dev_fd);
>       fb_dev_fd = -1;
>                       
> 
>       data->screen_width = (int)fb_vinfo.xres;
>       data->screen_height = (int)fb_vinfo.yres;
> 
315c340
<     
---
>       
383,387d407
<       ClearSurface();
< 
<       //display output layer
<     DFBCHECK(data->layer->SetOpacity(data->layer, 0xff));
< 
388a409,410
>     VideoOutput::InitBuffers(kNumBuffers, true, kNeedFreeFrames,
>                              kPrebufferFrames, kKeepPrebuffer);
392c414
<     //desc.pixelformat = DSPF_YV12;
---
>       //can this change ?
447a470,478
>     VideoOutput::Init(width, height, aspect, winid, winx, winy, data->screen_width, 
> data->screen_height,
>                       embedid);
>       
>       VERBOSE(VB_GENERAL, QString("DirectFB output : screen size 
> %1x%2").arg(data->screen_width).arg(data->screen_height));
>       MoveResize();
> 
>       //display output layer
>     DFBCHECK(data->layer->SetOpacity(data->layer, 0xff));
> 
452,453c483
< // clear the surface
< void VideoOutputDirectfb::ClearSurface()
---
> float VideoOutputDirectfb::GetDisplayAspect(void)
455,462c485
<       if (data->surface)
<       {
<               for(int i=0; i<3; i++)
<               {
<                       DFBCHECK(data->surface->Clear(data->surface, 0x00, 0x00, 0x00, 
0xff));
<                       DFBCHECK(data->surface->Flip(data->surface, NULL, 
DSFLIP_ONSYNC));
<               }
<       }
---
>       return (float)data->screen_width/(float)data->screen_height;
465d487
< 
555,556c577,601
<     //**FIXME - should do something here
<     cerr << "DrawUnusedRects()" << endl;
---
> /* DirectFB only draws what is needed :-)
>       VERBOSE(VB_GENERAL, QString("drawUnusedRects : screen size %1x%2, proposed x : 
> %3, y : %4, w : %5, h : %6")
>                                                               
> .arg(data->screen_width)
>                                                               
> .arg(data->screen_height)
>                                                               .arg(dispxoff)
>                                                               .arg(dispyoff)
>                                                               .arg(dispwoff)
>                                                               .arg(disphoff));
>     // Draw black in masked areas
>     if (dispxoff > dispx) // left
>               DFBCHECK (data->surface->FillRectangle (data->surface, 
>                        dispx, dispy, dispxoff-dispx, disph));
>     if (dispxoff+dispwoff < dispx+dispw) // right
>               DFBCHECK (data->surface->FillRectangle (data->surface, 
>                        dispxoff+dispwoff, dispy, 
>                        (dispx+dispw)-(dispxoff+dispwoff), disph));
>     if (dispyoff > dispy) // bottom
>               DFBCHECK (data->surface->FillRectangle (data->surface, 
>                        dispx, dispy, dispw, dispyoff-dispy));
>     if (dispyoff+disphoff < dispy+disph) // top
>               DFBCHECK (data->surface->FillRectangle (data->surface, 
>                        dispx, dispyoff+disphoff, 
>                        dispw, (dispy+disph)-(dispyoff+disphoff)));
> //    DFBCHECK (data->surface->Flip (data->surface, NULL, 0));
> */
594d638
<     //**FIXME - MoveResize()??
598a643
>       MoveResize();
614,615c659,660
<     //**FIXME - -do something here
<     cerr << "AspectChanged()" << endl;
---
>     VideoOutput::AspectChanged(aspect);
>     MoveResize();
623a669,689
> void VideoOutputDirectfb::MoveResize(void)
> {
>     VideoOutput::MoveResize();
> 
>       VERBOSE(VB_GENERAL, QString("DirectFB MoveResize : screen size %1x%2, proposed 
> x : %3, y : %4, w : %5, h : %6")
>                                                               
> .arg(data->screen_width)
>                                                               
> .arg(data->screen_height)
>                                                               .arg(dispxoff)
>                                                               .arg(dispyoff)
>                                                               .arg(dispwoff)
>                                                               .arg(disphoff));
>       //**FIXME support for zooming when dispwoff > screenwidth || disphoff > 
> screenheight
>       DFBCHECK(data->layer->SetScreenLocation(data->layer,
>                                                                                      
>  (float)dispxoff/(float)data->screen_width,
>                                                                                      
>  (float)dispyoff/(float)data->screen_height,
>                                                                                      
>  (float)dispwoff/(float)data->screen_width,
>                                                                                      
>  (float)disphoff/(float)data->screen_height));
> }
>       
> 
> 
640c706
<               //TO DO: set the three following parameters correctly
---
>               //**FIXME set the three following parameters correctly
664d729
< 
669a735
>       IDirectFBSurface *surface;
672a739,742
>       //clear every surface we discover
>       DFBCHECK(vodata->layer->GetSurface(vodata->layer, &surface));
>       ClearSurface(surface);
> 
28c28
<     void AspectChanged(float aspect);
---
>       void AspectChanged(float aspect);
30a31,33
>       float GetDisplayAspect(void);
>       void VideoOutputDirectfb::MoveResize();
> 
57d59
<     void ClearSurface(void);
81c83,94
< 
---
> static inline void ClearSurface(IDirectFBSurface *surface)
> {
>     if (surface)
>     {
>         for(int i=0; i<3; i++)
>         {
>             //DFBCHECK(surface->FillRectangle(surface, 0, 0, data->screen_width, 
> data->screen_height));
>             surface->Clear(surface, 0x00, 0x00, 0x00, 0xff);
>             surface->Flip(surface, NULL, DSFLIP_ONSYNC);
>         }
>     }
> }

Reply via email to