On Mon, 2013-05-13 at 16:45 +0200, Denis Oliver Kropp wrote: > What about a convenience function that returns all three pointers and pitches > in an array?
Sounds better! > Also, passing the config is enough, as we are passing pointer/pitch already, > this is very OK. > get_ ( const CoreSurfaceConfig * const config, > const void * const data, > int pitch, > int x, > int y, > unsigned int num, <=== should be 1, 2 or 3 as > limit for output arrays > u8 ** pointers, > int * pitches ) > How about calling it dfb_surface_get_data_offsets() and having it return int, so that it can return an error if necessary? Although I am not sure errors are / should be possible here. Should array index #1 be Cb for 3-plane formats? Or should it reflect the endianess of the format, e.g. Cr for YV12 but Cb for I420? I would think it should be deterministic and less confusing if it was always the same, i.e. always Cb. Should behaviour change depending on num, or should num only be used to verify that the array was sized correctly? Do we need to keep the existing (internal) dfb_surface_data_offset()? Attached is an updated version. Cheers, Andre'
>From a87d2ecf4033733c6cc71e6c4b1802d4c13fe151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= <andre.dras...@st.com> Date: Tue, 14 May 2013 10:50:55 +0100 Subject: [PATCH] surface: add dfb_surface_get_data_offsets() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This can be used to calculate (and return) the pixel address and pitch for split buffer formats, for the CbCr or Cb and Cr components (2-plane or 3-plane formats). Signed-off-by: André Draszik <andre.dras...@st.com> --- src/core/surface.h | 145 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 133 insertions(+), 12 deletions(-) diff --git a/src/core/surface.h b/src/core/surface.h index aaa18d0..5e2339b 100644 --- a/src/core/surface.h +++ b/src/core/surface.h @@ -478,29 +478,150 @@ dfb_surface_get_buffer3( CoreSurface *surface, return surface->right_buffers[ surface->buffer_indices[(flip_count + role) % surface->num_buffers] ]; } -static __inline__ void * -dfb_surface_data_offset( const CoreSurface *surface, - void *data, - int pitch, - int x, - int y ) +static __inline__ void +dfb_surface_get_data_offsets( const CoreSurfaceConfig * const config, + const void * const data, + int pitch, + int x, + int y, + unsigned int num, + u8 ** const pointers, + int * const pitches ) { - D_ASSERT( surface != NULL ); + D_ASSERT( config != NULL ); D_ASSERT( data != NULL ); D_ASSERT( pitch > 0 ); D_ASSERT( x >= 0 ); - D_ASSERT( x < surface->config.size.w ); + D_ASSERT( x < config->size.w ); D_ASSERT( y >= 0 ); - D_ASSERT( y < surface->config.size.h ); + D_ASSERT( y < config->size.h ); + D_ASSERT( !num + || (num && pointers && pitches) ); + + if (!num) + return; + + switch (config->format) { + case DSPF_NV12: + case DSPF_NV21: + case DSPF_NV16: + D_ASSERT( num == 2 ); + break; - if (surface->config.caps & DSCAPS_SEPARATED) { + case DSPF_I420: + case DSPF_YV12: + case DSPF_YV16: + case DSPF_YUV444P: + D_ASSERT( num == 3 ); + break; + + default: + D_ASSERT( !DFB_PLANAR_PIXELFORMAT( config->format ) ); + D_ASSERT( num == 1 ); + break; + } + + if (config->caps & DSCAPS_SEPARATED) { if (y & 1) - y += surface->config.size.h; + y += config->size.h; y >>= 1; } - return (u8*)data + pitch * y + DFB_BYTES_PER_LINE( surface->config.format, x ); + switch (config->format) { + case DSPF_NV12: + case DSPF_NV21: + pitches[1] = pitch; + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * y/2 + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + break; + + case DSPF_NV16: + pitches[1] = pitch; + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * y + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + break; + + case DSPF_I420: + pitches[1] = pitches[2] = pitch / 2; + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * y/2 + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + pointers[2] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * config->size.h/2 + + pitches[2] * y/2 + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + break; + + case DSPF_YV12: + pitches[1] = pitches[2] = pitch / 2; + pointers[2] = ( (u8*)data + + pitch * config->size.h + + pitches[2] * y/2 + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[2] * config->size.h/2 + + pitches[1] * y/2 + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + break; + + case DSPF_YV16: + pitches[1] = pitches[2] = pitch / 2; + pointers[2] = ( (u8*)data + + pitch * config->size.h + + pitches[2] * y + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[2] * config->size.h + + pitches[1] * y + + DFB_BYTES_PER_LINE( config->format, x/2 ) ); + break; + + case DSPF_YUV444P: + pitches[1] = pitches[2] = pitch; + pointers[1] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * y + + DFB_BYTES_PER_LINE( config->format, x ) ); + pointers[2] = ( (u8*)data + + pitch * config->size.h + + pitches[1] * config->size.h + + pitches[2] * y + + DFB_BYTES_PER_LINE( config->format, x ) ); + break; + + default: + break; + } + + pointers[0] = ( (u8*)data + + pitch * y + + DFB_BYTES_PER_LINE( config->format, x ) ); + pitches[0] = pitch; +} + +static __inline__ void * +dfb_surface_data_offset( const CoreSurface *surface, + void *data, + int pitch, + int x, + int y ) +{ + u8 *pointers[1]; + int pitches[1]; + + dfb_surface_get_data_offsets( &surface->config, data, pitch, x, y, + 1, pointers, pitches); + + return pointers[0]; } static __inline__ void -- 1.8.2
_______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev