This is just a guess from seeing what AVPitcure struct contains.
void *ptr; int pitch; AVPicture dst; surface->GetSize( surface, &w, &h ); surface->Lock( surface, DSLF_WRITE, &ptr, &pitch ); dst.data[0] = ptr; dst.linesize[0] = pitch; // For I420/YV12 dst.data[1] = dst.data[0] + h * pitch; dst.data[2] = dst.data[1] + h/2 * pitch/2; dst.linesize[1] = dst.linesize[2] = pitch/2; avpicture_deinterlace( &dst, src, fmt, w, h ); surface->Unlock( surface );
Obviosly you need to get "src" and "fmt" from somewhere. "surface" can be your output surface if you don't need to perform any other oprations on the data.
My "problem" now is, that I've no idea how to copy an AVPicture back to the framebuffer...
By the way, I don't really know if it's a good idea but, as I haven't really figured out how to read data from /dev/video0 with ffmpeg's functions, I thought it could work like that:
DirectFB-Videoprovider(reads from /dev/video0) -> "BufferSurface" -> "convert" the data from "BufferSurface" to an AVPicture -> deinterlace this AVPicture -> Blit the deinterlaced AVPicture onto the screen-Surface
For this scenario you simply lock the source surface with DSLF_READ and fill another AVPicture struct with the results.
Thanks for your answer!
I somehow tried to hack something useful together, but sadly I didn't manage to get a working code... :'-(
I just thought, that it would be best to simply post the code, maybe you could have a look at it? :)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <math.h> #include <string.h> #include <directfb.h> #include <ffmpeg/avcodec.h>
#define VIDEO_DEVICE "/dev/video0"
#define VIDEO_LAYER 0
#define SCREEN_WIDTH 720
#define SCREEN_HEIGHT 576
#define DFBCHECK(x...) \
{ \
err = x; \
if (err != DFB_OK) { \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
int err;
static AVCodec *av_codec;
static AVCodecContext *av_context;
static AVPicture av_input;
static AVPicture av_output;
static IDirectFB *dfb;
static IDirectFBInputDevice *df_keyboard;
static IDirectFBDisplayLayer *df_layer;
static IDirectFBVideoProvider *df_provider;
static IDirectFBSurface *df_screen;
static IDirectFBSurface *df_input;
static IDirectFBSurface *df_output;
static DFBDisplayLayerConfig df_dlc;
static DFBSurfaceDescription df_dsc;
static DFBRectangle df_screen_rect;
void InitAVCodec(void);
void InitDFB(int *argc, char **argv[]);
void CleanUpDFB(void);
void CleanUpAVCodec();
int BlitData(void);
int ReadData(void);
int WriteData(void);
int Deinterlace(void);
int main(int argc, char *argv[])
{
InitAVCodec();
InitDFB(&argc, &argv);
DFBCHECK( dfb->CreateVideoProvider(dfb, VIDEO_DEVICE, &df_provider) );
DFBCHECK( df_provider->PlayTo(df_provider, df_input, NULL, NULL, NULL) );
DFBInputDeviceKeyState quit = DIKS_UP;
while(quit == DIKS_UP) {
df_keyboard->GetKeyState(df_keyboard, DIKI_ESCAPE, &quit);
ReadData();
Deinterlace();
WriteData();
BlitData();
}
CleanUpAVCodec();
CleanUpDFB();
return 0;
}
void InitAVCodec()
{
avcodec_init();
avcodec_register_all();
av_codec = avcodec_find_decoder(CODEC_ID_RAWVIDEO);
if (NULL == av_codec) {
printf("codec not found\n");
exit(0);
}
av_context = avcodec_alloc_context();
if (NULL == av_context) {
printf("cannot allocate codec context\n");
exit(0);
}
if (avcodec_open(av_context, av_codec) < 0) {
printf("could not open codec\n");
exit(0);
}
}
void InitDFB(int *argc, char **argv[])
{
DFBCHECK( DirectFBInit(argc, argv) );
DFBCHECK( DirectFBCreate(&dfb) );
DFBCHECK( dfb->GetInputDevice(dfb, DIDID_KEYBOARD, &df_keyboard) );
DFBCHECK( dfb->GetDisplayLayer(dfb, VIDEO_LAYER, &df_layer) );
DFBCHECK( df_layer->SetCooperativeLevel(df_layer, DLSCL_EXCLUSIVE) );
df_screen_rect.x = 0;
df_screen_rect.y = 0;
df_screen_rect.w = SCREEN_WIDTH;
df_screen_rect.h = SCREEN_HEIGHT;
DFBCHECK( df_layer->GetConfiguration(df_layer, &df_dlc) );
df_dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_OPTIONS | DLCONF_BUFFERMODE;
df_dlc.width = df_screen_rect.w;
df_dlc.height = df_screen_rect.h;
//df_dlc.pixelformat = DSPF_RGB16;
//df_dlc.buffermode = DLBM_BACKVIDEO;
//df_dlc.options = DLOP_DEINTERLACING;
DFBCHECK( df_layer->SetConfiguration(df_layer, &df_dlc) );
DFBCHECK( df_layer->GetSurface(df_layer, &df_screen) );
df_dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT |
DSDESC_PIXELFORMAT;
df_dsc.width = df_screen_rect.w;
df_dsc.height = df_screen_rect.h;
df_dsc.pixelformat = df_dlc.pixelformat;
//df_dsc.caps = DSCAPS_PRIMARY | DSCAPS_INTERLACED;
DFBCHECK( dfb->CreateSurface(dfb, &df_dsc, &df_input) );
DFBCHECK( dfb->CreateSurface(dfb, &df_dsc, &df_output) );
}
void CleanUpDFB()
{
df_provider->Release(df_provider);
df_output->Release(df_output);
df_input->Release(df_input);
df_screen->Release(df_screen);
df_layer->Release(df_layer);
dfb->Release(dfb);
}
void CleanUpAVCodec()
{
avcodec_close(av_context);
free(av_codec);
}
int ReadData()
{
int pitch, i, w, h;
void *dst;
df_input->Flip(df_input, NULL, DSFLIP_ONSYNC);
df_input->GetSize(df_input, &w, &h);
df_input->Lock(df_input, DSLF_READ, &dst, &pitch);
av_input.data[0] = dst;
av_input.linesize[0] = pitch;
av_input.data[1] = av_input.data[0] + h * pitch;
av_input.data[2] = av_input.data[1] + h/2 * pitch/2;
av_input.linesize[1] = pitch/2;
av_input.linesize[2] = pitch/2;
df_input->Unlock(df_input);
return 0;
}
int Deinterlace()
{
avpicture_deinterlace(&av_output, &av_input, PIX_FMT_RGB24,
df_screen_rect.w, df_screen_rect.h);
return 0;
}
int WriteData()
{
int pitch, i, w, h;
void *dst;
df_output->GetSize(df_output, &w, &h);
df_output->Lock(df_output, DSLF_WRITE, &dst, &pitch);
for (i = 0; i < 576; i++)
memcpy(dst + i * pitch, av_output.data[0] + i * av_output.linesize[0],
pitch);
dst += pitch * 576;
for (i = 0; i < 576 / 2; i++)
memcpy(dst + i * (pitch / 2), av_output.data[2] + i *
av_output.linesize[2], pitch / 2);
dst += (pitch / 2) * (576 / 2);
for (i = 0; i < 576 / 2; i++)
memcpy(dst + i * (pitch / 2), av_output.data[1] + i *
av_output.linesize[1], pitch / 2);
df_output->Unlock(df_output);
return 0;
}
int BlitData()
{
df_screen->SetBlittingFlags(df_screen, DSBLIT_NOFX);
df_screen->Blit(df_screen, df_output, NULL, 0, 0);
return 0;
}
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ directfb-dev mailing list [email protected] http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev
