使用外部数据创建DirectFB Surface

来源:互联网 发布:java utf8编码转换gbk 编辑:程序博客网 时间:2024/05/16 15:07

Video解码出来需要使用DirectFB进行Blending,由于解出来的frame已经分配了buffer,所以想直接使用frame的buffer就可以创建surface,这样可以减少一次buffer的操作。在DFBSurfaceDescription的flags的属性中有一个feature为DSDESC_PREALLOCATED正好可以实现这个功能。我首先把解码完成的frame直接保存到一个文件中,frame的格式为YV12,只要DirectFB支持的格式都可以例如很多hardware解出来的为NV12,在测试代码中把相应的数据读出来map到内存中,最后attach到一个surface上,下面是具体的实现。

 

================================code begin=========================================

#include <stdio.h>

#include <unistd.h>

 

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/mman.h>

#include <fcntl.h>

 

#include <directfb.h>

 

static IDirectFB *dfb = NULL;

static IDirectFBSurface *primary = NULL;

static int screen_width, screen_height;

 

static int img_width = 720;

static int img_height= 480;

 

#define DFBCHECK(x...)                                                   \ 

                {                                                        \

                DFBResult err = x;                                        \

                if (err != DFB_OK)                                        \

                {                                                         \       

                    fprintf( stderr, "%s<%d>:\n\t", __FILE__, __LINE__ );\

                    DirectFBErrorFatal( #x, err);                        \

                }                                                         \ 

                }

int main (int argc, char **argv){

 DFBSurfaceDescription dsc;

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

 DFBCHECK (DirectFBCreate (&dfb));

 DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));

 dsc.flags = DSDESC_CAPS; 

 dsc.caps  = DSCAPS_PRIMARY |DSCAPS_FLIPPING;

 DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));

 DFBCHECK (primary->GetSize( primary, &screen_width,&screen_height ));

 //fill screen with green

 DFBCHECK (primary->SetColor(primary,0,255,0,255));

 DFBCHECK(primary->FillRectangle(primary,0,0,screen_width,screen_height));

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

 sleep(2);

 //load data from file

  intfd;

 struct stat  stat;

 char * data;

  fd= open( "dump01.yuv", O_RDONLY );

  if(fd < 0) {

         perror( "open" );

         return 0;

  }

  if(fstat( fd, &stat ) < 0) {

     perror( "fstat" );

     close( fd );

     return 0;

  }

 //map the data to memory

 data = mmap( NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0 );

  if(data == MAP_FAILED) {

     perror( "mmap" );

     close( fd );

     return 0;

  }

 //Create a surface with your frame data

 IDirectFBSurface *frm_surface = NULL;

 DFBSurfaceDescription frm_dsc;

 DFBRectangle clipRect = {0,0,img_width,img_height};

 DFBRegion flipRegion = {0,0,img_width,img_height};

 frm_dsc.flags =DSDESC_CAPS|DSDESC_PREALLOCATED|DSDESC_PIXELFORMAT|DSDESC_WIDTH|DSDESC_HEIGHT; 

 frm_dsc.caps  =DSCAPS_SYSTEMONLY;//DSCAPS_NONE;

 frm_dsc.width = img_width;     //image width

 frm_dsc.height = img_height;   //image height

 frm_dsc.pixelformat = DSPF_YV12;     //video pixel format

 frm_dsc.preallocated[0].data = data;  //attach frame data

 frm_dsc.preallocated[0].pitch = 2048; //stride in your data

  frm_dsc.preallocated[1].data  = NULL;

 frm_dsc.preallocated[1].pitch = 0;

 

 DFBCHECK (dfb->CreateSurface( dfb, &frm_dsc, &frm_surface ));

 //draw to primary

 DFBCHECK (primary->SetBlittingFlags( primary, DSBLIT_NOFX ));

 DFBCHECK (primary->Blit(primary, frm_surface, &clipRect, 0, 0 ));

 DFBCHECK (primary->Flip(primary, &flipRegion, 0));

 //wait a moment

 sleep(2);

 //free something

 frm_surface->Release(frm_surface);

 primary->Release( primary );

 dfb->Release( dfb );

 close(fd);

 return 23;

}

 ================================code end=========================================


另外还有一个问题Ubuntu中如何enable DirectFB,在网上查找了一些资料,一般都是说更改menu.lst文件,但是在我的系统中没有找到相应的文件,后来在找到另外一个方法就是在相关用户的目录下创建.directfbrc文件,解决了运行的问题,具体如下:

Log in into your gnome or kde or whatevergraphical environment you use. Open up a terminal in there and type:

nano ~/.directfbrc

What we’re going to do now is change a fewdirectfb settings to run it under X11. (see man directfbrc for more settings)

Just plain copy and paste the followingsettings in that file:

mode=1024×768

pixelformat=RGB32

system=x11

You can change the resolution to yourliking if you want.

Now type (still in that same console that’srunning inside your graphical environment):

df_window & // runs it in thebackground

df_cpuload &
原创粉丝点击