diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/aclib/img_yuv_packed.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/aclib/img_yuv_packed.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/aclib/img_yuv_packed.c b/debian/transcode/transcode-1.1.7/aclib/img_yuv_packed.c new file mode 100644 index 00000000..05357405 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/aclib/img_yuv_packed.c @@ -0,0 +1,290 @@ +/* + * img_yuv_packed.c - YUV packed image format conversion routines + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#include "ac.h" +#include "imgconvert.h" +#include "img_internal.h" + +/*************************************************************************/ +/*************************************************************************/ + +/* Standard C implementations */ + +/*************************************************************************/ + +/* Identity transformation, works when src==dest */ +static int yuv16_copy(uint8_t **src, uint8_t **dest, int width, int height) +{ + ac_memcpy(dest[0], src[0], width*height*2); + return 1; +} + +/* Used for YUY2->UYVY and UYVY->YUY2, works when src==dest */ +static int yuv16_swap16(uint8_t **src, uint8_t **dest, int width, int height) +{ + uint16_t *srcp = (uint16_t *)src[0]; + uint16_t *destp = (uint16_t *)dest[0]; + int i; + for (i = 0; i < width*height; i++) + destp[i] = srcp[i]>>8 | srcp[i]<<8; + return 1; +} + +/* Used for YUY2->YVYU and YVYU->YUY2, works when src==dest */ +static int yuv16_swapuv(uint8_t **src, uint8_t **dest, int width, int height) +{ + int i; + for (i = 0; i < width*height/2; i++) { + uint8_t tmp = src[0][i*4+1]; + dest[0][i*4 ] = src[0][i*4 ]; + dest[0][i*4+1] = src[0][i*4+3]; + dest[0][i*4+2] = src[0][i*4+2]; + dest[0][i*4+3] = tmp; + } + return 1; +} + +/*************************************************************************/ + +static int uyvy_yvyu(uint8_t **src, uint8_t **dest, int width, int height) +{ + int i; + for (i = 0; i < width*height/2; i++) { + dest[0][i*4 ] = src[0][i*4+1]; + dest[0][i*4+1] = src[0][i*4+2]; + dest[0][i*4+2] = src[0][i*4+3]; + dest[0][i*4+3] = src[0][i*4 ]; + } + return 1; +} + +static int yvyu_uyvy(uint8_t **src, uint8_t **dest, int width, int height) +{ + int i; + for (i = 0; i < width*height/2; i++) { + dest[0][i*4 ] = src[0][i*4+3]; + dest[0][i*4+1] = src[0][i*4 ]; + dest[0][i*4+2] = src[0][i*4+1]; + dest[0][i*4+3] = src[0][i*4+2]; + } + return 1; +} + +/*************************************************************************/ +/*************************************************************************/ + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + +/* Common macros/data for x86 code */ +#define DEFINE_MASK_DATA +#include "img_x86_common.h" + +/*************************************************************************/ + +/* Basic assembly routines */ + +static int yuv16_swap16_x86(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP16_2_X86(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yuv16_swapuv_x86(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP32_13_X86(width*height/2); + return 1; +} + +static int uyvy_yvyu_x86(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROR32_X86(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yvyu_uyvy_x86(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROL32_X86(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +/*************************************************************************/ + +/* MMX routines */ + +#if defined(HAVE_ASM_MMX) && defined(ARCH_X86) /* i.e. not x86_64 */ + +static int yuv16_swap16_mmx(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP16_2_MMX(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yuv16_swapuv_mmx(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP32_13_MMX(width*height/2); + return 1; +} + +static int uyvy_yvyu_mmx(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROR32_MMX(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yvyu_uyvy_mmx(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROL32_MMX(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +#endif /* HAVE_ASM_MMX && ARCH_X86 */ + +/*************************************************************************/ + +/* SSE2 routines */ + +#if defined(HAVE_ASM_SSE2) + +static int yuv16_swap16_sse2(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP16_2_SSE2(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yuv16_swapuv_sse2(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_SWAP32_13_SSE2(width*height/2); + return 1; +} + +static int uyvy_yvyu_sse2(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROR32_SSE2(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +static int yvyu_uyvy_sse2(uint8_t **src, uint8_t **dest, int width, int height) +{ + ASM_ROL32_SSE2(width*height/2); + if (width*height % 1) + ((uint16_t *)(dest[0]))[width*height-1] = + src[0][width*height*2-2]<<8 | src[0][width*height*2-1]; + return 1; +} + +#endif /* HAVE_ASM_SSE2 */ + +/*************************************************************************/ + +#endif /* ARCH_X86 || ARCH_X86_64 */ + +/*************************************************************************/ +/*************************************************************************/ + +/* Initialization */ + +int ac_imgconvert_init_yuv_packed(int accel) +{ + if (!register_conversion(IMG_YUY2, IMG_YUY2, yuv16_copy) + || !register_conversion(IMG_YUY2, IMG_UYVY, yuv16_swap16) + || !register_conversion(IMG_YUY2, IMG_YVYU, yuv16_swapuv) + + || !register_conversion(IMG_UYVY, IMG_YUY2, yuv16_swap16) + || !register_conversion(IMG_UYVY, IMG_UYVY, yuv16_copy) + || !register_conversion(IMG_UYVY, IMG_YVYU, uyvy_yvyu) + + || !register_conversion(IMG_YVYU, IMG_YUY2, yuv16_swapuv) + || !register_conversion(IMG_YVYU, IMG_UYVY, yvyu_uyvy) + || !register_conversion(IMG_YVYU, IMG_YVYU, yuv16_copy) + ) { + return 0; + } + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + if (accel & (AC_IA32ASM | AC_AMD64ASM)) { + if (!register_conversion(IMG_YUY2, IMG_UYVY, yuv16_swap16_x86) + || !register_conversion(IMG_YUY2, IMG_YVYU, yuv16_swapuv_x86) + || !register_conversion(IMG_UYVY, IMG_YUY2, yuv16_swap16_x86) + || !register_conversion(IMG_UYVY, IMG_YVYU, uyvy_yvyu_x86) + || !register_conversion(IMG_YVYU, IMG_YUY2, yuv16_swapuv_x86) + || !register_conversion(IMG_YVYU, IMG_UYVY, yvyu_uyvy_x86) + ) { + return 0; + } + } + +#if defined(HAVE_ASM_MMX) && defined(ARCH_X86) + if (accel & AC_MMX) { + if (!register_conversion(IMG_YUY2, IMG_UYVY, yuv16_swap16_mmx) + || !register_conversion(IMG_YUY2, IMG_YVYU, yuv16_swapuv_mmx) + || !register_conversion(IMG_UYVY, IMG_YUY2, yuv16_swap16_mmx) + || !register_conversion(IMG_UYVY, IMG_YVYU, uyvy_yvyu_mmx) + || !register_conversion(IMG_YVYU, IMG_YUY2, yuv16_swapuv_mmx) + || !register_conversion(IMG_YVYU, IMG_UYVY, yvyu_uyvy_mmx) + ) { + return 0; + } + } +#endif + +#if defined(HAVE_ASM_SSE2) + if (accel & AC_SSE2) { + if (!register_conversion(IMG_YUY2, IMG_UYVY, yuv16_swap16_sse2) + || !register_conversion(IMG_YUY2, IMG_YVYU, yuv16_swapuv_sse2) + || !register_conversion(IMG_UYVY, IMG_YUY2, yuv16_swap16_sse2) + || !register_conversion(IMG_UYVY, IMG_YVYU, uyvy_yvyu_sse2) + || !register_conversion(IMG_YVYU, IMG_YUY2, yuv16_swapuv_sse2) + || !register_conversion(IMG_YVYU, IMG_UYVY, yvyu_uyvy_sse2) + ) { + return 0; + } + } +#endif + +#endif /* ARCH_X86 || ARCH_X86_64 */ + + return 1; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ |
