From 64d779f2f7607070a87b0a70edeba5e51834ce85 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 12 Jan 2012 21:11:27 +0100 Subject: [PATCH 1/9] cabac: Remove ff_h264_lps_state array. It was only ever used in the cabac test program, but never initialized. --- libavcodec/cabac.c | 2 -- libavcodec/cabac.h | 1 - 2 files changed, 3 deletions(-) diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 54414fa1e5..1de45841ea 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -51,7 +51,6 @@ static const uint8_t lps_range[64][4]= { uint8_t ff_h264_mlps_state[4*64]; uint8_t ff_h264_lps_range[4*2*64]; -uint8_t ff_h264_lps_state[2*64]; uint8_t ff_h264_mps_state[2*64]; static const uint8_t mps_state[64]= { @@ -196,7 +195,6 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ }else{ c->low += c->range - RangeLPS; c->range = RangeLPS; - *state= ff_h264_lps_state[*state]; } renorm_cabac_encoder(c); diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index dda6348ea4..f7d169ac11 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -50,7 +50,6 @@ typedef struct CABACContext{ extern uint8_t ff_h264_mlps_state[4*64]; extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS -extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS extern const uint8_t ff_h264_norm_shift[512]; #if ARCH_X86 From 0a60780c7fe72e2f9cc41efc152b3807954b7820 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 12 Jan 2012 21:35:34 +0100 Subject: [PATCH 2/9] cabac: Mark ff_h264_mps_state array as static, it is only used within cabac.c. --- libavcodec/cabac.c | 8 ++++---- libavcodec/cabac.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 1de45841ea..11971f5984 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -51,7 +51,7 @@ static const uint8_t lps_range[64][4]= { uint8_t ff_h264_mlps_state[4*64]; uint8_t ff_h264_lps_range[4*2*64]; -uint8_t ff_h264_mps_state[2*64]; +static uint8_t h264_mps_state[2 * 64]; static const uint8_t mps_state[64]= { 1, 2, 3, 4, 5, 6, 7, 8, @@ -140,9 +140,9 @@ void ff_init_cabac_states(CABACContext *c){ } ff_h264_mlps_state[128+2*i+0]= - ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0; + h264_mps_state[2 * i + 0] = 2 * mps_state[i] + 0; ff_h264_mlps_state[128+2*i+1]= - ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; + h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1; if( i ){ ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; @@ -191,7 +191,7 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ if(bit == ((*state)&1)){ c->range -= RangeLPS; - *state= ff_h264_mps_state[*state]; + *state = h264_mps_state[*state]; }else{ c->low += c->range - RangeLPS; c->range = RangeLPS; diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index f7d169ac11..ab835f921f 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -49,7 +49,6 @@ typedef struct CABACContext{ extern uint8_t ff_h264_mlps_state[4*64]; extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS -extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS extern const uint8_t ff_h264_norm_shift[512]; #if ARCH_X86 From 55b9ef18e4a139fc24a3b695cb3c176f3ced09b8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 12 Jan 2012 21:56:02 +0100 Subject: [PATCH 3/9] cabac: split cabac.h into declarations and function definitions This fixes standalone compilation of some decoders with --disable-optimizations. cabac.h defines some inline functions that use symbols from cabac.c. Without optimizations these inline functions are not eliminated and linking fails with references to non-existing symbols. Splitting the inline functions off into their own header and only #including it in the places where the inline functions are used allows #including cabac.h from anywhere without ill effects. --- libavcodec/cabac.c | 1 + libavcodec/cabac.h | 131 +--------------------------- libavcodec/cabac_functions.h | 160 +++++++++++++++++++++++++++++++++++ libavcodec/h264.c | 4 +- libavcodec/h264_cabac.c | 4 +- 5 files changed, 167 insertions(+), 133 deletions(-) create mode 100644 libavcodec/cabac_functions.h diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 11971f5984..4afcafb52b 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -29,6 +29,7 @@ #include "libavutil/common.h" #include "get_bits.h" #include "cabac.h" +#include "cabac_functions.h" static const uint8_t lps_range[64][4]= { {128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205}, diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index ab835f921f..5a99f0b2fe 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -27,13 +27,10 @@ #ifndef AVCODEC_CABAC_H #define AVCODEC_CABAC_H -#include +#include #include "put_bits.h" -//#undef NDEBUG -#include - #define CABAC_BITS 16 #define CABAC_MASK ((1<low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); -#else - c->low+= c->bytestream[0]<<1; -#endif - c->low -= CABAC_MASK; - c->bytestream+= CABAC_BITS/8; -} - -static inline void renorm_cabac_decoder_once(CABACContext *c){ - int shift= (uint32_t)(c->range - 0x100)>>31; - c->range<<= shift; - c->low <<= shift; - if(!(c->low & CABAC_MASK)) - refill(c); -} - -#ifndef get_cabac_inline -static void refill2(CABACContext *c){ - int i, x; - - x= c->low ^ (c->low-1); - i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; - - x= -CABAC_MASK; - -#if CABAC_BITS == 16 - x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); -#else - x+= c->bytestream[0]<<1; -#endif - - c->low += x<bytestream+= CABAC_BITS/8; -} - -static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ - int s = *state; - int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; - int bit, lps_mask; - - c->range -= RangeLPS; - lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; - - c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; - c->range += (RangeLPS - c->range) & lps_mask; - - s^=lps_mask; - *state= (ff_h264_mlps_state+128)[s]; - bit= s&1; - - lps_mask= ff_h264_norm_shift[c->range]; - c->range<<= lps_mask; - c->low <<= lps_mask; - if(!(c->low & CABAC_MASK)) - refill2(c); - return bit; -} -#endif - -static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac_bypass(CABACContext *c){ - int range; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - if(c->low < range){ - return 0; - }else{ - c->low -= range; - return 1; - } -} - - -#ifndef get_cabac_bypass_sign -static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ - int range, mask; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - c->low -= range; - mask= c->low >> 31; - range &= mask; - c->low += range; - return (val^mask)-mask; -} -#endif - -/** - * - * @return the number of bytes read or 0 if no end - */ -static int av_unused get_cabac_terminate(CABACContext *c){ - c->range -= 2; - if(c->low < c->range<<(CABAC_BITS+1)){ - renorm_cabac_decoder_once(c); - return 0; - }else{ - return c->bytestream - c->bytestream_start; - } -} - #endif /* AVCODEC_CABAC_H */ diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h new file mode 100644 index 0000000000..b150aabcc4 --- /dev/null +++ b/libavcodec/cabac_functions.h @@ -0,0 +1,160 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Context Adaptive Binary Arithmetic Coder inline functions + */ + +#ifndef AVCODEC_CABAC_FUNCTIONS_H +#define AVCODEC_CABAC_FUNCTIONS_H + +#include + +#include "cabac.h" +#include "config.h" + +#if ARCH_X86 +# include "x86/cabac.h" +#endif + +extern const uint8_t ff_h264_norm_shift[512]; +extern uint8_t ff_h264_mlps_state[4*64]; +extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS + +static void refill(CABACContext *c){ +#if CABAC_BITS == 16 + c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); +#else + c->low+= c->bytestream[0]<<1; +#endif + c->low -= CABAC_MASK; + c->bytestream+= CABAC_BITS/8; +} + +static inline void renorm_cabac_decoder_once(CABACContext *c){ + int shift= (uint32_t)(c->range - 0x100)>>31; + c->range<<= shift; + c->low <<= shift; + if(!(c->low & CABAC_MASK)) + refill(c); +} + +#ifndef get_cabac_inline +static void refill2(CABACContext *c){ + int i, x; + + x= c->low ^ (c->low-1); + i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; + + x= -CABAC_MASK; + +#if CABAC_BITS == 16 + x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); +#else + x+= c->bytestream[0]<<1; +#endif + + c->low += x<bytestream+= CABAC_BITS/8; +} + +static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ + int s = *state; + int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; + int bit, lps_mask; + + c->range -= RangeLPS; + lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; + + c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; + c->range += (RangeLPS - c->range) & lps_mask; + + s^=lps_mask; + *state= (ff_h264_mlps_state+128)[s]; + bit= s&1; + + lps_mask= ff_h264_norm_shift[c->range]; + c->range<<= lps_mask; + c->low <<= lps_mask; + if(!(c->low & CABAC_MASK)) + refill2(c); + return bit; +} +#endif + +static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ + return get_cabac_inline(c,state); +} + +static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ + return get_cabac_inline(c,state); +} + +static int av_unused get_cabac_bypass(CABACContext *c){ + int range; + c->low += c->low; + + if(!(c->low & CABAC_MASK)) + refill(c); + + range= c->range<<(CABAC_BITS+1); + if(c->low < range){ + return 0; + }else{ + c->low -= range; + return 1; + } +} + + +#ifndef get_cabac_bypass_sign +static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ + int range, mask; + c->low += c->low; + + if(!(c->low & CABAC_MASK)) + refill(c); + + range= c->range<<(CABAC_BITS+1); + c->low -= range; + mask= c->low >> 31; + range &= mask; + c->low += range; + return (val^mask)-mask; +} +#endif + +/** + * + * @return the number of bytes read or 0 if no end + */ +static int av_unused get_cabac_terminate(CABACContext *c){ + c->range -= 2; + if(c->low < c->range<<(CABAC_BITS+1)){ + renorm_cabac_decoder_once(c); + return 0; + }else{ + return c->bytestream - c->bytestream_start; + } +} + +#endif /* AVCODEC_CABAC_FUNCTIONS_H */ diff --git a/libavcodec/h264.c b/libavcodec/h264.c index cee16e7577..581848be16 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -27,6 +27,8 @@ #include "libavutil/imgutils.h" #include "internal.h" +#include "cabac.h" +#include "cabac_functions.h" #include "dsputil.h" #include "avcodec.h" #include "mpegvideo.h" @@ -40,8 +42,6 @@ #include "vdpau_internal.h" #include "libavutil/avassert.h" -#include "cabac.h" - //#undef NDEBUG #include diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index feadf49364..a49ac6d498 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -27,6 +27,9 @@ #define CABAC 1 +#include "config.h" +#include "cabac.h" +#include "cabac_functions.h" #include "internal.h" #include "dsputil.h" #include "avcodec.h" @@ -35,7 +38,6 @@ #include "h264_mvpred.h" #include "golomb.h" -#include "cabac.h" #if ARCH_X86 #include "x86/h264_i386.h" #endif From e7843db3df0224cafcc1af9da103a3a7286ae2ba Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 12 Jan 2012 15:37:58 -0800 Subject: [PATCH 4/9] swscale: fix invalid conversions and memory problems. Fixes problems where rgbToRgbWrapper() is called even though it doesn't support this particular conversion (e.g. converting from RGB444 to anything). Thirdly, fixes issues where rgbToRgbWrapper() is called for non-native endiannness conversions (e.g. RGB555BE on a LE system). Fourthly, fixes crashes when converting from e.g. monowhite to monowhite, which calls planarCopyWrapper() and overwrites/reads because n_bytes != n_pixels. --- libswscale/swscale_unscaled.c | 49 +++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index a1b7199a23..e497fef84f 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -352,17 +352,22 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], ) /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ -static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], - int srcSliceY, int srcSliceH, uint8_t *dst[], - int dstStride[]) +typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int); +static rgbConvFn findRgbConvFn(SwsContext *c) { const enum PixelFormat srcFormat = c->srcFormat; const enum PixelFormat dstFormat = c->dstFormat; - const int srcBpp = (c->srcFormatBpp + 7) >> 3; - const int dstBpp = (c->dstFormatBpp + 7) >> 3; const int srcId = c->srcFormatBpp; const int dstId = c->dstFormatBpp; - void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL; + rgbConvFn conv = NULL; + +#define IS_NOT_NE(bpp, fmt) \ + (((bpp + 7) >> 3) == 2 && \ + (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN)) + + /* if this is non-native rgb444/555/565, don't handle it here. */ + if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat)) + return NULL; #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) @@ -419,6 +424,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], } } + return conv; +} + +/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ +static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], + int dstStride[]) + +{ + const enum PixelFormat srcFormat = c->srcFormat; + const enum PixelFormat dstFormat = c->dstFormat; + const int srcBpp = (c->srcFormatBpp + 7) >> 3; + const int dstBpp = (c->dstFormatBpp + 7) >> 3; + rgbConvFn conv = findRgbConvFn(c); + if (!conv) { av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", sws_format_name(srcFormat), sws_format_name(dstFormat)); @@ -716,6 +736,8 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], } else { if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) length *= 2; + else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1) + length >>= 3; // monowhite/black for (i = 0; i < height; i++) { memcpy(dstPtr, srcPtr, length); srcPtr += srcStride[plane]; @@ -770,20 +792,7 @@ void ff_get_unscaled_swscale(SwsContext *c) c->swScale = bgr24ToYv12Wrapper; /* RGB/BGR -> RGB/BGR (no dither needed forms) */ - if ( isAnyRGB(srcFormat) - && isAnyRGB(dstFormat) - && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 - && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 - && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 - && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 - && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE - && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE - && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK - && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE - && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE - && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE - && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE - && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE + if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c) && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) c->swScale= rgbToRgbWrapper; From 06b0246da07e7c9d95476b35275a63cd6dbc300c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 12 Jan 2012 15:38:37 -0800 Subject: [PATCH 5/9] swscale-test: fix stack overread. Fixes problems in swscale-test where it gives a 3-member array to a function expecting a 4-member array. --- libswscale/swscale-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c index 7ea01a6b68..3497dffbe0 100644 --- a/libswscale/swscale-test.c +++ b/libswscale/swscale-test.c @@ -337,8 +337,8 @@ int main(int argc, char **argv) enum PixelFormat srcFormat = PIX_FMT_NONE; enum PixelFormat dstFormat = PIX_FMT_NONE; uint8_t *rgb_data = av_malloc(W * H * 4); - uint8_t *rgb_src[3] = { rgb_data, NULL, NULL }; - int rgb_stride[3] = { 4 * W, 0, 0 }; + uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL }; + int rgb_stride[4] = { 4 * W, 0, 0, 0 }; uint8_t *data = av_malloc(4 * W * H); uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 }; int stride[4] = { W, W, W, W }; From 0cc1a86dc34b020d857f946e47edf9e425274330 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 12 Jan 2012 20:28:47 +0000 Subject: [PATCH 6/9] rgb2rgb: rgb12to15() Signed-off-by: Ronald S. Bultje --- libswscale/rgb2rgb.c | 19 +++++++++++++++++++ libswscale/rgb2rgb.h | 1 + libswscale/swscale_unscaled.c | 1 + 3 files changed, 21 insertions(+) diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c index 9fbb6cfd60..47b06f53fc 100644 --- a/libswscale/rgb2rgb.c +++ b/libswscale/rgb2rgb.c @@ -183,6 +183,25 @@ void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size) } } +void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size) +{ + const uint16_t *end; + uint16_t *d = (uint16_t *)dst; + const uint16_t *s = (const uint16_t *)src; + uint16_t rgb, r, g, b; + end = s + src_size / 2; + while (s < end) { + rgb = *s++; + r = rgb & 0xF00; + g = rgb & 0x0F0; + b = rgb & 0x00F; + r = (r << 3) | ((r & 0x800) >> 1); + g = (g << 2) | ((g & 0x080) >> 2); + b = (b << 1) | ( b >> 3); + *d++ = r | g | b; + } +} + void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size) { const uint16_t *end; diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h index bfb85d722f..42f468fe21 100644 --- a/libswscale/rgb2rgb.h +++ b/libswscale/rgb2rgb.h @@ -63,6 +63,7 @@ void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size); void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size); void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); +void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size); void bgr8torgb8(const uint8_t *src, uint8_t *dst, int src_size); void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size); diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index e497fef84f..5fe2b14256 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -389,6 +389,7 @@ static rgbConvFn findRgbConvFn(SwsContext *c) if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { switch (srcId | (dstId << 16)) { + case 0x000F000C: conv = rgb12to15; break; case 0x000F0010: conv = rgb16to15; break; case 0x000F0018: conv = rgb24to15; break; case 0x000F0020: conv = rgb32to15; break; From 5c5e1ea3cdccc5af0b2d3de15a9c3739c30ec88c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 13 Jan 2012 18:56:36 +0000 Subject: [PATCH 7/9] ARM: 4-byte align start of all asm functions Due to apprent bugs in the GNU assembler and/or linker, relocations can be incorrectly processed if the alignment of a Thumb instruction is changed in the output file compared to the input object. This fixes crashes in h264 decoding with Thumb enabled. No effect in ARM mode since everything is 4-byte aligned there. Signed-off-by: Mans Rullgard --- libavcodec/arm/asm.S | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/arm/asm.S b/libavcodec/arm/asm.S index aaf497e8c2..3b495a279f 100644 --- a/libavcodec/arm/asm.S +++ b/libavcodec/arm/asm.S @@ -68,6 +68,7 @@ ELF .size \name, . - \name .purgem endfunc .endm .text + .align 2 .if \export .global EXTERN_ASM\name EXTERN_ASM\name: From 71b3a63e9c87057a1cc1431ac1edd6854e1e4e44 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 13 Jan 2012 19:03:14 +0000 Subject: [PATCH 8/9] ARM: fix Thumb-mode simple_idct_arm The alignment directive must obviously precede the label. This was never noticed in ARM mode since the location is already aligned there. Signed-off-by: Mans Rullgard --- libavcodec/arm/simple_idct_arm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S index 1490f539df..a9c3095157 100644 --- a/libavcodec/arm/simple_idct_arm.S +++ b/libavcodec/arm/simple_idct_arm.S @@ -491,8 +491,8 @@ __end_bef_a_evaluation: bal __end_a_evaluation -__constant_ptr__: @@ see #defines at the beginning of the source code for values. .align +__constant_ptr__: @@ see #defines at the beginning of the source code for values. .word W1 .word W2 .word W3 From 68d6012c723bb520daac5336dcb046c0a5dd3826 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 11 Jan 2012 20:06:46 -0500 Subject: [PATCH 9/9] FATE: add tests for targa Based on a patch by Oana Stratulat --- tests/fate/image.mak | 28 ++++++++++++++++++++++++++ tests/ref/fate/targa-conformance-CBW8 | 1 + tests/ref/fate/targa-conformance-CTC16 | 1 + tests/ref/fate/targa-conformance-CTC24 | 1 + tests/ref/fate/targa-conformance-CTC32 | 1 + tests/ref/fate/targa-conformance-UBW8 | 1 + tests/ref/fate/targa-conformance-UTC16 | 1 + tests/ref/fate/targa-conformance-UTC24 | 1 + tests/ref/fate/targa-conformance-UTC32 | 1 + tests/ref/fate/targa-top-to-bottom | 1 + 10 files changed, 37 insertions(+) create mode 100644 tests/ref/fate/targa-conformance-CBW8 create mode 100644 tests/ref/fate/targa-conformance-CTC16 create mode 100644 tests/ref/fate/targa-conformance-CTC24 create mode 100644 tests/ref/fate/targa-conformance-CTC32 create mode 100644 tests/ref/fate/targa-conformance-UBW8 create mode 100644 tests/ref/fate/targa-conformance-UTC16 create mode 100644 tests/ref/fate/targa-conformance-UTC24 create mode 100644 tests/ref/fate/targa-conformance-UTC32 create mode 100644 tests/ref/fate/targa-top-to-bottom diff --git a/tests/fate/image.mak b/tests/fate/image.mak index 9c5106f803..153a4f397e 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -30,3 +30,31 @@ fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw. FATE_TESTS += fate-sunraster-24bit-rle fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun + +FATE_TARGA = CBW8 \ + CTC16 \ + CTC24 \ + CTC32 \ + UBW8 \ + UTC16 \ + UTC24 \ + UTC32 + +FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%) \ + fate-targa-top-to-bottom + +FATE_TESTS += $(FATE_TARGA) +fate-targa: $(FATE_TARGA) + +fate-targa-conformance-CBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA +# fate-targa-conformance-CCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CCM8.TGA +fate-targa-conformance-CTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC16.TGA +fate-targa-conformance-CTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC24.TGA +fate-targa-conformance-CTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC32.TGA +fate-targa-conformance-UBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UBW8.TGA +# fate-targa-conformance-UCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UCM8.TGA +fate-targa-conformance-UTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC16.TGA +fate-targa-conformance-UTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC24.TGA +fate-targa-conformance-UTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC32.TGA + +fate-targa-top-to-bottom: CMD = framecrc -i $(SAMPLES)/targa/lena-top-to-bottom.tga diff --git a/tests/ref/fate/targa-conformance-CBW8 b/tests/ref/fate/targa-conformance-CBW8 new file mode 100644 index 0000000000..4ff3a9d42a --- /dev/null +++ b/tests/ref/fate/targa-conformance-CBW8 @@ -0,0 +1 @@ +0, 0, 16384, 0x267e21ef diff --git a/tests/ref/fate/targa-conformance-CTC16 b/tests/ref/fate/targa-conformance-CTC16 new file mode 100644 index 0000000000..d2c75f684d --- /dev/null +++ b/tests/ref/fate/targa-conformance-CTC16 @@ -0,0 +1 @@ +0, 0, 32768, 0xa6b3d20d diff --git a/tests/ref/fate/targa-conformance-CTC24 b/tests/ref/fate/targa-conformance-CTC24 new file mode 100644 index 0000000000..42e12715ac --- /dev/null +++ b/tests/ref/fate/targa-conformance-CTC24 @@ -0,0 +1 @@ +0, 0, 49152, 0xaca4bc29 diff --git a/tests/ref/fate/targa-conformance-CTC32 b/tests/ref/fate/targa-conformance-CTC32 new file mode 100644 index 0000000000..acc3068e26 --- /dev/null +++ b/tests/ref/fate/targa-conformance-CTC32 @@ -0,0 +1 @@ +0, 0, 65536, 0xcf98bc29 diff --git a/tests/ref/fate/targa-conformance-UBW8 b/tests/ref/fate/targa-conformance-UBW8 new file mode 100644 index 0000000000..4ff3a9d42a --- /dev/null +++ b/tests/ref/fate/targa-conformance-UBW8 @@ -0,0 +1 @@ +0, 0, 16384, 0x267e21ef diff --git a/tests/ref/fate/targa-conformance-UTC16 b/tests/ref/fate/targa-conformance-UTC16 new file mode 100644 index 0000000000..d2c75f684d --- /dev/null +++ b/tests/ref/fate/targa-conformance-UTC16 @@ -0,0 +1 @@ +0, 0, 32768, 0xa6b3d20d diff --git a/tests/ref/fate/targa-conformance-UTC24 b/tests/ref/fate/targa-conformance-UTC24 new file mode 100644 index 0000000000..42e12715ac --- /dev/null +++ b/tests/ref/fate/targa-conformance-UTC24 @@ -0,0 +1 @@ +0, 0, 49152, 0xaca4bc29 diff --git a/tests/ref/fate/targa-conformance-UTC32 b/tests/ref/fate/targa-conformance-UTC32 new file mode 100644 index 0000000000..acc3068e26 --- /dev/null +++ b/tests/ref/fate/targa-conformance-UTC32 @@ -0,0 +1 @@ +0, 0, 65536, 0xcf98bc29 diff --git a/tests/ref/fate/targa-top-to-bottom b/tests/ref/fate/targa-top-to-bottom new file mode 100644 index 0000000000..e9d53bb455 --- /dev/null +++ b/tests/ref/fate/targa-top-to-bottom @@ -0,0 +1 @@ +0, 0, 196608, 0xb29ec51a