Hello, I'm trying to play a video (from an IP camera) using the DirectFB
library.
Currently I have found several tearing issues.
I've attached a small program that displays a randomly generated color
bars.
The effect is the same that I see using, instead of the bars, the frame
of the video.
---- start df_colobars.c ---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <directfb.h>
#define FONT "font.ttf"
#define BG_IMAGE "nocamera.png"
typedef struct{
IDirectFBFont *font;
int height;
} tFont;
unsigned long long frames = 0;
tFont fonts[5];
/* macro for a safe call to DirectFB functions */
#define DFBCHECK(x...) \
{ \
err = x; \
if (err != DFB_OK) { \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
void draw_colorbars(IDirectFBSurface* surface){
int w,h;
int bar_w;
int i;
surface->GetSize(surface, &w,&h);
bar_w = w / 10;
surface->Clear(surface, 0x00, 0x00, 0x00, 0xFF);
for(i=0; i<10; i++){
surface->SetColor(surface, rand()%256, rand()%256, rand()%256, rand()%
256);
surface->FillRectangle(surface, bar_w*i,0, bar_w, h);
}
surface->DrawString(surface,
"COLORBARS MODE",
-1, w / 2, h / 2,
(DFBSurfaceTextFlags)(DSTF_CENTER));
surface->Flip(surface, NULL, (DFBSurfaceFlipFlags) 0 );
}
int main(int argc, char *argv[])
{
IDirectFB *dfb;
IDirectFBDisplayLayer *layer;
IDirectFBSurface *bgsurface;
IDirectFBWindow *osd_window;
IDirectFBSurface *osd_surface;
IDirectFBWindow *video_window;
IDirectFBSurface *video_surface;
IDirectFBSurface *frame_surface;
IDirectFBEventBuffer *buffer;
DFBDisplayLayerConfig layer_config;
DFBGraphicsDeviceDescription gdesc;
DFBResult err;
int quit = 0;
int i;
DFBRectangle rect;
bool colorbars = true;
int camera_w = 1280;
int camera_h = 800;
DFBCHECK(DirectFBInit(&argc, &argv));
DFBCHECK(DirectFBCreate(&dfb));
dfb->GetDeviceDescription(dfb, &gdesc);
DFBCHECK(dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer));
layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
if (!((gdesc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL) &&
(gdesc.blitting_flags & DSBLIT_BLEND_COLORALPHA))) {
layer_config.flags = (DFBDisplayLayerConfigFlags)( DLCONF_SURFACE_CAPS
| DLCONF_BUFFERMODE );
layer_config.buffermode = DLBM_BACKSYSTEM;
layer_config.surface_caps = (DFBSurfaceCapabilities) ( DSCAPS_PRIMARY
| DSCAPS_DOUBLE | DSCAPS_TRIPLE);
layer->SetConfiguration(layer, &layer_config);
}
layer->GetConfiguration(layer, &layer_config);
layer->EnableCursor(layer, 0);
{
DFBFontDescription desc;
desc.flags = DFDESC_HEIGHT;
desc.height = 10;
DFBCHECK(dfb->CreateFont(dfb, FONT, &desc, &fonts[0].font));
fonts[0].font->GetHeight(fonts[0].font, &fonts[0].height);
desc.height = 20;
DFBCHECK(dfb->CreateFont(dfb, FONT, &desc, &fonts[1].font));
fonts[1].font->GetHeight(fonts[1].font, &fonts[1].height);
desc.height = 30;
DFBCHECK(dfb->CreateFont(dfb, FONT, &desc, &fonts[2].font));
fonts[2].font->GetHeight(fonts[2].font, &fonts[2].height);
desc.height = 40;
DFBCHECK(dfb->CreateFont(dfb, FONT, &desc, &fonts[3].font));
fonts[3].font->GetHeight(fonts[3].font, &fonts[3].height);
desc.height = 50;
DFBCHECK(dfb->CreateFont(dfb, FONT, &desc, &fonts[4].font));
fonts[4].font->GetHeight(fonts[4].font, &fonts[4].height);
}
{
DFBSurfaceDescription desc;
desc.flags =
(DFBSurfaceDescriptionFlags) (DSDESC_WIDTH | DSDESC_HEIGHT |
DSDESC_CAPS);
desc.width = layer_config.width;
desc.height = layer_config.height;
desc.caps = (DFBSurfaceCapabilities) ( DSCAPS_NONE );
DFBCHECK(dfb->CreateSurface(dfb, &desc, &bgsurface));
layer->SetBackgroundColor(layer, 0x00, 0x00, 0x00, 0xFF);
layer->SetBackgroundMode(layer, DLBM_COLOR);
}
{
DFBSurfaceDescription sdsc;
DFBWindowDescription desc;
desc.flags =
(DFBWindowDescriptionFlags) (DWDESC_POSX | DWDESC_POSY |
DWDESC_WIDTH | DWDESC_HEIGHT |
DWDESC_CAPS);
desc.caps = DWCAPS_ALPHACHANNEL;
sdsc.width = 600;
sdsc.height = 500;
desc.posx = (layer_config.width - sdsc.width) / 2;
desc.posy = (layer_config.height - sdsc.height) / 2;
desc.width = sdsc.width;
desc.height = sdsc.height;
DFBCHECK(layer->CreateWindow(layer, &desc, &osd_window));
osd_window->GetSurface(osd_window, &osd_surface);
osd_window->SetOpacity(osd_window, 0xFF);
osd_window->CreateEventBuffer(osd_window, &buffer);
osd_surface->Clear(osd_surface, 0x00, 0x00, 0x00, 0x00);
DFBCHECK(osd_surface->SetFont(osd_surface, fonts[1].font));
osd_surface->Flip(osd_surface, NULL, (DFBSurfaceFlipFlags) 0);
}
{
DFBSurfaceDescription desc;
desc.flags = (DFBSurfaceDescriptionFlags) (DSDESC_WIDTH |
DSDESC_HEIGHT | DSDESC_CAPS);
desc.height = camera_h;
desc.width = camera_w;
desc.caps = (DFBSurfaceCapabilities) ( DSCAPS_DOUBLE | DSCAPS_TRIPLE
);
DFBCHECK(dfb->CreateSurface(dfb, &desc, &frame_surface));
DFBCHECK(frame_surface->SetFont(frame_surface, fonts[4].font));
}
{
DFBWindowDescription desc;
desc.flags = (DFBWindowDescriptionFlags) (DWDESC_POSX | DWDESC_POSY |
DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_SURFACE_CAPS | DWDESC_CAPS);
desc.caps = DWCAPS_ALPHACHANNEL;
desc.surface_caps = (DFBSurfaceCapabilities) (DSCAPS_PRIMARY |
DSCAPS_TRIPLE | DSCAPS_DOUBLE);
desc.height = layer_config.height;
desc.width = layer_config.width;
desc.posx = 0;
desc.posy = 0;
DFBCHECK(layer->CreateWindow(layer, &desc, &video_window));
video_window->GetSurface(video_window, &video_surface);
video_window->SetOpacity(video_window, 0xFF);
video_window->AttachEventBuffer(video_window, buffer);
video_surface->Clear(video_surface, 0xFF, 0xFF, 0xFF, 0xFF);
DFBCHECK(video_surface->SetFont(video_surface, fonts[4].font));
video_surface->SetColor(video_surface, 0xFF, 0xFF, 0xFF, 0xFF);
video_surface->Flip(video_surface, NULL, (DFBSurfaceFlipFlags) 0);
}
osd_surface->SetColor(osd_surface, 0xFF, 0xFF, 0xFF, 0xFF);
video_window->RequestFocus(video_window);
video_window->RaiseToTop(video_window);
rect.x = 0;
rect.y = 0;
rect.w = camera_w;
rect.h = camera_h;
while (!quit) {
DFBWindowEvent evt;
frames++;
if(colorbars){
draw_colorbars(frame_surface);
video_surface->Blit(video_surface, frame_surface, &rect,0,0);
video_surface->Flip(video_surface, NULL, (DFBSurfaceFlipFlags)
DSFLIP_WAITFORSYNC);
}
buffer->WaitForEventWithTimeout(buffer, 0, 10);
while (buffer->GetEvent(buffer, DFB_EVENT(&evt)) == DFB_OK) {
switch (evt.type) {
case DWET_KEYDOWN:
switch (evt.key_symbol) {
case DIKS_ESCAPE:
case DIKS_SMALL_Q:
case DIKS_CAPITAL_Q:
case DIKS_BACK:
case DIKS_STOP:
quit = 1;
break;
case DIKS_SMALL_B:
case DIKS_CAPITAL_B:
colorbars = !colorbars;
break;
default:
break;
}
break;
}
}
}
buffer->Release(buffer);
for(i=0; i<5; i++)
fonts[i].font->Release(fonts[i].font);
osd_surface->Release(osd_surface);
osd_window->Release(osd_window);
frame_surface->Release(frame_surface);
video_surface->Release(video_surface);
video_window->Release(video_window);
layer->Release(layer);
bgsurface->Release(bgsurface);
dfb->Release(dfb);
return 1;
}
---- end df_colobars.c ---
---
gcc -D_REENTRANT -I/usr/include/directfb -D_GNU_SOURCE -Wall -O3 -pipe
-Werror-implicit-function-declaration -o df_colorbars df_colobars.c
-ldirectfb -lfusion -ldirect -lpthread -lm
---
Can anyone help me?
Thank you.