summaryrefslogtreecommitdiffstats
path: root/libswscale/swscale.c
diff options
context:
space:
mode:
Diffstat (limited to 'libswscale/swscale.c')
-rw-r--r--libswscale/swscale.c135
1 files changed, 101 insertions, 34 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index ff2d1d49d4..a926bade05 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -155,6 +155,13 @@ unsigned swscale_version(void)
|| isRGB(x) \
|| isBGR(x) \
)
+#define usePal(x) ( \
+ (x)==PIX_FMT_PAL8 \
+ || (x)==PIX_FMT_BGR4_BYTE \
+ || (x)==PIX_FMT_RGB4_BYTE \
+ || (x)==PIX_FMT_BGR8 \
+ || (x)==PIX_FMT_RGB8 \
+ )
#define RGB2YUV_SHIFT 15
#define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
@@ -205,11 +212,6 @@ DECLARE_ASM_CONST(8, uint64_t, bm00000111)=0x0000000000FFFFFFLL;
DECLARE_ASM_CONST(8, uint64_t, bm11111000)=0xFFFFFFFFFF000000LL;
DECLARE_ASM_CONST(8, uint64_t, bm01010101)=0x00FF00FF00FF00FFLL;
-static volatile uint64_t attribute_used __attribute__((aligned(8))) b5Dither;
-static volatile uint64_t attribute_used __attribute__((aligned(8))) g5Dither;
-static volatile uint64_t attribute_used __attribute__((aligned(8))) g6Dither;
-static volatile uint64_t attribute_used __attribute__((aligned(8))) r5Dither;
-
const DECLARE_ALIGNED(8, uint64_t, ff_dither4[2]) = {
0x0103010301030103LL,
0x0200020002000200LL,};
@@ -242,18 +244,18 @@ DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YOffset) = 0x1010101010101010ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_w1111) = 0x0001000100010001ULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_bgr24toYOffset) = 0x0008400000084000ULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toYOffset) = 0x0008400000084000ULL;
-DECLARE_ALIGNED(8, const uint64_t, ff_bgr24toUV[2][4]) = {
+DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUV[2][4]) = {
{0x38380000DAC83838ULL, 0xECFFDAC80000ECFFULL, 0xF6E40000D0E3F6E4ULL, 0x3838D0E300003838ULL},
{0xECFF0000DAC8ECFFULL, 0x3838DAC800003838ULL, 0x38380000D0E33838ULL, 0xF6E4D0E30000F6E4ULL},
};
-DECLARE_ALIGNED(8, const uint64_t, ff_bgr24toUVOffset)= 0x0040400000404000ULL;
+DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUVOffset)= 0x0040400000404000ULL;
#endif /* defined(ARCH_X86) */
@@ -262,12 +264,12 @@ static unsigned char clip_table[768];
static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b);
-const uint8_t __attribute__((aligned(8))) dither_2x2_4[2][8]={
+static const uint8_t __attribute__((aligned(8))) dither_2x2_4[2][8]={
{ 1, 3, 1, 3, 1, 3, 1, 3, },
{ 2, 0, 2, 0, 2, 0, 2, 0, },
};
-const uint8_t __attribute__((aligned(8))) dither_2x2_8[2][8]={
+static const uint8_t __attribute__((aligned(8))) dither_2x2_8[2][8]={
{ 6, 2, 6, 2, 6, 2, 6, 2, },
{ 0, 4, 0, 4, 0, 4, 0, 4, },
};
@@ -1059,7 +1061,7 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF
int ret= -1;
#if defined(ARCH_X86)
if (flags & SWS_CPU_CAPS_MMX)
- asm volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
+ __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
#endif
// Note the +1 is for the MMXscaler which reads over the end
@@ -1448,7 +1450,7 @@ static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *fil
//code fragment
- asm volatile(
+ __asm__ volatile(
"jmp 9f \n\t"
// Begin
"0: \n\t"
@@ -1488,7 +1490,7 @@ static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *fil
"=r" (fragmentLengthA)
);
- asm volatile(
+ __asm__ volatile(
"jmp 9f \n\t"
// Begin
"0: \n\t"
@@ -1712,11 +1714,46 @@ static int YUV422PToUyvyWrapper(SwsContext *c, uint8_t* src[], int srcStride[],
return srcSliceH;
}
+static int pal2rgbWrapper(SwsContext *c, 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;
+ void (*conv)(const uint8_t *src, uint8_t *dst, long num_pixels,
+ const uint8_t *palette)=NULL;
+ int i;
+ uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
+ uint8_t *srcPtr= src[0];
+
+ if (!usePal(srcFormat))
+ av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
+ sws_format_name(srcFormat), sws_format_name(dstFormat));
+
+ switch(dstFormat){
+ case PIX_FMT_RGB32 : conv = palette8topacked32; break;
+ case PIX_FMT_BGR32 : conv = palette8topacked32; break;
+ case PIX_FMT_BGR32_1: conv = palette8topacked32; break;
+ case PIX_FMT_RGB32_1: conv = palette8topacked32; break;
+ case PIX_FMT_RGB24 : conv = palette8topacked24; break;
+ case PIX_FMT_BGR24 : conv = palette8topacked24; break;
+ default: av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
+ sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
+ }
+
+
+ for (i=0; i<srcSliceH; i++) {
+ conv(srcPtr, dstPtr, c->srcW, c->pal_rgb);
+ srcPtr+= srcStride[0];
+ dstPtr+= dstStride[0];
+ }
+
+ return srcSliceH;
+}
+
/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
static int rgb2rgbWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
- const int srcFormat= c->srcFormat;
- const int dstFormat= c->dstFormat;
+ const enum PixelFormat srcFormat= c->srcFormat;
+ const enum PixelFormat dstFormat= c->dstFormat;
const int srcBpp= (fmt_depth(srcFormat) + 7) >> 3;
const int dstBpp= (fmt_depth(dstFormat) + 7) >> 3;
const int srcId= fmt_depth(srcFormat) >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
@@ -2101,7 +2138,7 @@ int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int
return 0;
}
-static int handle_jpeg(int *format)
+static int handle_jpeg(enum PixelFormat *format)
{
switch (*format) {
case PIX_FMT_YUVJ420P:
@@ -2121,7 +2158,7 @@ static int handle_jpeg(int *format)
}
}
-SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
+SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags,
SwsFilter *srcFilter, SwsFilter *dstFilter, double *param){
SwsContext *c;
@@ -2132,7 +2169,7 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
#if defined(ARCH_X86)
if (flags & SWS_CPU_CAPS_MMX)
- asm volatile("emms\n\t"::: "memory");
+ __asm__ volatile("emms\n\t"::: "memory");
#endif
#if !defined(RUNTIME_CPUDETECT) || !defined (CONFIG_GPL) //ensure that the flags match the compiled variant if cpudetect is off
@@ -2306,6 +2343,15 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH
&& (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
c->swScale= rgb2rgbWrapper;
+ if ((usePal(srcFormat) && (
+ dstFormat == PIX_FMT_RGB32 ||
+ dstFormat == PIX_FMT_RGB32_1 ||
+ dstFormat == PIX_FMT_RGB24 ||
+ dstFormat == PIX_FMT_BGR32 ||
+ dstFormat == PIX_FMT_BGR32_1 ||
+ dstFormat == PIX_FMT_BGR24)))
+ c->swScale= pal2rgbWrapper;
+
if (srcFormat == PIX_FMT_YUV422P)
{
if (dstFormat == PIX_FMT_YUYV422)
@@ -2659,12 +2705,6 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int i;
uint8_t* src2[4]= {src[0], src[1], src[2]};
- uint32_t pal[256];
- int use_pal= c->srcFormat == PIX_FMT_PAL8
- || c->srcFormat == PIX_FMT_BGR4_BYTE
- || c->srcFormat == PIX_FMT_RGB4_BYTE
- || c->srcFormat == PIX_FMT_BGR8
- || c->srcFormat == PIX_FMT_RGB8;
if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
@@ -2674,7 +2714,7 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
}
- if (use_pal){
+ if (usePal(c->srcFormat)){
for (i=0; i<256; i++){
int p, r, g, b,y,u,v;
if(c->srcFormat == PIX_FMT_PAL8){
@@ -2702,9 +2742,36 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
- pal[i]= y + (u<<8) + (v<<16);
+ c->pal_yuv[i]= y + (u<<8) + (v<<16);
+
+
+ switch(c->dstFormat) {
+ case PIX_FMT_BGR32:
+#ifndef WORDS_BIGENDIAN
+ case PIX_FMT_RGB24:
+#endif
+ c->pal_rgb[i]= r + (g<<8) + (b<<16);
+ break;
+ case PIX_FMT_BGR32_1:
+#ifdef WORDS_BIGENDIAN
+ case PIX_FMT_BGR24:
+#endif
+ c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8;
+ break;
+ case PIX_FMT_RGB32_1:
+#ifdef WORDS_BIGENDIAN
+ case PIX_FMT_RGB24:
+#endif
+ c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8;
+ break;
+ case PIX_FMT_RGB32:
+#ifndef WORDS_BIGENDIAN
+ case PIX_FMT_BGR24:
+#endif
+ default:
+ c->pal_rgb[i]= b + (g<<8) + (r<<16);
+ }
}
- src2[1]= (uint8_t*)pal;
}
// copy strides, so they can safely be modified
@@ -2722,7 +2789,7 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2]};
src2[0] += (srcSliceH-1)*srcStride[0];
- if (!use_pal)
+ if (!usePal(c->srcFormat))
src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
@@ -3087,8 +3154,8 @@ void sws_freeContext(SwsContext *c){
* asumed to remain valid.
*/
struct SwsContext *sws_getCachedContext(struct SwsContext *context,
- int srcW, int srcH, int srcFormat,
- int dstW, int dstH, int dstFormat, int flags,
+ int srcW, int srcH, enum PixelFormat srcFormat,
+ int dstW, int dstH, enum PixelFormat dstFormat, int flags,
SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)
{
static const double default_param[2] = {SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT};