void* BufferThread( DirectThread *self, void *arg ) { IDirectFBVideoProvider_Xine_data *data = arg; IDirectFBDataBuffer *buffer = data->buffer; int fd; fd = open( data->pipe, O_WRONLY ); if (fd < 0) { D_PERROR( "IDirectFBVideoProvider_Xine: " "failed to open fifo '%s'\n", data->pipe ); return (void*)1; } while (!direct_thread_is_canceled( self )) { DFBResult ret; char buf[4096]; unsigned int len = 0; buffer->WaitForDataWithTimeout( buffer, sizeof(buf), 0, 1 ); ret = buffer->GetData( buffer, sizeof(buf), buf, &len ); if (ret == DFB_OK && len) write( fd, buf, len ); if (ret == DFB_EOF) break; } close( fd ); return (void*)0; }
static DFBResult Construct( IDirectFBImageProvider *thiz, ... ) { DFBResult ret = DFB_FAILURE; IDirectFBDataBuffer *buffer; CoreDFB *core; va_list tag; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_MPEG2) va_start( tag, thiz ); buffer = va_arg( tag, IDirectFBDataBuffer * ); core = va_arg( tag, CoreDFB * ); va_end( tag ); data->base.ref = 1; data->base.buffer = buffer; data->core = core; /* Increase the data buffer reference counter. */ buffer->AddRef( buffer ); /* Initialize mpeg2 decoding. */ data->dec = MPEG2_Init( mpeg2_read_func, buffer, &data->width, &data->height ); if (!data->dec) goto error; data->stage = STAGE_INFO; /* Allocate image data. */ data->image = D_MALLOC( data->width * data->height * 4 ); if (!data->image) goto error; data->stage = STAGE_IMAGE; data->base.Destruct = IDirectFBImageProvider_MPEG2_Destruct; thiz->RenderTo = IDirectFBImageProvider_MPEG2_RenderTo; thiz->SetRenderCallback = IDirectFBImageProvider_MPEG2_SetRenderCallback; thiz->GetImageDescription = IDirectFBImageProvider_MPEG2_GetImageDescription; thiz->GetSurfaceDescription = IDirectFBImageProvider_MPEG2_GetSurfaceDescription; return DFB_OK; error: if (data->dec) MPEG2_Close(data->dec); buffer->Release( buffer ); DIRECT_DEALLOCATE_INTERFACE(thiz); return ret; }
static DFBResult Construct( IDirectFBImageProvider *thiz, ... ) { DFBResult ret; struct stat info; void *ptr; IDirectFBDataBuffer_data *buffer_data; IDirectFBDataBuffer *buffer; CoreDFB *core; va_list tag; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_ANDROID) va_start( tag, thiz ); buffer = va_arg( tag, IDirectFBDataBuffer * ); core = va_arg( tag, CoreDFB * ); va_end( tag ); D_MAGIC_ASSERT( (IAny*) buffer, DirectInterface ); buffer_data = buffer->priv; if (!buffer_data) { ret = DFB_DEAD; goto error; } if (buffer_data->filename) { data->path = D_STRDUP( buffer_data->filename ); if (stat( buffer_data->filename, &info ) < 0) { ret = errno2result( errno ); D_PERROR( "ImageProvider/ANDROID: Failure during fstat() of '%s'!\n", buffer_data->filename ); goto error; } } data->base.ref = 1; data->base.core = core; data->base.buffer = buffer; buffer->AddRef( buffer ); data->base.Destruct = IDirectFBImageProvider_ANDROID_Destruct; thiz->RenderTo = IDirectFBImageProvider_ANDROID_RenderTo; thiz->GetImageDescription = IDirectFBImageProvider_ANDROID_GetImageDescription; thiz->GetSurfaceDescription = IDirectFBImageProvider_ANDROID_GetSurfaceDescription; return DFB_OK; error: DIRECT_DEALLOCATE_INTERFACE(thiz); return ret; }
static DFBResult Construct( IDirectFBImageProvider *thiz, ... ) { IDirectFBDataBuffer *buffer; CoreDFB *core; va_list tag; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_GIF) va_start( tag, thiz ); buffer = va_arg( tag, IDirectFBDataBuffer * ); core = va_arg( tag, CoreDFB * ); va_end( tag ); data->base.ref = 1; data->base.buffer = buffer; data->base.core = core; buffer->AddRef( buffer ); data->GrayScale = -1; data->transparent = -1; data->delayTime = -1; data->image = ReadGIF( data, 1, &data->image_width, &data->image_height, &data->image_transparency, &data->image_colorkey, true, false ); buffer->Release( buffer ); data->base.buffer = NULL; if (!data->image || (data->image_height == 0) || (data->image_width == 0) ) { DIRECT_DEALLOCATE_INTERFACE( thiz ); return DFB_FAILURE; } data->base.Destruct = IDirectFBImageProvider_GIF_Destruct; thiz->RenderTo = IDirectFBImageProvider_GIF_RenderTo; thiz->GetImageDescription = IDirectFBImageProvider_GIF_GetImageDescription; thiz->GetSurfaceDescription = IDirectFBImageProvider_GIF_GetSurfaceDescription; return DFB_OK; }
static DFBResult readBufferStream( IDirectFBImageProvider_ANDROID_data *data, char **bufferData, int *bufferSize ) { IDirectFBDataBuffer *buffer = data->base.buffer; int total_size = 0; const int bufsize = 0x10000; char *buf = NULL; DFBResult ret; int len; char *rbuf; while (1) { rbuf = realloc( buf, total_size + bufsize ); if (!rbuf) { free( buf ); return DFB_NOSYSTEMMEMORY; } buf = rbuf; while (buffer->HasData( buffer ) == DFB_OK) { D_DEBUG_AT( imageProviderANDROID, "Retrieving data (up to %d )...\n", bufsize ); ret = buffer->GetData( buffer, bufsize, &buf[total_size], &len ); if (ret) return ret; D_DEBUG_AT( imageProviderANDROID, " -> got %d bytes\n", len ); total_size += len; } D_DEBUG_AT( imageProviderANDROID, "Waiting for data...\n" ); if (buffer->WaitForData( buffer, 1 ) == DFB_EOF) { *bufferData = buf; *bufferSize = total_size; return DFB_OK; } } free( buf ); return DFB_INCOMPLETE; }
DFBResult ICore_Real::CreateImageProvider( u32 buffer_call, u32 *ret_call ) { DFBResult ret; IDirectFBDataBuffer *buffer; IDirectFBImageProvider *provider; ImageProviderDispatch *dispatch; D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Real::%s()\n", __FUNCTION__ ); D_MAGIC_ASSERT( obj, CoreDFB ); D_ASSERT( ret_call != NULL ); DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBDataBuffer ); if (!buffer) return (DFBResult) D_OOM(); /* Construct data buffer client */ ret = IDirectFBDataBuffer_Client_Construct( buffer, core, buffer_call ); if (ret) return ret; /* Create image provider */ ret = buffer->CreateImageProvider( buffer, &provider ); if (ret) { buffer->Release( buffer ); return ret; } /* Create dispatch object */ ret = ImageProviderDispatch_Create( idirectfb_singleton, buffer, provider, &dispatch ); if (ret) { provider->Release( provider ); buffer->Release( buffer ); return ret; } *ret_call = dispatch->call.call_id; return DFB_OK; }
static DFBResult WebP_decode_image( IDirectFBImageProvider_WebP_data *data, CoreSurfaceBufferLock *lock ) { VP8StatusCode status = VP8_STATUS_NOT_ENOUGH_DATA; DFBResult ret; uint32_t read_size; u8 image[data->image_size]; WebPIDecoder* WebP_dec; IDirectFBDataBuffer *buffer = data->base.buffer; WebP_dec = WebPINewDecoder( &data->config.output ); data->config.output.colorspace = (data->pixelformat == DSPF_ARGB) ? MODE_bgrA : MODE_BGR; data->config.output.u.RGBA.rgba = (uint8_t*)lock->addr; data->config.output.u.RGBA.stride = lock->pitch; data->config.output.u.RGBA.size = lock->pitch * data->height; data->config.output.is_external_memory = 1; ret = DFB_OK; while (ret != DFB_EOF && buffer->HasData( buffer ) == DFB_OK) { ret = buffer->GetData( buffer, data->image_size, image, &read_size ); status = WebPIAppend( WebP_dec, image, read_size ); if (!(status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED)) break; } WebPIDelete( WebP_dec ); return (status == VP8_STATUS_OK) ? DFB_OK : DFB_FAILURE; }
static DFBResult Construct( IDirectFBImageProvider *thiz, ... ) { DFBResult ret = DFB_FAILURE; IDirectFBDataBuffer *buffer; CoreDFB *core; va_list tag; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_PNG) va_start( tag, thiz ); buffer = va_arg( tag, IDirectFBDataBuffer * ); core = va_arg( tag, CoreDFB * ); va_end( tag ); data->ref = 1; data->buffer = buffer; data->core = core; /* Increase the data buffer reference counter. */ buffer->AddRef( buffer ); /* Create the PNG read handle. */ data->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!data->png_ptr) goto error; if (setjmp( data->png_ptr->jmpbuf )) { D_ERROR( "ImageProvider/PNG: Error reading header!\n" ); goto error; } /* Create the PNG info handle. */ data->info_ptr = png_create_info_struct( data->png_ptr ); if (!data->info_ptr) goto error; /* Setup progressive image loading. */ png_set_progressive_read_fn( data->png_ptr, data, png_info_callback, png_row_callback, png_end_callback ); /* Read until info callback is called. */ ret = push_data_until_stage( data, STAGE_INFO, 64 ); if (ret) goto error; thiz->AddRef = IDirectFBImageProvider_PNG_AddRef; thiz->Release = IDirectFBImageProvider_PNG_Release; thiz->RenderTo = IDirectFBImageProvider_PNG_RenderTo; thiz->SetRenderCallback = IDirectFBImageProvider_PNG_SetRenderCallback; thiz->GetImageDescription = IDirectFBImageProvider_PNG_GetImageDescription; thiz->GetSurfaceDescription = IDirectFBImageProvider_PNG_GetSurfaceDescription; return DFB_OK; error: if (data->png_ptr) png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL ); buffer->Release( buffer ); if (data->image) D_FREE( data->image ); DIRECT_DEALLOCATE_INTERFACE(thiz); return ret; }
//------------------------------------------------------------------------------ // Unit Test main //------------------------------------------------------------------------------ int main (int argc, char **argv) { int i, j; DFBResult rle_build_databuffer_err; // File name to load logo image from char *filename = NULL; // Basic directfb elements IDirectFB *dfb = NULL; IDirectFBSurface *primary = NULL; int screen_width = 0; int screen_height = 0; // The image is to be loaded into a surface that we can blit from. IDirectFBSurface *logo = NULL; // Loading an image is done with an Image Provider. IDirectFBImageProvider *provider = NULL; // An Image provider instance can also be created from a directfb buffer IDirectFBDataBuffer *databuffer = NULL; // Surface description DFBSurfaceDescription surface_dsc; // Initialize directfb first DFBCHECK (DirectFBInit (&argc, &argv)); DFBCHECK (DirectFBCreate (&dfb)); DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN)); // Create primary surface surface_dsc.flags = DSDESC_CAPS; surface_dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING; DFBCHECK (dfb->CreateSurface( dfb, &surface_dsc, &primary )); DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height)); if (argc==1) { argv[1] = "./data/directfb.rle"; argc++; } DISPLAY_INFO ("Rendering %d files\n",argc-1); for (j=1; j<argc; j++) { // // --- WE CREATE OUR IMAGE PROVIDER INSTANCE HERE // filename = argv[j]; DISPLAY_INFO ("Rendering : %s\n",filename); // We create a directfb data buffer holding RLE image contents that we // pick up from a file (could get the RLE contents from memory as well). // "rle_build_databuffer" details the process of dealing with a memory // RLE packet as a matter of fact. rle_build_databuffer_err = rle_build_databuffer (dfb, filename, &databuffer); if (rle_build_databuffer_err == DFB_OK) { // We want to create an Image Provider tied to a directfb data buffer. // DirectFB will find (or not) an Image Provider for the data type // depending on Image Providers probe method (sniffing data headers) DFBCHECK (databuffer->CreateImageProvider (databuffer, &provider)); } else { # ifdef USE_PACKET_BUILDER_ONLY DFBFAIL(rle_build_databuffer_err); # else // We could also create an Image Provider by passing a filename. // DirectFB will find (or not) an Image Provider matching the file type. DFBCHECK (dfb->CreateImageProvider (dfb, filename, &provider)); # endif } // Get a surface description from the provider. It will contain the width, // height, bits per pixel and the flag for an alphachannel if the image // has one. If the image has no alphachannel the bits per pixel is set to // the bits per pixel of the primary layer to use simple blitting without // pixel format conversion. DFBCHECK (provider->GetSurfaceDescription (provider, &surface_dsc)); // Create a surface based on the description of the provider. DFBCHECK (dfb->CreateSurface( dfb, &surface_dsc, &logo )); // Let the provider render to our surface. Image providers are supposed // to support every destination pixel format and size. If the size // differs the image will be scaled (bilinear). The last parameter allows // to specify an optional destination rectangle. We use NULL here so that // our image covers the whole logo surface. DFBCHECK (provider->RenderTo (provider, logo, NULL)); // Note: RLE Image Provider allows for direct non-scaled LUT-8 surface // rendering without any attached colormap. #ifdef CLEVER_APPROACH // Let's setup our logo surface palette outside of the RLE Image // Provider if we got a colormap from rle_build_databuffer ... if (color_palette) { IDirectFBPalette *palette; DFBCHECK (logo->GetPalette (logo, &palette)); palette->SetEntries (palette, color_palette, number_of_colors, 0); palette->Release (palette); } #endif // // --- WE GET RID OF OUR IMAGE PROVIDER INSTANCE HERE // // Release the provider, we don't need it anymore. provider->Release (provider); provider = NULL; // Destroy the databuffer as well, we don't need it anymore. rle_destroy_databuffer (databuffer); databuffer = NULL; # ifndef SUBTITLES_MODE // We want to let the logo slide in on the left and slide out on the // right. for (i = -surface_dsc.width; i < screen_width; i++) # else // We want to let the logo slide in on the right and slide out on the // left. for (i = screen_width-1; i >= -surface_dsc.width; i--) # endif { // Clear the screen. DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height)); // Blit the logo vertically centered with "i" as the X coordinate. // NULL means that we want to blit the whole surface. DFBCHECK (primary->Blit (primary, logo, NULL, i, (screen_height - surface_dsc.height) / 2)); // Flip the front and back buffer, but wait for the vertical // retrace to avoid tearing. DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC)); if (argc < 3) { usleep(1000*5); } } // Release the image. if (logo) { logo->Release (logo); } } // Release everything else primary->Release (primary); dfb->Release (dfb); return 0; }