使用外部數據創建DirectFB Surface

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 &
發佈了41 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章