Hi,

Thanks for your reply, and for looking into my problem. I'm afraid that I
still can't get things to work :-(

I'm trying to get this going with the softmpeg plugin for VDR. As you
guessed, I want to have an alpha blended OSD on top of the video. Video is
currently playing back fine using the video overlay, and I'm trying to get
the OSD code in softmpeg to work.

(I notice that the only way to get windows to display is to remove the call
to dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN). When I do this the
application starts up with a pointer and a light blue background.
Previously, the video window did not show through this, but it appears to be
doing so now! Strange.

(When you say that AiRGB is not accelerated - is this only blitting
window->Primary surface, or does it mean that primary surface/video window
blending is done in software as opposed to hardware?)

The code I'm using is as follows:

I create the video surface and draw two rectangles onto it:


static void initializeDFB(int argc, char *argv[])
{
  DFBResult err;
  DFBSurfaceDescription dsc;

  DFBCHECK(DirectFBInit( &argc, &argv ));

  /* create the super interface */
  DFBCHECK(DirectFBCreate( &dfb ));

#if 0 // remove for windows to display.
  /* set our cooperative level to DFSCL_FULLSCREEN
     for exclusive access to the primary layer */
  err = dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );
  if (err)
    DirectFBError( "Failed to get exclusive access", err );
#endif

  err = dfb->GetDisplayLayer(dfb,DLID_PRIMARY , &primarylayer);
  if (err)
    DirectFBErrorFatal( "Could not find primary layer", err );

  DFBCHECK(primarylayer->SetCooperativeLevel(primarylayer,
DLSCL_ADMINISTRATIVE));
}

 ...and the video layer.
static void init_video_layer(int width, int height)
{
    DFBResult err;
    DFBDisplayLayerConfig dlc;
    DFBDisplayLayerConfigFlags failed;
    DFBSurfaceDescription dsc;

    dlc.flags       = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_BUFFERMODE;
    dlc.width       = width;
    dlc.height      = height;
    dlc.buffermode  = DLBM_FRONTONLY;
    dlc.pixelformat = DSPF_YV12;

    err = dfb->GetDisplayLayer(dfb, 1, &videolayer);
    if (err)
        DirectFBErrorFatal( "Could not find video layer", err );


    err = videolayer->SetCooperativeLevel( videolayer, DLSCL_EXCLUSIVE );
    if (err)
        DirectFBError( "Failed to get exclusive access to video layer",
err );

    videolayer->SetOpacity(videolayer,0xff);

    /* Test the configuration, getting failed fields */
    err = videolayer->TestConfiguration( videolayer, &dlc, &failed );
    if (err)
        DirectFBErrorFatal("Stream format not supported by overlay", err);

    err = videolayer->SetConfiguration( videolayer, &dlc );
    if (err)
        DirectFBErrorFatal( "videolayer->SetConfiguration failed", err );

    /* Make video layer full screen. */
    videolayer->SetScreenLocation(videolayer, 0.0, 0.0, 1.0, 1.0);

    /* Get video surface. */
    err = videolayer->GetSurface( videolayer, &videosurface );
    if (err)
        DirectFBErrorFatal( "videolayer->GetSurface failed", err );


    printf("Drawing green+blue rectangles on the video surface...\n");

    DFBCHECK(videosurface->SetColor(videosurface,0x00,0xff,0x00,0xff));
    DFBCHECK(videosurface->FillRectangle(videosurface,00,00,600,500));
    DFBCHECK(videosurface->SetColor(videosurface,0x00,0x00,0xff,0xff));
    DFBCHECK(videosurface->FillRectangle(videosurface,150,150,300,200));


   // cpaton. Fiddle with video layer..

   DFBCHECK(videolayer->SetLevel(videolayer,1));
}

I then draw two rectangles on to the primary surface, one solid, and one
alpha blended. It seems that an alpha channel of 0xff makes the full video
window show through, and 0x00 makes the primary colour solid. This seems to
occur regardless of whether I set the line 'dsc.pixelformat = DSPF_AiRGB or
DSPF_RGB'

void drawPrimaryRectangles(void)
{
DFBResult err;
DFBSurfaceDescription dsc;

/* Get primary surface. */
dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
dsc.caps = DSCAPS_PRIMARY;
dsc.pixelformat = DSPF_ARGB;
DFBCHECK(dfb->CreateSurface( dfb, &dsc, &primary ));
primary->Clear(primary, 0, 0, 0, 0xff);

printf("Drawing a red rectangle on the primary layer...\n");
DFBCHECK (primary->SetColor (primary, 0xff, 0x00, 0x00, 0xff));
DFBCHECK (primary->FillRectangle (primary,20, 20, 400, 300));

DFBCHECK (primary->SetColor (primary, 0xff, 0x00, 0x00, 0x3f));
DFBCHECK (primary->FillRectangle (primary,50, 50, 320, 240));

DFBCHECK (primary->Flip (primary, NULL, 0));
}

This all works so far...but it all goes wrong when I try to create a Window:

void create_window_colin(void)
{
  DFBResult err;
  DFBWindowDescription windowdesc;
  IDirectFBWindow *osd;
  IDirectFBSurface* surface;

  windowdesc.flags = (DFBWindowDescriptionFlags)(DWDESC_HEIGHT |
DWDESC_WIDTH | DWDESC_POSX | DWDESC_POSY | DSDESC_PIXELFORMAT |
DWDESC_CAPS);

  windowdesc.height = 300;
  windowdesc.width = 400;
  windowdesc.posx = 100;
  windowdesc.posy = 200;
  windowdesc.pixelformat = DSPF_AiRGB;
  windowdesc.caps = DWCAPS_ALPHACHANNEL;

  DFBCHECK(primarylayer->CreateWindow(primarylayer, &windowdesc, &osd));
  osd->SetOptions(osd, DWOP_NONE); // New test suggested by dok
  osd->SetOpacity(osd, 0xff); // ff -> show window.
   DFBCHECK(osd->GetSurface(osd, &surface));

  DFBCHECK(surface->SetColor(surface,0x00,0x00,0xff,0x7f));
  DFBCHECK(surface->FillRectangle(surface,00,00,200,200));
   DFBCHECK(surface->Flip(surface, 0, 0));

  osd->RaiseToTop(osd);

  printf("The window should be displayed...\n");

}

In order to get the window to display at all, I have to remove the call to
SetCooperativeLevel(DFSCL_FULLSCREEN).
The window now displays.

Changing osd->SetOpacity() changes the colour of the whole window. 0xff is
full window, down to 0x00 is no window (video shows)

However, there is no per-pixel blending - the red of the rectangle in the
window is solid red, whereas I hoped that the green and blue from the video
window beneath it would change. Again, DSPF_AiRGB or DSPF_RGB seem to make
no difference.

If I remove the create window calls, and just have a video window with the
alpha blended primary red rectangles, but the the call to
SetCooperativeLevel(DFSCL_FULLSCREEN) removed then I don't think alpha
blending works, but I'm not quite sure. When this happens I get the green
background of the video window, but a black window in the centre, and light
blue and dark blue rectangles where the red rectangles were previously.

I'm wondering if the problem is something to do with the SetCooperativeLevel
call.

What is worrying me is that, of course, tonight, video does appear to show
through with the SetCooperativeLevel call removed, whereas at the weekend it
didn't - just got the default blue background. To be fair, I'm not using
exactly the same configuration - using my monitor and vesafb/cle266vgaio at
the moment, wheras before I used viafb and the TV output.

If I set the window format to be DSPF_RGB32 I get a segmentation fault, the
backtrace being
Flipping_Thread()->dfb_window_repaint()->wind_of_change()->wind_of_change()-
>update_region()->update_region()->update->region()->draw_background()->dfb_
gfxcard_fillrectangle()->dfb_gfxcard_state_check().

It doesn't segfault if I remove DWDESC_CAPS, so I guess that flag only works
with an ARGB/AiRGB surface.

I also notice that a grep for AiRGB in gfxdrivers/cle266 shows nothing, but
this might be a red herring.

If any DirectFB experts could spot my mistake I would be highly
appreciative!

Thanks a lot,

Colin





-- 
Info:  To unsubscribe send a mail to [EMAIL PROTECTED] with 
"unsubscribe directfb-dev" as subject.

Reply via email to