[mythtv] [directfb-dev] Improved MythTV DirectFB output
Kristof Pelckmans
kristof.pelckmans at antwerpen.be
Wed Mar 31 18:11:22 EST 2004
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
-------------- next part --------------
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);
>
-------------- next part --------------
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);
> }
> }
> }
More information about the mythtv-dev
mailing list