From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c | 395 ++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c (limited to 'Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c') diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c new file mode 100755 index 0000000..9208890 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c @@ -0,0 +1,395 @@ +#ifdef SH7722_DEBUG_JPEG +#define DIRECT_ENABLE_DEBUG +#endif + +#include +#include + +#undef HAVE_STDLIB_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "sh7722.h" +#include "sh7722_jpeglib.h" + +D_DEBUG_DOMAIN( SH7722_JPEG, "SH7722/JPEG", "SH7722 JPEG Processing Unit" ); + +/**********************************************************************************************************************/ + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, SH7722_JPEG ) + +/* + * private data struct of IDirectFBImageProvider_SH7722_JPEG + */ +typedef struct { + int ref; /* reference counter */ + + SH7722_JPEG_context info; + + CoreDFB *core; + + IDirectFBDataBuffer *buffer; + DirectStream *stream; + + DIRenderCallback render_callback; + void *render_callback_context; +} IDirectFBImageProvider_SH7722_JPEG_data; + +/**********************************************************************************************************************/ + +static void +IDirectFBImageProvider_SH7722_JPEG_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_SH7722_JPEG_data *data = thiz->priv; + + data->buffer->Release( data->buffer ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_SH7722_JPEG_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_SH7722_JPEG_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG) + + if (--data->ref == 0) + IDirectFBImageProvider_SH7722_JPEG_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_SH7722_JPEG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + DFBRegion clip; + DFBRectangle rect; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + CoreSurfaceBufferLock lock; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG); + + if (!data->buffer) + return DFB_BUFFEREMPTY; + + DIRECT_INTERFACE_GET_DATA_FROM(destination, dst_data, IDirectFBSurface); + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + + rect.x = dest_rect->x + dst_data->area.wanted.x; + rect.y = dest_rect->y + dst_data->area.wanted.y; + rect.w = dest_rect->w; + rect.h = dest_rect->h; + } + else + rect = dst_data->area.wanted; + + if (!dfb_rectangle_region_intersects( &rect, &clip )) + return DFB_OK; + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_GPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + ret = SH7722_JPEG_Decode( &data->info, &rect, &clip, dst_surface->config.format, + lock.phys, lock.addr, lock.pitch, dst_surface->config.size.w, dst_surface->config.size.h ); + + dfb_surface_unlock_buffer( dst_surface, &lock ); + + return ret; +} + +static DFBResult +IDirectFBImageProvider_SH7722_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_SH7722_JPEG) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_SH7722_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG) + + if (!data->buffer) + return DFB_BUFFEREMPTY; + + desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + desc->height = data->info.height; + desc->width = data->info.width; + desc->pixelformat = data->info.mode420 ? DSPF_NV12 : DSPF_NV16; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_SH7722_JPEG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG) + + if (!desc) + return DFB_INVARG; + + if (!data->buffer) + return DFB_BUFFEREMPTY; + + desc->caps = DICAPS_NONE; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_SH7722_JPEG_WriteBack( IDirectFBImageProvider *thiz, + IDirectFBSurface *surface, + const DFBRectangle *src_rect, + const char *filename ) +{ + DFBResult ret; + DFBRegion clip; + DFBRectangle rect; + IDirectFBSurface_data *src_data; + CoreSurface *src_surface; + CoreSurfaceBufferLock lock; + DFBDimension jpeg_size; + + CoreSurface *tmp_surface; + CoreSurfaceBufferLock tmp_lock; + int tmp_pitch; + unsigned int tmp_phys; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG) + + if (!surface || !filename) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA_FROM(surface, src_data, IDirectFBSurface); + + D_DEBUG_AT( SH7722_JPEG, "%s - surface %p, rect %p to file %s\n", + __FUNCTION__, surface, src_rect, filename ); + + src_surface = src_data->surface; + if (!src_surface) + return DFB_DESTROYED; + + switch (src_surface->config.format) { + case DSPF_NV12: + case DSPF_NV16: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_RGB24: + break; + + default: + /* FIXME: implement fallback */ + D_UNIMPLEMENTED(); + return DFB_UNIMPLEMENTED; + } + + dfb_region_from_rectangle( &clip, &src_data->area.current ); + + if (src_rect) { + if (src_rect->w < 1 || src_rect->h < 1) + return DFB_INVARG; + + rect.x = src_rect->x + src_data->area.wanted.x; + rect.y = src_rect->y + src_data->area.wanted.y; + rect.w = src_rect->w; + rect.h = src_rect->h; + } + else + rect = src_data->area.wanted; + + if (!dfb_rectangle_region_intersects( &rect, &clip )) + return DFB_INVAREA; + + jpeg_size.w = src_surface->config.size.w; + jpeg_size.h = src_surface->config.size.h; + + /* it would be great if we had intermediate storage, since + * this prevents handling the encoding in 16-line chunks, + * causing scaling artefacts at the border of these chunks */ + + tmp_pitch = (jpeg_size.w + 3) & ~3; + ret = dfb_surface_create_simple( data->core, tmp_pitch, jpeg_size.h, + DSPF_NV16, DSCAPS_VIDEOONLY, + CSTF_NONE, 0, 0, &tmp_surface ); + if( ret ) { + /* too bad, we proceed without */ + D_DEBUG_AT( SH7722_JPEG, "%s - failed to create intermediate storage: %d\n", + __FUNCTION__, ret ); + tmp_surface = 0; + tmp_phys = 0; + } + else { + /* lock it to get the address */ + ret = dfb_surface_lock_buffer( tmp_surface, CSBR_FRONT, CSAID_GPU, CSAF_READ | CSAF_WRITE, &tmp_lock ); + if (ret) { + D_DEBUG_AT( SH7722_JPEG, "%s - failed to lock intermediate storage: %d\n", + __FUNCTION__, ret ); + dfb_surface_unref( tmp_surface ); + tmp_surface = 0; + tmp_phys = 0; + } + else { + tmp_phys = tmp_lock.phys; + D_DEBUG_AT( SH7722_JPEG, "%s - surface locked at %x\n", __FUNCTION__, tmp_phys ); + } + } + + ret = dfb_surface_lock_buffer( src_surface, CSBR_FRONT, CSAID_GPU, CSAF_READ, &lock ); + if ( ret == DFB_OK ) { + ret = SH7722_JPEG_Encode( filename, &rect, src_surface->config.format, lock.phys, lock.pitch, + jpeg_size.w, jpeg_size.h, tmp_phys ); + + dfb_surface_unlock_buffer( src_surface, &lock ); + } + + if( tmp_surface ) { + /* unlock and release the created surface */ + dfb_surface_unlock_buffer( tmp_surface, &tmp_lock ); + dfb_surface_unref( tmp_surface ); + } + + return ret; +} + +/**********************************************************************************************************************/ + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + SH7722DeviceData *sdev = dfb_gfxcard_get_device_data(); + +#ifndef JPU_SUPPORT + return DFB_UNSUPPORTED; +#endif + + if (sdev->sh772x != 7722) + return DFB_UNSUPPORTED; + + /* Called with NULL when used for encoding. */ + if (!ctx) + return DFB_OK; + + if (ctx->header[0] == 0xff && ctx->header[1] == 0xd8 && ctx->filename) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + DFBResult ret; + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_SH7722_JPEG); + + 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; + + if (buffer) { + IDirectFBDataBuffer_File_data *file_data; + + ret = buffer->AddRef( buffer ); + if (ret) { + DIRECT_DEALLOCATE_INTERFACE(thiz); + return ret; + } + + DIRECT_INTERFACE_GET_DATA_FROM( buffer, file_data, IDirectFBDataBuffer_File ); + + data->stream = file_data->stream; + + ret = SH7722_JPEG_Open( file_data->stream, &data->info ); + if (ret) { + buffer->Release( buffer ); + DIRECT_DEALLOCATE_INTERFACE(thiz); + return ret; + } + } + + thiz->AddRef = IDirectFBImageProvider_SH7722_JPEG_AddRef; + thiz->Release = IDirectFBImageProvider_SH7722_JPEG_Release; + thiz->RenderTo = IDirectFBImageProvider_SH7722_JPEG_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_SH7722_JPEG_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_SH7722_JPEG_GetImageDescription; + thiz->GetSurfaceDescription = IDirectFBImageProvider_SH7722_JPEG_GetSurfaceDescription; + thiz->WriteBack = IDirectFBImageProvider_SH7722_JPEG_WriteBack; + + return DFB_OK; +} + -- cgit