Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
ef0ee7f6
Commit
ef0ee7f6
authored
Apr 01, 2012
by
Diego Biurrun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
swscale: K&R formatting cosmetics (part II)
Also adjust some comments including wording and typo fixes.
parent
90a43060
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1128 additions
and
920 deletions
+1128
-920
swscale.c
libswscale/swscale.c
+306
-261
swscale_internal.h
libswscale/swscale_internal.h
+4
-4
utils.c
libswscale/utils.c
+818
-655
No files found.
libswscale/swscale.c
View file @
ef0ee7f6
...
...
@@ -18,61 +18,63 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <assert.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include "config.h"
#include <assert.h>
#include "swscale.h"
#include "swscale_internal.h"
#include "rgb2rgb.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/cpu.h"
#include <string.h>
#include "libavutil/avutil.h"
#include "libavutil/mathematics.h"
#include "libavutil/bswap.h"
#include "libavutil/cpu.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "config.h"
#include "rgb2rgb.h"
#include "swscale_internal.h"
#include "swscale.h"
DECLARE_ALIGNED
(
8
,
const
uint8_t
,
dither_8x8_128
)[
8
][
8
]
=
{
{
36
,
68
,
60
,
92
,
34
,
66
,
58
,
90
,},
{
100
,
4
,
124
,
28
,
98
,
2
,
122
,
26
,},
{
52
,
84
,
44
,
76
,
50
,
82
,
42
,
74
,},
{
116
,
20
,
108
,
12
,
114
,
18
,
106
,
10
,},
{
32
,
64
,
56
,
88
,
38
,
70
,
62
,
94
,},
{
96
,
0
,
120
,
24
,
102
,
6
,
126
,
30
,},
{
48
,
80
,
40
,
72
,
54
,
86
,
46
,
78
,},
{
112
,
16
,
104
,
8
,
118
,
22
,
110
,
14
,},
{
36
,
68
,
60
,
92
,
34
,
66
,
58
,
90
,
},
{
100
,
4
,
124
,
28
,
98
,
2
,
122
,
26
,
},
{
52
,
84
,
44
,
76
,
50
,
82
,
42
,
74
,
},
{
116
,
20
,
108
,
12
,
114
,
18
,
106
,
10
,
},
{
32
,
64
,
56
,
88
,
38
,
70
,
62
,
94
,
},
{
96
,
0
,
120
,
24
,
102
,
6
,
126
,
30
,
},
{
48
,
80
,
40
,
72
,
54
,
86
,
46
,
78
,
},
{
112
,
16
,
104
,
8
,
118
,
22
,
110
,
14
,
},
};
DECLARE_ALIGNED
(
8
,
const
uint8_t
,
ff_sws_pb_64
)[
8
]
=
{
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
};
DECLARE_ALIGNED
(
8
,
const
uint8_t
,
ff_sws_pb_64
)[
8
]
=
{
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
};
static
av_always_inline
void
fillPlane
(
uint8_t
*
plane
,
int
stride
,
int
width
,
int
height
,
int
y
,
uint8_t
val
)
static
av_always_inline
void
fillPlane
(
uint8_t
*
plane
,
int
stride
,
int
width
,
int
height
,
int
y
,
uint8_t
val
)
{
int
i
;
uint8_t
*
ptr
=
plane
+
stride
*
y
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
uint8_t
*
ptr
=
plane
+
stride
*
y
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memset
(
ptr
,
val
,
width
);
ptr
+=
stride
;
}
}
static
void
hScale16To19_c
(
SwsContext
*
c
,
int16_t
*
_dst
,
int
dstW
,
const
uint8_t
*
_src
,
const
int16_t
*
filter
,
static
void
hScale16To19_c
(
SwsContext
*
c
,
int16_t
*
_dst
,
int
dstW
,
const
uint8_t
*
_src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
{
int
i
;
int32_t
*
dst
=
(
int32_t
*
)
_dst
;
int32_t
*
dst
=
(
int32_t
*
)
_dst
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
_src
;
int
bits
=
av_pix_fmt_descriptors
[
c
->
srcFormat
].
comp
[
0
].
depth_minus1
;
int
sh
=
bits
-
4
;
int
bits
=
av_pix_fmt_descriptors
[
c
->
srcFormat
].
comp
[
0
].
depth_minus1
;
int
sh
=
bits
-
4
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
src
[
srcPos
+
j
]
*
filter
[
filterSize
*
i
+
j
];
...
...
@@ -82,18 +84,18 @@ static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t
}
}
static
void
hScale16To15_c
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstW
,
const
uint8_t
*
_src
,
const
int16_t
*
filter
,
static
void
hScale16To15_c
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstW
,
const
uint8_t
*
_src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
{
int
i
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
_src
;
int
sh
=
av_pix_fmt_descriptors
[
c
->
srcFormat
].
comp
[
0
].
depth_minus1
;
int
sh
=
av_pix_fmt_descriptors
[
c
->
srcFormat
].
comp
[
0
].
depth_minus1
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
src
[
srcPos
+
j
]
*
filter
[
filterSize
*
i
+
j
];
...
...
@@ -104,72 +106,71 @@ static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t
}
// bilinear / bicubic scaling
static
void
hScale8To15_c
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstW
,
const
uint8_t
*
src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
static
void
hScale8To15_c
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstW
,
const
uint8_t
*
src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
{
int
i
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
((
int
)
src
[
srcPos
+
j
])
*
filter
[
filterSize
*
i
+
j
];
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
((
int
)
src
[
srcPos
+
j
])
*
filter
[
filterSize
*
i
+
j
];
}
//filter += hFilterSize;
dst
[
i
]
=
FFMIN
(
val
>>
7
,
(
1
<<
15
)
-
1
);
// the cubic equation does overflow ...
//dst[i] = val>>7;
dst
[
i
]
=
FFMIN
(
val
>>
7
,
(
1
<<
15
)
-
1
);
// the cubic equation does overflow ...
}
}
static
void
hScale8To19_c
(
SwsContext
*
c
,
int16_t
*
_dst
,
int
dstW
,
const
uint8_t
*
src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
static
void
hScale8To19_c
(
SwsContext
*
c
,
int16_t
*
_dst
,
int
dstW
,
const
uint8_t
*
src
,
const
int16_t
*
filter
,
const
int32_t
*
filterPos
,
int
filterSize
)
{
int
i
;
int32_t
*
dst
=
(
int32_t
*
)
_dst
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
((
int
)
src
[
srcPos
+
j
])
*
filter
[
filterSize
*
i
+
j
];
int
srcPos
=
filterPos
[
i
];
int
val
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
val
+=
((
int
)
src
[
srcPos
+
j
])
*
filter
[
filterSize
*
i
+
j
];
}
//filter += hFilterSize;
dst
[
i
]
=
FFMIN
(
val
>>
3
,
(
1
<<
19
)
-
1
);
// the cubic equation does overflow ...
//dst[i] = val>>7;
dst
[
i
]
=
FFMIN
(
val
>>
3
,
(
1
<<
19
)
-
1
);
// the cubic equation does overflow ...
}
}
//FIXME all pal and rgb srcFormats could do this convertion as well
//FIXME all scalers more complex than bilinear could do half of this transform
//
FIXME all pal and rgb srcFormats could do this convertion as well
//
FIXME all scalers more complex than bilinear could do half of this transform
static
void
chrRangeToJpeg_c
(
int16_t
*
dstU
,
int16_t
*
dstV
,
int
width
)
{
int
i
;
for
(
i
=
0
;
i
<
width
;
i
++
)
{
dstU
[
i
]
=
(
FFMIN
(
dstU
[
i
],
30775
)
*
4663
-
9289992
)
>>
12
;
//
-264
dstV
[
i
]
=
(
FFMIN
(
dstV
[
i
],
30775
)
*
4663
-
9289992
)
>>
12
;
//
-264
dstU
[
i
]
=
(
FFMIN
(
dstU
[
i
],
30775
)
*
4663
-
9289992
)
>>
12
;
//
-264
dstV
[
i
]
=
(
FFMIN
(
dstV
[
i
],
30775
)
*
4663
-
9289992
)
>>
12
;
//
-264
}
}
static
void
chrRangeFromJpeg_c
(
int16_t
*
dstU
,
int16_t
*
dstV
,
int
width
)
{
int
i
;
for
(
i
=
0
;
i
<
width
;
i
++
)
{
dstU
[
i
]
=
(
dstU
[
i
]
*
1799
+
4081085
)
>>
11
;
//
1469
dstV
[
i
]
=
(
dstV
[
i
]
*
1799
+
4081085
)
>>
11
;
//
1469
dstU
[
i
]
=
(
dstU
[
i
]
*
1799
+
4081085
)
>>
11
;
//
1469
dstV
[
i
]
=
(
dstV
[
i
]
*
1799
+
4081085
)
>>
11
;
//
1469
}
}
static
void
lumRangeToJpeg_c
(
int16_t
*
dst
,
int
width
)
{
int
i
;
for
(
i
=
0
;
i
<
width
;
i
++
)
dst
[
i
]
=
(
FFMIN
(
dst
[
i
],
30189
)
*
19077
-
39057361
)
>>
14
;
dst
[
i
]
=
(
FFMIN
(
dst
[
i
],
30189
)
*
19077
-
39057361
)
>>
14
;
}
static
void
lumRangeFromJpeg_c
(
int16_t
*
dst
,
int
width
)
{
int
i
;
for
(
i
=
0
;
i
<
width
;
i
++
)
dst
[
i
]
=
(
dst
[
i
]
*
14071
+
33561947
)
>>
14
;
dst
[
i
]
=
(
dst
[
i
]
*
14071
+
33561947
)
>>
14
;
}
static
void
chrRangeToJpeg16_c
(
int16_t
*
_dstU
,
int16_t
*
_dstV
,
int
width
)
...
...
@@ -178,70 +179,77 @@ static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
int32_t
*
dstU
=
(
int32_t
*
)
_dstU
;
int32_t
*
dstV
=
(
int32_t
*
)
_dstV
;
for
(
i
=
0
;
i
<
width
;
i
++
)
{
dstU
[
i
]
=
(
FFMIN
(
dstU
[
i
],
30775
<<
4
)
*
4663
-
(
9289992
<<
4
))
>>
12
;
//
-264
dstV
[
i
]
=
(
FFMIN
(
dstV
[
i
],
30775
<<
4
)
*
4663
-
(
9289992
<<
4
))
>>
12
;
//
-264
dstU
[
i
]
=
(
FFMIN
(
dstU
[
i
],
30775
<<
4
)
*
4663
-
(
9289992
<<
4
))
>>
12
;
//
-264
dstV
[
i
]
=
(
FFMIN
(
dstV
[
i
],
30775
<<
4
)
*
4663
-
(
9289992
<<
4
))
>>
12
;
//
-264
}
}
static
void
chrRangeFromJpeg16_c
(
int16_t
*
_dstU
,
int16_t
*
_dstV
,
int
width
)
{
int
i
;
int32_t
*
dstU
=
(
int32_t
*
)
_dstU
;
int32_t
*
dstV
=
(
int32_t
*
)
_dstV
;
for
(
i
=
0
;
i
<
width
;
i
++
)
{
dstU
[
i
]
=
(
dstU
[
i
]
*
1799
+
(
4081085
<<
4
))
>>
11
;
//
1469
dstV
[
i
]
=
(
dstV
[
i
]
*
1799
+
(
4081085
<<
4
))
>>
11
;
//
1469
dstU
[
i
]
=
(
dstU
[
i
]
*
1799
+
(
4081085
<<
4
))
>>
11
;
//
1469
dstV
[
i
]
=
(
dstV
[
i
]
*
1799
+
(
4081085
<<
4
))
>>
11
;
//
1469
}
}
static
void
lumRangeToJpeg16_c
(
int16_t
*
_dst
,
int
width
)
{
int
i
;
int32_t
*
dst
=
(
int32_t
*
)
_dst
;
for
(
i
=
0
;
i
<
width
;
i
++
)
dst
[
i
]
=
(
FFMIN
(
dst
[
i
],
30189
<<
4
)
*
4769
-
(
39057361
<<
2
))
>>
12
;
dst
[
i
]
=
(
FFMIN
(
dst
[
i
],
30189
<<
4
)
*
4769
-
(
39057361
<<
2
))
>>
12
;
}
static
void
lumRangeFromJpeg16_c
(
int16_t
*
_dst
,
int
width
)
{
int
i
;
int32_t
*
dst
=
(
int32_t
*
)
_dst
;
for
(
i
=
0
;
i
<
width
;
i
++
)
dst
[
i
]
=
(
dst
[
i
]
*
14071
+
(
33561947
<<
4
))
>>
14
;
dst
[
i
]
=
(
dst
[
i
]
*
14071
+
(
33561947
<<
4
))
>>
14
;
}
static
void
hyscale_fast_c
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstWidth
,
const
uint8_t
*
src
,
int
srcW
,
int
xInc
)
{
int
i
;
unsigned
int
xpos
=
0
;
for
(
i
=
0
;
i
<
dstWidth
;
i
++
)
{
register
unsigned
int
xx
=
xpos
>>
16
;
register
unsigned
int
xalpha
=
(
xpos
&
0xFFFF
)
>>
9
;
dst
[
i
]
=
(
src
[
xx
]
<<
7
)
+
(
src
[
xx
+
1
]
-
src
[
xx
])
*
xalpha
;
xpos
+=
xInc
;
unsigned
int
xpos
=
0
;
for
(
i
=
0
;
i
<
dstWidth
;
i
++
)
{
register
unsigned
int
xx
=
xpos
>>
16
;
register
unsigned
int
xalpha
=
(
xpos
&
0xFFFF
)
>>
9
;
dst
[
i
]
=
(
src
[
xx
]
<<
7
)
+
(
src
[
xx
+
1
]
-
src
[
xx
])
*
xalpha
;
xpos
+=
xInc
;
}
}
// *** horizontal scale Y line to temp buffer
static
av_always_inline
void
hyscale
(
SwsContext
*
c
,
int16_t
*
dst
,
int
dstWidth
,
const
uint8_t
*
src_in
[
4
],
int
srcW
,
int
xInc
,
const
uint8_t
*
src_in
[
4
],
int
srcW
,
int
xInc
,
const
int16_t
*
hLumFilter
,
const
int32_t
*
hLumFilterPos
,
int
hLumFilterSize
,
const
int32_t
*
hLumFilterPos
,
int
hLumFilterSize
,
uint8_t
*
formatConvBuffer
,
uint32_t
*
pal
,
int
isAlpha
)
{
void
(
*
toYV12
)(
uint8_t
*
,
const
uint8_t
*
,
int
,
uint32_t
*
)
=
isAlpha
?
c
->
alpToYV12
:
c
->
lumToYV12
;
void
(
*
toYV12
)(
uint8_t
*
,
const
uint8_t
*
,
int
,
uint32_t
*
)
=
isAlpha
?
c
->
alpToYV12
:
c
->
lumToYV12
;
void
(
*
convertRange
)(
int16_t
*
,
int
)
=
isAlpha
?
NULL
:
c
->
lumConvertRange
;
const
uint8_t
*
src
=
src_in
[
isAlpha
?
3
:
0
];
if
(
toYV12
)
{
toYV12
(
formatConvBuffer
,
src
,
srcW
,
pal
);
src
=
formatConvBuffer
;
src
=
formatConvBuffer
;
}
else
if
(
c
->
readLumPlanar
&&
!
isAlpha
)
{
c
->
readLumPlanar
(
formatConvBuffer
,
src_in
,
srcW
);
src
=
formatConvBuffer
;
}
if
(
!
c
->
hyscale_fast
)
{
c
->
hyScale
(
c
,
dst
,
dstWidth
,
src
,
hLumFilter
,
hLumFilterPos
,
hLumFilterSize
);
c
->
hyScale
(
c
,
dst
,
dstWidth
,
src
,
hLumFilter
,
hLumFilterPos
,
hLumFilterSize
);
}
else
{
// fast bilinear upscale / crap downscale
c
->
hyscale_fast
(
c
,
dst
,
dstWidth
,
src
,
srcW
,
xInc
);
}
...
...
@@ -255,33 +263,38 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
const
uint8_t
*
src2
,
int
srcW
,
int
xInc
)
{
int
i
;
unsigned
int
xpos
=
0
;
for
(
i
=
0
;
i
<
dstWidth
;
i
++
)
{
register
unsigned
int
xx
=
xpos
>>
16
;
register
unsigned
int
xalpha
=
(
xpos
&
0xFFFF
)
>>
9
;
dst1
[
i
]
=
(
src1
[
xx
]
*
(
xalpha
^
127
)
+
src1
[
xx
+
1
]
*
xalpha
);
dst2
[
i
]
=
(
src2
[
xx
]
*
(
xalpha
^
127
)
+
src2
[
xx
+
1
]
*
xalpha
);
xpos
+=
xInc
;
unsigned
int
xpos
=
0
;
for
(
i
=
0
;
i
<
dstWidth
;
i
++
)
{
register
unsigned
int
xx
=
xpos
>>
16
;
register
unsigned
int
xalpha
=
(
xpos
&
0xFFFF
)
>>
9
;
dst1
[
i
]
=
(
src1
[
xx
]
*
(
xalpha
^
127
)
+
src1
[
xx
+
1
]
*
xalpha
);
dst2
[
i
]
=
(
src2
[
xx
]
*
(
xalpha
^
127
)
+
src2
[
xx
+
1
]
*
xalpha
);
xpos
+=
xInc
;
}
}
static
av_always_inline
void
hcscale
(
SwsContext
*
c
,
int16_t
*
dst1
,
int16_t
*
dst2
,
int
dstWidth
,
static
av_always_inline
void
hcscale
(
SwsContext
*
c
,
int16_t
*
dst1
,
int16_t
*
dst2
,
int
dstWidth
,
const
uint8_t
*
src_in
[
4
],
int
srcW
,
int
xInc
,
const
int16_t
*
hChrFilter
,
const
int32_t
*
hChrFilterPos
,
int
hChrFilterSize
,
int
srcW
,
int
xInc
,
const
int16_t
*
hChrFilter
,
const
int32_t
*
hChrFilterPos
,
int
hChrFilterSize
,
uint8_t
*
formatConvBuffer
,
uint32_t
*
pal
)
{
const
uint8_t
*
src1
=
src_in
[
1
],
*
src2
=
src_in
[
2
];
if
(
c
->
chrToYV12
)
{
uint8_t
*
buf2
=
formatConvBuffer
+
FFALIGN
(
srcW
*
FFALIGN
(
c
->
srcBpc
,
8
)
>>
3
,
16
);
uint8_t
*
buf2
=
formatConvBuffer
+
FFALIGN
(
srcW
*
FFALIGN
(
c
->
srcBpc
,
8
)
>>
3
,
16
);
c
->
chrToYV12
(
formatConvBuffer
,
buf2
,
src1
,
src2
,
srcW
,
pal
);
src1
=
formatConvBuffer
;
src2
=
buf2
;
src1
=
formatConvBuffer
;
src2
=
buf2
;
}
else
if
(
c
->
readChrPlanar
)
{
uint8_t
*
buf2
=
formatConvBuffer
+
FFALIGN
(
srcW
*
FFALIGN
(
c
->
srcBpc
,
8
)
>>
3
,
16
);
uint8_t
*
buf2
=
formatConvBuffer
+
FFALIGN
(
srcW
*
FFALIGN
(
c
->
srcBpc
,
8
)
>>
3
,
16
);
c
->
readChrPlanar
(
formatConvBuffer
,
buf2
,
src_in
,
srcW
);
src1
=
formatConvBuffer
;
src2
=
buf2
;
src1
=
formatConvBuffer
;
src2
=
buf2
;
}
if
(
!
c
->
hcscale_fast
)
{
...
...
@@ -296,120 +309,130 @@ static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2
}
#define DEBUG_SWSCALE_BUFFERS 0
#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
#define DEBUG_BUFFERS(...) \
if (DEBUG_SWSCALE_BUFFERS) \
av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
static
int
swScale
(
SwsContext
*
c
,
const
uint8_t
*
src
[],
static
int
swScale
(
SwsContext
*
c
,
const
uint8_t
*
src
[],
int
srcStride
[],
int
srcSliceY
,
int
srcSliceH
,
uint8_t
*
dst
[],
int
dstStride
[])
int
srcSliceH
,
uint8_t
*
dst
[],
int
dstStride
[])
{
/* load a few things into local vars to make the code more readable? and faster */
const
int
srcW
=
c
->
srcW
;
const
int
dstW
=
c
->
dstW
;
const
int
dstH
=
c
->
dstH
;
const
int
chrDstW
=
c
->
chrDstW
;
const
int
chrSrcW
=
c
->
chrSrcW
;
const
int
lumXInc
=
c
->
lumXInc
;
const
int
chrXInc
=
c
->
chrXInc
;
const
enum
PixelFormat
dstFormat
=
c
->
dstFormat
;
const
int
flags
=
c
->
flags
;
int32_t
*
vLumFilterPos
=
c
->
vLumFilterPos
;
int32_t
*
vChrFilterPos
=
c
->
vChrFilterPos
;
int32_t
*
hLumFilterPos
=
c
->
hLumFilterPos
;
int32_t
*
hChrFilterPos
=
c
->
hChrFilterPos
;
int16_t
*
vLumFilter
=
c
->
vLumFilter
;
int16_t
*
vChrFilter
=
c
->
vChrFilter
;
int16_t
*
hLumFilter
=
c
->
hLumFilter
;
int16_t
*
hChrFilter
=
c
->
hChrFilter
;
int32_t
*
lumMmxFilter
=
c
->
lumMmxFilter
;
int32_t
*
chrMmxFilter
=
c
->
chrMmxFilter
;
const
int
vLumFilterSize
=
c
->
vLumFilterSize
;
const
int
vChrFilterSize
=
c
->
vChrFilterSize
;
const
int
hLumFilterSize
=
c
->
hLumFilterSize
;
const
int
hChrFilterSize
=
c
->
hChrFilterSize
;
int16_t
**
lumPixBuf
=
c
->
lumPixBuf
;
int16_t
**
chrUPixBuf
=
c
->
chrUPixBuf
;
int16_t
**
chrVPixBuf
=
c
->
chrVPixBuf
;
int16_t
**
alpPixBuf
=
c
->
alpPixBuf
;
const
int
vLumBufSize
=
c
->
vLumBufSize
;
const
int
vChrBufSize
=
c
->
vChrBufSize
;
uint8_t
*
formatConvBuffer
=
c
->
formatConvBuffer
;
const
int
chrSrcSliceY
=
srcSliceY
>>
c
->
chrSrcVSubSample
;
const
int
chrSrcSliceH
=
-
((
-
srcSliceH
)
>>
c
->
chrSrcVSubSample
);
/* load a few things into local vars to make the code more readable?
* and faster */
const
int
srcW
=
c
->
srcW
;
const
int
dstW
=
c
->
dstW
;
const
int
dstH
=
c
->
dstH
;
const
int
chrDstW
=
c
->
chrDstW
;
const
int
chrSrcW
=
c
->
chrSrcW
;
const
int
lumXInc
=
c
->
lumXInc
;
const
int
chrXInc
=
c
->
chrXInc
;
const
enum
PixelFormat
dstFormat
=
c
->
dstFormat
;
const
int
flags
=
c
->
flags
;
int32_t
*
vLumFilterPos
=
c
->
vLumFilterPos
;
int32_t
*
vChrFilterPos
=
c
->
vChrFilterPos
;
int32_t
*
hLumFilterPos
=
c
->
hLumFilterPos
;
int32_t
*
hChrFilterPos
=
c
->
hChrFilterPos
;
int16_t
*
vLumFilter
=
c
->
vLumFilter
;
int16_t
*
vChrFilter
=
c
->
vChrFilter
;
int16_t
*
hLumFilter
=
c
->
hLumFilter
;
int16_t
*
hChrFilter
=
c
->
hChrFilter
;
int32_t
*
lumMmxFilter
=
c
->
lumMmxFilter
;
int32_t
*
chrMmxFilter
=
c
->
chrMmxFilter
;
const
int
vLumFilterSize
=
c
->
vLumFilterSize
;
const
int
vChrFilterSize
=
c
->
vChrFilterSize
;
const
int
hLumFilterSize
=
c
->
hLumFilterSize
;
const
int
hChrFilterSize
=
c
->
hChrFilterSize
;
int16_t
**
lumPixBuf
=
c
->
lumPixBuf
;
int16_t
**
chrUPixBuf
=
c
->
chrUPixBuf
;
int16_t
**
chrVPixBuf
=
c
->
chrVPixBuf
;
int16_t
**
alpPixBuf
=
c
->
alpPixBuf
;
const
int
vLumBufSize
=
c
->
vLumBufSize
;
const
int
vChrBufSize
=
c
->
vChrBufSize
;
uint8_t
*
formatConvBuffer
=
c
->
formatConvBuffer
;
uint32_t
*
pal
=
c
->
pal_yuv
;
yuv2planar1_fn
yuv2plane1
=
c
->
yuv2plane1
;
yuv2planarX_fn
yuv2planeX
=
c
->
yuv2planeX
;
yuv2interleavedX_fn
yuv2nv12cX
=
c
->
yuv2nv12cX
;
yuv2packed1_fn
yuv2packed1
=
c
->
yuv2packed1
;
yuv2packed2_fn
yuv2packed2
=
c
->
yuv2packed2
;
yuv2packedX_fn
yuv2packedX
=
c
->
yuv2packedX
;
const
int
chrSrcSliceY
=
srcSliceY
>>
c
->
chrSrcVSubSample
;
const
int
chrSrcSliceH
=
-
((
-
srcSliceH
)
>>
c
->
chrSrcVSubSample
);
int
should_dither
=
is9_OR_10BPS
(
c
->
srcFormat
)
||
is16BPS
(
c
->
srcFormat
);
int
lastDstY
;
uint32_t
*
pal
=
c
->
pal_yuv
;
yuv2planar1_fn
yuv2plane1
=
c
->
yuv2plane1
;
yuv2planarX_fn
yuv2planeX
=
c
->
yuv2planeX
;
yuv2interleavedX_fn
yuv2nv12cX
=
c
->
yuv2nv12cX
;
yuv2packed1_fn
yuv2packed1
=
c
->
yuv2packed1
;
yuv2packed2_fn
yuv2packed2
=
c
->
yuv2packed2
;
yuv2packedX_fn
yuv2packedX
=
c
->
yuv2packedX
;
int
should_dither
=
is9_OR_10BPS
(
c
->
srcFormat
)
||
is16BPS
(
c
->
srcFormat
);
/* vars which will change and which we need to store back in the context */
int
dstY
=
c
->
dstY
;
int
lumBufIndex
=
c
->
lumBufIndex
;
int
chrBufIndex
=
c
->
chrBufIndex
;
int
lastInLumBuf
=
c
->
lastInLumBuf
;
int
lastInChrBuf
=
c
->
lastInChrBuf
;
int
dstY
=
c
->
dstY
;
int
lumBufIndex
=
c
->
lumBufIndex
;
int
chrBufIndex
=
c
->
chrBufIndex
;
int
lastInLumBuf
=
c
->
lastInLumBuf
;
int
lastInChrBuf
=
c
->
lastInChrBuf
;
if
(
isPacked
(
c
->
srcFormat
))
{
src
[
0
]
=
src
[
1
]
=
src
[
2
]
=
src
[
3
]
=
src
[
0
];
srcStride
[
0
]
=
srcStride
[
1
]
=
srcStride
[
2
]
=
srcStride
[
3
]
=
srcStride
[
0
];
src
[
0
]
=
src
[
1
]
=
src
[
2
]
=
src
[
3
]
=
src
[
0
];
srcStride
[
0
]
=
srcStride
[
1
]
=
srcStride
[
2
]
=
srcStride
[
3
]
=
srcStride
[
0
];
}
srcStride
[
1
]
<<=
c
->
vChrDrop
;
srcStride
[
2
]
<<=
c
->
vChrDrop
;
srcStride
[
1
]
<<=
c
->
vChrDrop
;
srcStride
[
2
]
<<=
c
->
vChrDrop
;
DEBUG_BUFFERS
(
"swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]
\n
"
,
src
[
0
],
srcStride
[
0
],
src
[
1
],
srcStride
[
1
],
src
[
2
],
srcStride
[
2
],
src
[
3
],
srcStride
[
3
],
dst
[
0
],
dstStride
[
0
],
dst
[
1
],
dstStride
[
1
],
dst
[
2
],
dstStride
[
2
],
dst
[
3
],
dstStride
[
3
]);
src
[
0
],
srcStride
[
0
],
src
[
1
],
srcStride
[
1
],
src
[
2
],
srcStride
[
2
],
src
[
3
],
srcStride
[
3
],
dst
[
0
],
dstStride
[
0
],
dst
[
1
],
dstStride
[
1
],
dst
[
2
],
dstStride
[
2
],
dst
[
3
],
dstStride
[
3
]);
DEBUG_BUFFERS
(
"srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d
\n
"
,
srcSliceY
,
srcSliceH
,
dstY
,
dstH
);
srcSliceY
,
srcSliceH
,
dstY
,
dstH
);
DEBUG_BUFFERS
(
"vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d
\n
"
,
vLumFilterSize
,
vLumBufSize
,
vChrFilterSize
,
vChrBufSize
);
vLumFilterSize
,
vLumBufSize
,
vChrFilterSize
,
vChrBufSize
);
if
(
dstStride
[
0
]
%
8
!=
0
||
dstStride
[
1
]
%
8
!=
0
||
dstStride
[
2
]
%
8
!=
0
||
dstStride
[
3
]
%
8
!=
0
)
{
static
int
warnedAlready
=
0
;
//FIXME move this into the context perhaps
if
(
dstStride
[
0
]
%
8
!=
0
||
dstStride
[
1
]
%
8
!=
0
||
dstStride
[
2
]
%
8
!=
0
||
dstStride
[
3
]
%
8
!=
0
)
{
static
int
warnedAlready
=
0
;
// FIXME maybe move this into the context
if
(
flags
&
SWS_PRINT_INFO
&&
!
warnedAlready
)
{
av_log
(
c
,
AV_LOG_WARNING
,
"Warning: dstStride is not aligned!
\n
"
av_log
(
c
,
AV_LOG_WARNING
,
"Warning: dstStride is not aligned!
\n
"
" ->cannot do aligned memory accesses anymore
\n
"
);
warnedAlready
=
1
;
warnedAlready
=
1
;
}
}
/* Note the user might start scaling the picture in the middle so this
will not get executed. This is not really intended but works
currently, so people might do it. */
if
(
srcSliceY
==
0
)
{
lumBufIndex
=
-
1
;
chrBufIndex
=
-
1
;
dstY
=
0
;
lastInLumBuf
=
-
1
;
lastInChrBuf
=
-
1
;
*
will not get executed. This is not really intended but works
*
currently, so people might do it. */
if
(
srcSliceY
==
0
)
{
lumBufIndex
=
-
1
;
chrBufIndex
=
-
1
;
dstY
=
0
;
lastInLumBuf
=
-
1
;
lastInChrBuf
=
-
1
;
}
if
(
!
should_dither
)
{
c
->
chrDither8
=
c
->
lumDither8
=
ff_sws_pb_64
;
}
lastDstY
=
dstY
;
lastDstY
=
dstY
;
for
(;
dstY
<
dstH
;
dstY
++
)
{
const
int
chrDstY
=
dstY
>>
c
->
chrDstVSubSample
;
uint8_t
*
dest
[
4
]
=
{
for
(;
dstY
<
dstH
;
dstY
++
)
{
const
int
chrDstY
=
dstY
>>
c
->
chrDstVSubSample
;
uint8_t
*
dest
[
4
]
=
{
dst
[
0
]
+
dstStride
[
0
]
*
dstY
,
dst
[
1
]
+
dstStride
[
1
]
*
chrDstY
,
dst
[
2
]
+
dstStride
[
2
]
*
chrDstY
,
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
?
dst
[
3
]
+
dstStride
[
3
]
*
dstY
:
NULL
,
};
const
int
firstLumSrcY
=
FFMAX
(
1
-
vLumFilterSize
,
vLumFilterPos
[
dstY
]);
//First line needed as input
const
int
firstLumSrcY2
=
FFMAX
(
1
-
vLumFilterSize
,
vLumFilterPos
[
FFMIN
(
dstY
|
((
1
<<
c
->
chrDstVSubSample
)
-
1
),
dstH
-
1
)]);
const
int
firstChrSrcY
=
FFMAX
(
1
-
vChrFilterSize
,
vChrFilterPos
[
chrDstY
]);
//First line needed as input
// First line needed as input
const
int
firstLumSrcY
=
FFMAX
(
1
-
vLumFilterSize
,
vLumFilterPos
[
dstY
]);
const
int
firstLumSrcY2
=
FFMAX
(
1
-
vLumFilterSize
,
vLumFilterPos
[
FFMIN
(
dstY
|
((
1
<<
c
->
chrDstVSubSample
)
-
1
),
dstH
-
1
)]);
// First line needed as input
const
int
firstChrSrcY
=
FFMAX
(
1
-
vChrFilterSize
,
vChrFilterPos
[
chrDstY
]);
// Last line needed as input
int
lastLumSrcY
=
FFMIN
(
c
->
srcH
,
firstLumSrcY
+
vLumFilterSize
)
-
1
;
...
...
@@ -417,30 +440,33 @@ static int swScale(SwsContext *c, const uint8_t* src[],
int
lastChrSrcY
=
FFMIN
(
c
->
chrSrcH
,
firstChrSrcY
+
vChrFilterSize
)
-
1
;
int
enough_lines
;
//handle holes (FAST_BILINEAR & weird filters)
if
(
firstLumSrcY
>
lastInLumBuf
)
lastInLumBuf
=
firstLumSrcY
-
1
;
if
(
firstChrSrcY
>
lastInChrBuf
)
lastInChrBuf
=
firstChrSrcY
-
1
;
// handle holes (FAST_BILINEAR & weird filters)
if
(
firstLumSrcY
>
lastInLumBuf
)
lastInLumBuf
=
firstLumSrcY
-
1
;
if
(
firstChrSrcY
>
lastInChrBuf
)
lastInChrBuf
=
firstChrSrcY
-
1
;
assert
(
firstLumSrcY
>=
lastInLumBuf
-
vLumBufSize
+
1
);
assert
(
firstChrSrcY
>=
lastInChrBuf
-
vChrBufSize
+
1
);
DEBUG_BUFFERS
(
"dstY: %d
\n
"
,
dstY
);
DEBUG_BUFFERS
(
"
\t
firstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d
\n
"
,
firstLumSrcY
,
lastLumSrcY
,
lastInLumBuf
);
firstLumSrcY
,
lastLumSrcY
,
lastInLumBuf
);
DEBUG_BUFFERS
(
"
\t
firstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d
\n
"
,
firstChrSrcY
,
lastChrSrcY
,
lastInChrBuf
);
firstChrSrcY
,
lastChrSrcY
,
lastInChrBuf
);
// Do we have enough lines in this slice to output the dstY line
enough_lines
=
lastLumSrcY2
<
srcSliceY
+
srcSliceH
&&
lastChrSrcY
<
-
((
-
srcSliceY
-
srcSliceH
)
>>
c
->
chrSrcVSubSample
);
enough_lines
=
lastLumSrcY2
<
srcSliceY
+
srcSliceH
&&
lastChrSrcY
<
-
((
-
srcSliceY
-
srcSliceH
)
>>
c
->
chrSrcVSubSample
);
if
(
!
enough_lines
)
{
lastLumSrcY
=
srcSliceY
+
srcSliceH
-
1
;
lastChrSrcY
=
chrSrcSliceY
+
chrSrcSliceH
-
1
;
DEBUG_BUFFERS
(
"buffering slice: lastLumSrcY %d lastChrSrcY %d
\n
"
,
lastLumSrcY
,
lastChrSrcY
);
lastLumSrcY
,
lastChrSrcY
);
}
//Do horizontal scaling
while
(
lastInLumBuf
<
lastLumSrcY
)
{
//
Do horizontal scaling
while
(
lastInLumBuf
<
lastLumSrcY
)
{
const
uint8_t
*
src1
[
4
]
=
{
src
[
0
]
+
(
lastInLumBuf
+
1
-
srcSliceY
)
*
srcStride
[
0
],
src
[
1
]
+
(
lastInLumBuf
+
1
-
srcSliceY
)
*
srcStride
[
1
],
...
...
@@ -448,23 +474,21 @@ static int swScale(SwsContext *c, const uint8_t* src[],
src
[
3
]
+
(
lastInLumBuf
+
1
-
srcSliceY
)
*
srcStride
[
3
],
};
lumBufIndex
++
;
assert
(
lumBufIndex
<
2
*
vLumBufSize
);
assert
(
lumBufIndex
<
2
*
vLumBufSize
);
assert
(
lastInLumBuf
+
1
-
srcSliceY
<
srcSliceH
);
assert
(
lastInLumBuf
+
1
-
srcSliceY
>=
0
);
hyscale
(
c
,
lumPixBuf
[
lumBufIndex
],
dstW
,
src1
,
srcW
,
lumXInc
,
hyscale
(
c
,
lumPixBuf
[
lumBufIndex
],
dstW
,
src1
,
srcW
,
lumXInc
,
hLumFilter
,
hLumFilterPos
,
hLumFilterSize
,
formatConvBuffer
,
pal
,
0
);
formatConvBuffer
,
pal
,
0
);
if
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
hyscale
(
c
,
alpPixBuf
[
lumBufIndex
],
dstW
,
src1
,
srcW
,
hyscale
(
c
,
alpPixBuf
[
lumBufIndex
],
dstW
,
src1
,
srcW
,
lumXInc
,
hLumFilter
,
hLumFilterPos
,
hLumFilterSize
,
formatConvBuffer
,
pal
,
1
);
formatConvBuffer
,
pal
,
1
);
lastInLumBuf
++
;
DEBUG_BUFFERS
(
"
\t\t
lumBufIndex %d: lastInLumBuf: %d
\n
"
,
lumBufIndex
,
lastInLumBuf
);
lumBufIndex
,
lastInLumBuf
);
}
while
(
lastInChrBuf
<
lastChrSrcY
)
{
while
(
lastInChrBuf
<
lastChrSrcY
)
{
const
uint8_t
*
src1
[
4
]
=
{
src
[
0
]
+
(
lastInChrBuf
+
1
-
chrSrcSliceY
)
*
srcStride
[
0
],
src
[
1
]
+
(
lastInChrBuf
+
1
-
chrSrcSliceY
)
*
srcStride
[
1
],
...
...
@@ -472,80 +496,90 @@ static int swScale(SwsContext *c, const uint8_t* src[],
src
[
3
]
+
(
lastInChrBuf
+
1
-
chrSrcSliceY
)
*
srcStride
[
3
],
};
chrBufIndex
++
;
assert
(
chrBufIndex
<
2
*
vChrBufSize
);
assert
(
chrBufIndex
<
2
*
vChrBufSize
);
assert
(
lastInChrBuf
+
1
-
chrSrcSliceY
<
(
chrSrcSliceH
));
assert
(
lastInChrBuf
+
1
-
chrSrcSliceY
>=
0
);
//FIXME replace parameters through context struct (some at least)
//
FIXME replace parameters through context struct (some at least)
if
(
c
->
needs_hcscale
)
hcscale
(
c
,
chrUPixBuf
[
chrBufIndex
],
chrVPixBuf
[
chrBufIndex
],
chrDstW
,
src1
,
chrSrcW
,
chrXInc
,
hChrFilter
,
hChrFilterPos
,
hChrFilterSize
,
formatConvBuffer
,
pal
);
chrDstW
,
src1
,
chrSrcW
,
chrXInc
,
hChrFilter
,
hChrFilterPos
,
hChrFilterSize
,
formatConvBuffer
,
pal
);
lastInChrBuf
++
;
DEBUG_BUFFERS
(
"
\t\t
chrBufIndex %d: lastInChrBuf: %d
\n
"
,
chrBufIndex
,
lastInChrBuf
);
chrBufIndex
,
lastInChrBuf
);
}
//wrap buf index around to stay inside the ring buffer
if
(
lumBufIndex
>=
vLumBufSize
)
lumBufIndex
-=
vLumBufSize
;
if
(
chrBufIndex
>=
vChrBufSize
)
chrBufIndex
-=
vChrBufSize
;
// wrap buf index around to stay inside the ring buffer
if
(
lumBufIndex
>=
vLumBufSize
)
lumBufIndex
-=
vLumBufSize
;
if
(
chrBufIndex
>=
vChrBufSize
)
chrBufIndex
-=
vChrBufSize
;
if
(
!
enough_lines
)
break
;
//
we can't output a dstY line so let's try with the next slice
break
;
//
we can't output a dstY line so let's try with the next slice
#if HAVE_MMX
updateMMXDitherTables
(
c
,
dstY
,
lumBufIndex
,
chrBufIndex
,
lastInLumBuf
,
lastInChrBuf
);
updateMMXDitherTables
(
c
,
dstY
,
lumBufIndex
,
chrBufIndex
,
lastInLumBuf
,
lastInChrBuf
);
#endif
if
(
should_dither
)
{
c
->
chrDither8
=
dither_8x8_128
[
chrDstY
&
7
];
c
->
lumDither8
=
dither_8x8_128
[
dstY
&
7
];
c
->
lumDither8
=
dither_8x8_128
[
dstY
&
7
];
}
if
(
dstY
>=
dstH
-
2
)
{
// hmm looks like we can't use MMX here without overwriting this array's tail
ff_sws_init_output_funcs
(
c
,
&
yuv2plane1
,
&
yuv2planeX
,
&
yuv2nv12cX
,
if
(
dstY
>=
dstH
-
2
)
{
/* hmm looks like we can't use MMX here without overwriting
* this array's tail */
ff_sws_init_output_funcs
(
c
,
&
yuv2plane1
,
&
yuv2planeX
,
&
yuv2nv12cX
,
&
yuv2packed1
,
&
yuv2packed2
,
&
yuv2packedX
);
}
{
const
int16_t
**
lumSrcPtr
=
(
const
int16_t
**
)
lumPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
;
const
int16_t
**
chrUSrcPtr
=
(
const
int16_t
**
)
chrUPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
chrVSrcPtr
=
(
const
int16_t
**
)
chrVPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
alpSrcPtr
=
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
?
(
const
int16_t
**
)
alpPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
:
NULL
;
const
int16_t
**
lumSrcPtr
=
(
const
int16_t
**
)
lumPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
;
const
int16_t
**
chrUSrcPtr
=
(
const
int16_t
**
)
chrUPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
chrVSrcPtr
=
(
const
int16_t
**
)
chrVPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
alpSrcPtr
=
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
?
(
const
int16_t
**
)
alpPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
:
NULL
;
if
(
firstLumSrcY
<
0
||
firstLumSrcY
+
vLumFilterSize
>
c
->
srcH
)
{
const
int16_t
**
tmpY
=
(
const
int16_t
**
)
lumPixBuf
+
2
*
vLumBufSize
;
int
neg
=
-
firstLumSrcY
,
i
,
end
=
FFMIN
(
c
->
srcH
-
firstLumSrcY
,
vLumFilterSize
);
for
(
i
=
0
;
i
<
neg
;
i
++
)
const
int16_t
**
tmpY
=
(
const
int16_t
**
)
lumPixBuf
+
2
*
vLumBufSize
;
int
neg
=
-
firstLumSrcY
,
i
;
int
end
=
FFMIN
(
c
->
srcH
-
firstLumSrcY
,
vLumFilterSize
);
for
(
i
=
0
;
i
<
neg
;
i
++
)
tmpY
[
i
]
=
lumSrcPtr
[
neg
];
for
(
;
i
<
end
;
i
++
)
for
(
;
i
<
end
;
i
++
)
tmpY
[
i
]
=
lumSrcPtr
[
i
];
for
(
;
i
<
vLumFilterSize
;
i
++
)
tmpY
[
i
]
=
tmpY
[
i
-
1
];
for
(;
i
<
vLumFilterSize
;
i
++
)
tmpY
[
i
]
=
tmpY
[
i
-
1
];
lumSrcPtr
=
tmpY
;
if
(
alpSrcPtr
)
{
const
int16_t
**
tmpA
=
(
const
int16_t
**
)
alpPixBuf
+
2
*
vLumBufSize
;
for
(
i
=
0
;
i
<
neg
;
i
++
)
const
int16_t
**
tmpA
=
(
const
int16_t
**
)
alpPixBuf
+
2
*
vLumBufSize
;
for
(
i
=
0
;
i
<
neg
;
i
++
)
tmpA
[
i
]
=
alpSrcPtr
[
neg
];
for
(
;
i
<
end
;
i
++
)
for
(
;
i
<
end
;
i
++
)
tmpA
[
i
]
=
alpSrcPtr
[
i
];
for
(
;
i
<
vLumFilterSize
;
i
++
)
for
(;
i
<
vLumFilterSize
;
i
++
)
tmpA
[
i
]
=
tmpA
[
i
-
1
];
alpSrcPtr
=
tmpA
;
}
}
if
(
firstChrSrcY
<
0
||
firstChrSrcY
+
vChrFilterSize
>
c
->
chrSrcH
)
{
const
int16_t
**
tmpU
=
(
const
int16_t
**
)
chrUPixBuf
+
2
*
vChrBufSize
,
**
tmpV
=
(
const
int16_t
**
)
chrVPixBuf
+
2
*
vChrBufSize
;
int
neg
=
-
firstChrSrcY
,
i
,
end
=
FFMIN
(
c
->
chrSrcH
-
firstChrSrcY
,
vChrFilterSize
);
for
(
i
=
0
;
i
<
neg
;
i
++
)
{
if
(
firstChrSrcY
<
0
||
firstChrSrcY
+
vChrFilterSize
>
c
->
chrSrcH
)
{
const
int16_t
**
tmpU
=
(
const
int16_t
**
)
chrUPixBuf
+
2
*
vChrBufSize
,
**
tmpV
=
(
const
int16_t
**
)
chrVPixBuf
+
2
*
vChrBufSize
;
int
neg
=
-
firstChrSrcY
,
i
;
int
end
=
FFMIN
(
c
->
chrSrcH
-
firstChrSrcY
,
vChrFilterSize
);
for
(
i
=
0
;
i
<
neg
;
i
++
)
{
tmpU
[
i
]
=
chrUSrcPtr
[
neg
];
tmpV
[
i
]
=
chrVSrcPtr
[
neg
];
}
for
(
;
i
<
end
;
i
++
)
{
for
(
;
i
<
end
;
i
++
)
{
tmpU
[
i
]
=
chrUSrcPtr
[
i
];
tmpV
[
i
]
=
chrVSrcPtr
[
i
];
}
for
(
;
i
<
vChrFilterSize
;
i
++
)
{
for
(;
i
<
vChrFilterSize
;
i
++
)
{
tmpU
[
i
]
=
tmpU
[
i
-
1
];
tmpV
[
i
]
=
tmpV
[
i
-
1
];
}
...
...
@@ -553,57 +587,67 @@ static int swScale(SwsContext *c, const uint8_t* src[],
chrVSrcPtr
=
tmpV
;
}
if
(
isPlanarYUV
(
dstFormat
)
||
(
isGray
(
dstFormat
)
&&
!
isALPHA
(
dstFormat
)))
{
//YV12 like
const
int
chrSkipMask
=
(
1
<<
c
->
chrDstVSubSample
)
-
1
;
if
(
isPlanarYUV
(
dstFormat
)
||
(
isGray
(
dstFormat
)
&&
!
isALPHA
(
dstFormat
)))
{
// YV12 like
const
int
chrSkipMask
=
(
1
<<
c
->
chrDstVSubSample
)
-
1
;
if
(
vLumFilterSize
==
1
)
{
yuv2plane1
(
lumSrcPtr
[
0
],
dest
[
0
],
dstW
,
c
->
lumDither8
,
0
);
}
else
{
yuv2planeX
(
vLumFilter
+
dstY
*
vLumFilterSize
,
vLumFilterSize
,
lumSrcPtr
,
dest
[
0
],
dstW
,
c
->
lumDither8
,
0
);
yuv2planeX
(
vLumFilter
+
dstY
*
vLumFilterSize
,
vLumFilterSize
,
lumSrcPtr
,
dest
[
0
],
dstW
,
c
->
lumDither8
,
0
);
}
if
(
!
((
dstY
&
chrSkipMask
)
||
isGray
(
dstFormat
)))
{
if
(
!
((
dstY
&
chrSkipMask
)
||
isGray
(
dstFormat
)))
{
if
(
yuv2nv12cX
)
{
yuv2nv12cX
(
c
,
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrUSrcPtr
,
chrVSrcPtr
,
dest
[
1
],
chrDstW
);
yuv2nv12cX
(
c
,
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrUSrcPtr
,
chrVSrcPtr
,
dest
[
1
],
chrDstW
);
}
else
if
(
vChrFilterSize
==
1
)
{
yuv2plane1
(
chrUSrcPtr
[
0
],
dest
[
1
],
chrDstW
,
c
->
chrDither8
,
0
);
yuv2plane1
(
chrVSrcPtr
[
0
],
dest
[
2
],
chrDstW
,
c
->
chrDither8
,
3
);
}
else
{
yuv2planeX
(
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrUSrcPtr
,
dest
[
1
],
chrDstW
,
c
->
chrDither8
,
0
);
yuv2planeX
(
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrVSrcPtr
,
dest
[
2
],
chrDstW
,
c
->
chrDither8
,
3
);
yuv2planeX
(
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrUSrcPtr
,
dest
[
1
],
chrDstW
,
c
->
chrDither8
,
0
);
yuv2planeX
(
vChrFilter
+
chrDstY
*
vChrFilterSize
,
vChrFilterSize
,
chrVSrcPtr
,
dest
[
2
],
chrDstW
,
c
->
chrDither8
,
3
);
}
}
if
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
){
if
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
{
if
(
vLumFilterSize
==
1
)
{
yuv2plane1
(
alpSrcPtr
[
0
],
dest
[
3
],
dstW
,
c
->
lumDither8
,
0
);
yuv2plane1
(
alpSrcPtr
[
0
],
dest
[
3
],
dstW
,
c
->
lumDither8
,
0
);
}
else
{
yuv2planeX
(
vLumFilter
+
dstY
*
vLumFilterSize
,
vLumFilterSize
,
alpSrcPtr
,
dest
[
3
],
dstW
,
c
->
lumDither8
,
0
);
yuv2planeX
(
vLumFilter
+
dstY
*
vLumFilterSize
,
vLumFilterSize
,
alpSrcPtr
,
dest
[
3
],
dstW
,
c
->
lumDither8
,
0
);
}
}
}
else
{
assert
(
lumSrcPtr
+
vLumFilterSize
-
1
<
lumPixBuf
+
vLumBufSize
*
2
);
assert
(
chrUSrcPtr
+
vChrFilterSize
-
1
<
chrUPixBuf
+
vChrBufSize
*
2
);
if
(
c
->
yuv2packed1
&&
vLumFilterSize
==
1
&&
vChrFilterSize
<=
2
)
{
//unscaled RGB
assert
(
lumSrcPtr
+
vLumFilterSize
-
1
<
lumPixBuf
+
vLumBufSize
*
2
);
assert
(
chrUSrcPtr
+
vChrFilterSize
-
1
<
chrUPixBuf
+
vChrBufSize
*
2
);
if
(
c
->
yuv2packed1
&&
vLumFilterSize
==
1
&&
vChrFilterSize
<=
2
)
{
// unscaled RGB
int
chrAlpha
=
vChrFilterSize
==
1
?
0
:
vChrFilter
[
2
*
dstY
+
1
];
yuv2packed1
(
c
,
*
lumSrcPtr
,
chrUSrcPtr
,
chrVSrcPtr
,
alpPixBuf
?
*
alpSrcPtr
:
NULL
,
dest
[
0
],
dstW
,
chrAlpha
,
dstY
);
}
else
if
(
c
->
yuv2packed2
&&
vLumFilterSize
==
2
&&
vChrFilterSize
==
2
)
{
//bilinear upscale RGB
}
else
if
(
c
->
yuv2packed2
&&
vLumFilterSize
==
2
&&
vChrFilterSize
==
2
)
{
// bilinear upscale RGB
int
lumAlpha
=
vLumFilter
[
2
*
dstY
+
1
];
int
chrAlpha
=
vChrFilter
[
2
*
dstY
+
1
];
lumMmxFilter
[
2
]
=
lumMmxFilter
[
3
]
=
vLumFilter
[
2
*
dstY
]
*
0x10001
;
lumMmxFilter
[
3
]
=
vLumFilter
[
2
*
dstY
]
*
0x10001
;
chrMmxFilter
[
2
]
=
chrMmxFilter
[
3
]
=
vChrFilter
[
2
*
chrDstY
]
*
0x10001
;
yuv2packed2
(
c
,
lumSrcPtr
,
chrUSrcPtr
,
chrVSrcPtr
,
alpPixBuf
?
alpSrcPtr
:
NULL
,
dest
[
0
],
dstW
,
lumAlpha
,
chrAlpha
,
dstY
);
}
else
{
//general RGB
}
else
{
//
general RGB
yuv2packedX
(
c
,
vLumFilter
+
dstY
*
vLumFilterSize
,
lumSrcPtr
,
vLumFilterSize
,
vChrFilter
+
dstY
*
vChrFilterSize
,
...
...
@@ -615,20 +659,20 @@ static int swScale(SwsContext *c, const uint8_t* src[],
}
if
(
isPlanar
(
dstFormat
)
&&
isALPHA
(
dstFormat
)
&&
!
alpPixBuf
)
fillPlane
(
dst
[
3
],
dstStride
[
3
],
dstW
,
dstY
-
lastDstY
,
lastDstY
,
255
);
fillPlane
(
dst
[
3
],
dstStride
[
3
],
dstW
,
dstY
-
lastDstY
,
lastDstY
,
255
);
#if HAVE_MMX2
if
(
av_get_cpu_flags
()
&
AV_CPU_FLAG_MMX2
)
__asm__
volatile
(
"sfence"
:::
"memory"
);
__asm__
volatile
(
"sfence"
:::
"memory"
);
#endif
emms_c
();
/* store changed local vars back in the context */
c
->
dstY
=
dstY
;
c
->
lumBufIndex
=
lumBufIndex
;
c
->
chrBufIndex
=
chrBufIndex
;
c
->
lastInLumBuf
=
lastInLumBuf
;
c
->
lastInChrBuf
=
lastInChrBuf
;
c
->
dstY
=
dstY
;
c
->
lumBufIndex
=
lumBufIndex
;
c
->
chrBufIndex
=
chrBufIndex
;
c
->
lastInLumBuf
=
lastInLumBuf
;
c
->
lastInChrBuf
=
lastInChrBuf
;
return
dstY
-
lastDstY
;
}
...
...
@@ -654,7 +698,8 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
c
->
hyScale
=
c
->
hcScale
=
hScale8To19_c
;
}
}
else
{
c
->
hyScale
=
c
->
hcScale
=
c
->
dstBpc
>
10
?
hScale16To19_c
:
hScale16To15_c
;
c
->
hyScale
=
c
->
hcScale
=
c
->
dstBpc
>
10
?
hScale16To19_c
:
hScale16To15_c
;
}
if
(
c
->
srcRange
!=
c
->
dstRange
&&
!
isAnyRGB
(
c
->
dstFormat
))
{
...
...
libswscale/swscale_internal.h
View file @
ef0ee7f6
...
...
@@ -614,8 +614,8 @@ const char *sws_format_name(enum PixelFormat format);
(isRGBinInt(x) || \
isBGRinInt(x))
#define isALPHA(x) \
(av_pix_fmt_descriptors[x].nb_components == 2 || \
#define isALPHA(x)
\
(av_pix_fmt_descriptors[x].nb_components == 2 ||
\
av_pix_fmt_descriptors[x].nb_components == 4)
#define isPacked(x) \
...
...
@@ -623,7 +623,7 @@ const char *sws_format_name(enum PixelFormat format);
!(av_pix_fmt_descriptors[x].flags & PIX_FMT_PLANAR)) || \
(x) == PIX_FMT_PAL8)
#define isPlanar(x) \
#define isPlanar(x)
\
(av_pix_fmt_descriptors[x].nb_components >= 2 && \
(av_pix_fmt_descriptors[x].flags & PIX_FMT_PLANAR))
...
...
@@ -635,7 +635,7 @@ const char *sws_format_name(enum PixelFormat format);
((av_pix_fmt_descriptors[x].flags & \
(PIX_FMT_PLANAR | PIX_FMT_RGB)) == (PIX_FMT_PLANAR | PIX_FMT_RGB))
#define usePal(x) ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL)
||
\
#define usePal(x) ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL)
||
\
(av_pix_fmt_descriptors[x].flags & PIX_FMT_PSEUDOPAL) || \
(x) == PIX_FMT_Y400A)
...
...
libswscale/utils.c
View file @
ef0ee7f6
...
...
@@ -18,13 +18,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _SVID_SOURCE //needed for MAP_ANONYMOUS
#include "config.h"
#define _SVID_SOURCE // needed for MAP_ANONYMOUS
#include <assert.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include "config.h"
#include <assert.h>
#include <string.h>
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
...
...
@@ -35,17 +36,18 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "swscale.h"
#include "swscale_internal.h"
#include "rgb2rgb.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/x86_cpu.h"
#include "libavutil/cpu.h"
#include "libavutil/avutil.h"
#include "libavutil/bswap.h"
#include "libavutil/cpu.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/x86_cpu.h"
#include "rgb2rgb.h"
#include "swscale.h"
#include "swscale_internal.h"
unsigned
swscale_version
(
void
)
{
...
...
@@ -63,101 +65,101 @@ const char *swscale_license(void)
return
LICENSE_PREFIX
LIBAV_LICENSE
+
sizeof
(
LICENSE_PREFIX
)
-
1
;
}
#define RET 0xC3 //near return opcode for x86
#define RET 0xC3 //
near return opcode for x86
typedef
struct
FormatEntry
{
int
is_supported_in
,
is_supported_out
;
}
FormatEntry
;
static
const
FormatEntry
format_entries
[
PIX_FMT_NB
]
=
{
[
PIX_FMT_YUV420P
]
=
{
1
,
1
},
[
PIX_FMT_YUYV422
]
=
{
1
,
1
},
[
PIX_FMT_RGB24
]
=
{
1
,
1
},
[
PIX_FMT_BGR24
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P
]
=
{
1
,
1
},
[
PIX_FMT_YUV410P
]
=
{
1
,
1
},
[
PIX_FMT_YUV411P
]
=
{
1
,
1
},
[
PIX_FMT_GRAY8
]
=
{
1
,
1
},
[
PIX_FMT_MONOWHITE
]
=
{
1
,
1
},
[
PIX_FMT_MONOBLACK
]
=
{
1
,
1
},
[
PIX_FMT_PAL8
]
=
{
1
,
0
},
[
PIX_FMT_YUVJ420P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ422P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ444P
]
=
{
1
,
1
},
[
PIX_FMT_UYVY422
]
=
{
1
,
1
},
[
PIX_FMT_UYYVYY411
]
=
{
0
,
0
},
[
PIX_FMT_BGR8
]
=
{
1
,
1
},
[
PIX_FMT_BGR4
]
=
{
0
,
1
},
[
PIX_FMT_BGR4_BYTE
]
=
{
1
,
1
},
[
PIX_FMT_RGB8
]
=
{
1
,
1
},
[
PIX_FMT_RGB4
]
=
{
0
,
1
},
[
PIX_FMT_RGB4_BYTE
]
=
{
1
,
1
},
[
PIX_FMT_NV12
]
=
{
1
,
1
},
[
PIX_FMT_NV21
]
=
{
1
,
1
},
[
PIX_FMT_ARGB
]
=
{
1
,
1
},
[
PIX_FMT_RGBA
]
=
{
1
,
1
},
[
PIX_FMT_ABGR
]
=
{
1
,
1
},
[
PIX_FMT_BGRA
]
=
{
1
,
1
},
[
PIX_FMT_GRAY16BE
]
=
{
1
,
1
},
[
PIX_FMT_GRAY16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV440P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ440P
]
=
{
1
,
1
},
[
PIX_FMT_YUVA420P
]
=
{
1
,
1
},
[
PIX_FMT_RGB48BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB48LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB565BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB565LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB555BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB555LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR565BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR565LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR555BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR555LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P16BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P16BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P16BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB444LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB444BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR444LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR444BE
]
=
{
1
,
1
},
[
PIX_FMT_Y400A
]
=
{
1
,
0
},
[
PIX_FMT_BGR48BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR48LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P10LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P10LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P10LE
]
=
{
1
,
1
},
[
PIX_FMT_GBRP
]
=
{
1
,
0
},
[
PIX_FMT_GBRP9LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP9BE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP10LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP10BE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP16LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP16BE
]
=
{
1
,
0
},
[
PIX_FMT_YUV420P
]
=
{
1
,
1
},
[
PIX_FMT_YUYV422
]
=
{
1
,
1
},
[
PIX_FMT_RGB24
]
=
{
1
,
1
},
[
PIX_FMT_BGR24
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P
]
=
{
1
,
1
},
[
PIX_FMT_YUV410P
]
=
{
1
,
1
},
[
PIX_FMT_YUV411P
]
=
{
1
,
1
},
[
PIX_FMT_GRAY8
]
=
{
1
,
1
},
[
PIX_FMT_MONOWHITE
]
=
{
1
,
1
},
[
PIX_FMT_MONOBLACK
]
=
{
1
,
1
},
[
PIX_FMT_PAL8
]
=
{
1
,
0
},
[
PIX_FMT_YUVJ420P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ422P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ444P
]
=
{
1
,
1
},
[
PIX_FMT_UYVY422
]
=
{
1
,
1
},
[
PIX_FMT_UYYVYY411
]
=
{
0
,
0
},
[
PIX_FMT_BGR8
]
=
{
1
,
1
},
[
PIX_FMT_BGR4
]
=
{
0
,
1
},
[
PIX_FMT_BGR4_BYTE
]
=
{
1
,
1
},
[
PIX_FMT_RGB8
]
=
{
1
,
1
},
[
PIX_FMT_RGB4
]
=
{
0
,
1
},
[
PIX_FMT_RGB4_BYTE
]
=
{
1
,
1
},
[
PIX_FMT_NV12
]
=
{
1
,
1
},
[
PIX_FMT_NV21
]
=
{
1
,
1
},
[
PIX_FMT_ARGB
]
=
{
1
,
1
},
[
PIX_FMT_RGBA
]
=
{
1
,
1
},
[
PIX_FMT_ABGR
]
=
{
1
,
1
},
[
PIX_FMT_BGRA
]
=
{
1
,
1
},
[
PIX_FMT_GRAY16BE
]
=
{
1
,
1
},
[
PIX_FMT_GRAY16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV440P
]
=
{
1
,
1
},
[
PIX_FMT_YUVJ440P
]
=
{
1
,
1
},
[
PIX_FMT_YUVA420P
]
=
{
1
,
1
},
[
PIX_FMT_RGB48BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB48LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB565BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB565LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB555BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB555LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR565BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR565LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR555BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR555LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P16BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P16BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P16LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P16BE
]
=
{
1
,
1
},
[
PIX_FMT_RGB444LE
]
=
{
1
,
1
},
[
PIX_FMT_RGB444BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR444LE
]
=
{
1
,
1
},
[
PIX_FMT_BGR444BE
]
=
{
1
,
1
},
[
PIX_FMT_Y400A
]
=
{
1
,
0
},
[
PIX_FMT_BGR48BE
]
=
{
1
,
1
},
[
PIX_FMT_BGR48LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV420P10LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV422P10LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P9BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P9LE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P10BE
]
=
{
1
,
1
},
[
PIX_FMT_YUV444P10LE
]
=
{
1
,
1
},
[
PIX_FMT_GBRP
]
=
{
1
,
0
},
[
PIX_FMT_GBRP9LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP9BE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP10LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP10BE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP16LE
]
=
{
1
,
0
},
[
PIX_FMT_GBRP16BE
]
=
{
1
,
0
},
};
int
sws_isSupportedInput
(
enum
PixelFormat
pix_fmt
)
{
return
(
unsigned
)
pix_fmt
<
PIX_FMT_NB
?
format_entries
[
pix_fmt
].
is_supported_in
:
0
;
format_entries
[
pix_fmt
].
is_supported_in
:
0
;
}
int
sws_isSupportedOutput
(
enum
PixelFormat
pix_fmt
)
{
return
(
unsigned
)
pix_fmt
<
PIX_FMT_NB
?
format_entries
[
pix_fmt
].
is_supported_out
:
0
;
format_entries
[
pix_fmt
].
is_supported_out
:
0
;
}
extern
const
int32_t
ff_yuv2rgb_coeffs
[
8
][
4
];
...
...
@@ -170,261 +172,302 @@ const char *sws_format_name(enum PixelFormat format)
return
"Unknown format"
;
}
static
double
getSplineCoeff
(
double
a
,
double
b
,
double
c
,
double
d
,
double
dist
)
static
double
getSplineCoeff
(
double
a
,
double
b
,
double
c
,
double
d
,
double
dist
)
{
if
(
dist
<=
1
.
0
)
return
((
d
*
dist
+
c
)
*
dist
+
b
)
*
dist
+
a
;
else
return
getSplineCoeff
(
0
.
0
,
b
+
2
.
0
*
c
+
3
.
0
*
d
,
c
+
3
.
0
*
d
,
-
b
-
3
.
0
*
c
-
6
.
0
*
d
,
dist
-
1
.
0
);
if
(
dist
<=
1
.
0
)
return
((
d
*
dist
+
c
)
*
dist
+
b
)
*
dist
+
a
;
else
return
getSplineCoeff
(
0
.
0
,
b
+
2
.
0
*
c
+
3
.
0
*
d
,
c
+
3
.
0
*
d
,
-
b
-
3
.
0
*
c
-
6
.
0
*
d
,
dist
-
1
.
0
);
}
static
int
initFilter
(
int16_t
**
outFilter
,
int32_t
**
filterPos
,
int
*
outFilterSize
,
int
xInc
,
int
srcW
,
int
dstW
,
int
filterAlign
,
int
one
,
int
flags
,
int
cpu_flags
,
SwsVector
*
srcFilter
,
SwsVector
*
dstFilter
,
double
param
[
2
],
int
is_horizontal
)
static
int
initFilter
(
int16_t
**
outFilter
,
int32_t
**
filterPos
,
int
*
outFilterSize
,
int
xInc
,
int
srcW
,
int
dstW
,
int
filterAlign
,
int
one
,
int
flags
,
int
cpu_flags
,
SwsVector
*
srcFilter
,
SwsVector
*
dstFilter
,
double
param
[
2
],
int
is_horizontal
)
{
int
i
;
int
filterSize
;
int
filter2Size
;
int
minFilterSize
;
int64_t
*
filter
=
NULL
;
int64_t
*
filter2
=
NULL
;
const
int64_t
fone
=
1LL
<<
54
;
int
ret
=
-
1
;
int64_t
*
filter
=
NULL
;
int64_t
*
filter2
=
NULL
;
const
int64_t
fone
=
1LL
<<
54
;
int
ret
=
-
1
;
emms_c
();
//
FIXME this should not be required but i
t IS (even for non-MMX versions)
emms_c
();
//
FIXME should not be required bu
t IS (even for non-MMX versions)
// NOTE: the +3 is for the MMX(+1)
/
SSE(+3) scaler which reads over the end
FF_ALLOC_OR_GOTO
(
NULL
,
*
filterPos
,
(
dstW
+
3
)
*
sizeof
(
**
filterPos
),
fail
);
// NOTE: the +3 is for the MMX(+1)
/
SSE(+3) scaler which reads over the end
FF_ALLOC_OR_GOTO
(
NULL
,
*
filterPos
,
(
dstW
+
3
)
*
sizeof
(
**
filterPos
),
fail
);
if
(
FFABS
(
xInc
-
0x10000
)
<
10
)
{
// unscaled
if
(
FFABS
(
xInc
-
0x10000
)
<
10
)
{
// unscaled
int
i
;
filterSize
=
1
;
FF_ALLOCZ_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
filterSize
=
1
;
FF_ALLOCZ_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
filter
[
i
*
filterSize
]
=
fone
;
(
*
filterPos
)[
i
]
=
i
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
filter
[
i
*
filterSize
]
=
fone
;
(
*
filterPos
)[
i
]
=
i
;
}
}
else
if
(
flags
&
SWS_POINT
)
{
// lame looking point sampling mode
}
else
if
(
flags
&
SWS_POINT
)
{
// lame looking point sampling mode
int
i
;
int
xDstInSrc
;
filterSize
=
1
;
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
filterSize
=
1
;
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
xDstInSrc
=
xInc
/
2
-
0x8000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
1
)
<<
15
)
+
(
1
<<
15
))
>>
16
;
xDstInSrc
=
xInc
/
2
-
0x8000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
1
)
<<
15
)
+
(
1
<<
15
))
>>
16
;
(
*
filterPos
)[
i
]
=
xx
;
filter
[
i
]
=
fone
;
xDstInSrc
+=
xInc
;
(
*
filterPos
)[
i
]
=
xx
;
filter
[
i
]
=
fone
;
xDstInSrc
+=
xInc
;
}
}
else
if
((
xInc
<=
(
1
<<
16
)
&&
(
flags
&
SWS_AREA
))
||
(
flags
&
SWS_FAST_BILINEAR
))
{
// bilinear upscale
}
else
if
((
xInc
<=
(
1
<<
16
)
&&
(
flags
&
SWS_AREA
))
||
(
flags
&
SWS_FAST_BILINEAR
))
{
// bilinear upscale
int
i
;
int
xDstInSrc
;
filterSize
=
2
;
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
filterSize
=
2
;
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
xDstInSrc
=
xInc
/
2
-
0x8000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
1
)
<<
15
)
+
(
1
<<
15
))
>>
16
;
xDstInSrc
=
xInc
/
2
-
0x8000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
1
)
<<
15
)
+
(
1
<<
15
))
>>
16
;
int
j
;
(
*
filterPos
)[
i
]
=
xx
;
//bilinear upscale / linear interpolate / area averaging
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
int64_t
coeff
=
fone
-
FFABS
((
xx
<<
16
)
-
xDstInSrc
)
*
(
fone
>>
16
);
if
(
coeff
<
0
)
coeff
=
0
;
filter
[
i
*
filterSize
+
j
]
=
coeff
;
(
*
filterPos
)[
i
]
=
xx
;
// bilinear upscale / linear interpolate / area averaging
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
int64_t
coeff
=
fone
-
FFABS
((
xx
<<
16
)
-
xDstInSrc
)
*
(
fone
>>
16
);
if
(
coeff
<
0
)
coeff
=
0
;
filter
[
i
*
filterSize
+
j
]
=
coeff
;
xx
++
;
}
xDstInSrc
+=
xInc
;
xDstInSrc
+=
xInc
;
}
}
else
{
int64_t
xDstInSrc
;
int
sizeFactor
;
if
(
flags
&
SWS_BICUBIC
)
sizeFactor
=
4
;
else
if
(
flags
&
SWS_X
)
sizeFactor
=
8
;
else
if
(
flags
&
SWS_AREA
)
sizeFactor
=
1
;
//downscale only, for upscale it is bilinear
else
if
(
flags
&
SWS_GAUSS
)
sizeFactor
=
8
;
// infinite ;)
else
if
(
flags
&
SWS_LANCZOS
)
sizeFactor
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
ceil
(
2
*
param
[
0
])
:
6
;
else
if
(
flags
&
SWS_SINC
)
sizeFactor
=
20
;
// infinite ;)
else
if
(
flags
&
SWS_SPLINE
)
sizeFactor
=
20
;
// infinite ;)
else
if
(
flags
&
SWS_BILINEAR
)
sizeFactor
=
2
;
if
(
flags
&
SWS_BICUBIC
)
sizeFactor
=
4
;
else
if
(
flags
&
SWS_X
)
sizeFactor
=
8
;
else
if
(
flags
&
SWS_AREA
)
sizeFactor
=
1
;
// downscale only, for upscale it is bilinear
else
if
(
flags
&
SWS_GAUSS
)
sizeFactor
=
8
;
// infinite ;)
else
if
(
flags
&
SWS_LANCZOS
)
sizeFactor
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
ceil
(
2
*
param
[
0
])
:
6
;
else
if
(
flags
&
SWS_SINC
)
sizeFactor
=
20
;
// infinite ;)
else
if
(
flags
&
SWS_SPLINE
)
sizeFactor
=
20
;
// infinite ;)
else
if
(
flags
&
SWS_BILINEAR
)
sizeFactor
=
2
;
else
{
sizeFactor
=
0
;
//
GCC warning killer
sizeFactor
=
0
;
//
GCC warning killer
assert
(
0
);
}
if
(
xInc
<=
1
<<
16
)
filterSize
=
1
+
sizeFactor
;
// upscale
else
filterSize
=
1
+
(
sizeFactor
*
srcW
+
dstW
-
1
)
/
dstW
;
if
(
xInc
<=
1
<<
16
)
filterSize
=
1
+
sizeFactor
;
// upscale
else
filterSize
=
1
+
(
sizeFactor
*
srcW
+
dstW
-
1
)
/
dstW
;
filterSize
=
FFMIN
(
filterSize
,
srcW
-
2
);
filterSize
=
FFMAX
(
filterSize
,
1
);
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
FF_ALLOC_OR_GOTO
(
NULL
,
filter
,
dstW
*
sizeof
(
*
filter
)
*
filterSize
,
fail
);
xDstInSrc
=
xInc
-
0x10000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
2
)
<<
16
))
/
(
1
<<
17
);
xDstInSrc
=
xInc
-
0x10000
;
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
xx
=
(
xDstInSrc
-
((
filterSize
-
2
)
<<
16
))
/
(
1
<<
17
);
int
j
;
(
*
filterPos
)[
i
]
=
xx
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
int64_t
d
=
(
FFABS
(((
int64_t
)
xx
<<
17
)
-
xDstInSrc
))
<<
13
;
(
*
filterPos
)[
i
]
=
xx
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
int64_t
d
=
(
FFABS
(((
int64_t
)
xx
<<
17
)
-
xDstInSrc
))
<<
13
;
double
floatd
;
int64_t
coeff
;
if
(
xInc
>
1
<<
16
)
d
=
d
*
dstW
/
srcW
;
floatd
=
d
*
(
1
.
0
/
(
1
<<
30
));
if
(
xInc
>
1
<<
16
)
d
=
d
*
dstW
/
srcW
;
floatd
=
d
*
(
1
.
0
/
(
1
<<
30
));
if
(
flags
&
SWS_BICUBIC
)
{
int64_t
B
=
(
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
0
)
*
(
1
<<
24
);
int64_t
C
=
(
param
[
1
]
!=
SWS_PARAM_DEFAULT
?
param
[
1
]
:
0
.
6
)
*
(
1
<<
24
);
int64_t
B
=
(
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
0
)
*
(
1
<<
24
);
int64_t
C
=
(
param
[
1
]
!=
SWS_PARAM_DEFAULT
?
param
[
1
]
:
0
.
6
)
*
(
1
<<
24
);
if
(
d
>=
1LL
<<
31
)
{
if
(
d
>=
1LL
<<
31
)
{
coeff
=
0
.
0
;
}
else
{
int64_t
dd
=
(
d
*
d
)
>>
30
;
int64_t
ddd
=
(
dd
*
d
)
>>
30
;
if
(
d
<
1LL
<<
30
)
coeff
=
(
12
*
(
1
<<
24
)
-
9
*
B
-
6
*
C
)
*
ddd
+
(
-
18
*
(
1
<<
24
)
+
12
*
B
+
6
*
C
)
*
dd
+
(
6
*
(
1
<<
24
)
-
2
*
B
)
*
(
1
<<
30
);
if
(
d
<
1LL
<<
30
)
coeff
=
(
12
*
(
1
<<
24
)
-
9
*
B
-
6
*
C
)
*
ddd
+
(
-
18
*
(
1
<<
24
)
+
12
*
B
+
6
*
C
)
*
dd
+
(
6
*
(
1
<<
24
)
-
2
*
B
)
*
(
1
<<
30
);
else
coeff
=
(
-
B
-
6
*
C
)
*
ddd
+
(
6
*
B
+
30
*
C
)
*
dd
+
(
-
12
*
B
-
48
*
C
)
*
d
+
(
8
*
B
+
24
*
C
)
*
(
1
<<
30
);
coeff
=
(
-
B
-
6
*
C
)
*
ddd
+
(
6
*
B
+
30
*
C
)
*
dd
+
(
-
12
*
B
-
48
*
C
)
*
d
+
(
8
*
B
+
24
*
C
)
*
(
1
<<
30
);
}
coeff
*=
fone
>>
(
30
+
24
);
coeff
*=
fone
>>
(
30
+
24
);
}
/* else if (flags & SWS_X) {
double p= param ? param*0.01 : 0.3;
coeff = d ? sin(d*M_PI)/(d*M_PI) : 1.0;
coeff*= pow(2.0, - p*d*d);
}*/
#if 0
else if (flags & SWS_X) {
double p = param ? param * 0.01 : 0.3;
coeff = d ? sin(d * M_PI) / (d * M_PI) : 1.0;
coeff *= pow(2.0, -p * d * d);
}
#endif
else
if
(
flags
&
SWS_X
)
{
double
A
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
1
.
0
;
double
A
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
1
.
0
;
double
c
;
if
(
floatd
<
1
.
0
)
c
=
cos
(
floatd
*
M_PI
);
if
(
floatd
<
1
.
0
)
c
=
cos
(
floatd
*
M_PI
);
else
c
=-
1
.
0
;
if
(
c
<
0
.
0
)
c
=
-
pow
(
-
c
,
A
);
else
c
=
pow
(
c
,
A
);
coeff
=
(
c
*
0
.
5
+
0
.
5
)
*
fone
;
c
=
-
1
.
0
;
if
(
c
<
0
.
0
)
c
=
-
pow
(
-
c
,
A
);
else
c
=
pow
(
c
,
A
);
coeff
=
(
c
*
0
.
5
+
0
.
5
)
*
fone
;
}
else
if
(
flags
&
SWS_AREA
)
{
int64_t
d2
=
d
-
(
1
<<
29
);
if
(
d2
*
xInc
<
-
(
1LL
<<
(
29
+
16
)))
coeff
=
1
.
0
*
(
1LL
<<
(
30
+
16
));
else
if
(
d2
*
xInc
<
(
1LL
<<
(
29
+
16
)))
coeff
=
-
d2
*
xInc
+
(
1LL
<<
(
29
+
16
));
else
coeff
=
0
.
0
;
coeff
*=
fone
>>
(
30
+
16
);
int64_t
d2
=
d
-
(
1
<<
29
);
if
(
d2
*
xInc
<
-
(
1LL
<<
(
29
+
16
)))
coeff
=
1
.
0
*
(
1LL
<<
(
30
+
16
));
else
if
(
d2
*
xInc
<
(
1LL
<<
(
29
+
16
)))
coeff
=
-
d2
*
xInc
+
(
1LL
<<
(
29
+
16
));
else
coeff
=
0
.
0
;
coeff
*=
fone
>>
(
30
+
16
);
}
else
if
(
flags
&
SWS_GAUSS
)
{
double
p
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
3
.
0
;
coeff
=
(
pow
(
2
.
0
,
-
p
*
floatd
*
floatd
))
*
fone
;
double
p
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
3
.
0
;
coeff
=
(
pow
(
2
.
0
,
-
p
*
floatd
*
floatd
))
*
fone
;
}
else
if
(
flags
&
SWS_SINC
)
{
coeff
=
(
d
?
sin
(
floatd
*
M_PI
)
/
(
floatd
*
M_PI
)
:
1
.
0
)
*
fone
;
coeff
=
(
d
?
sin
(
floatd
*
M_PI
)
/
(
floatd
*
M_PI
)
:
1
.
0
)
*
fone
;
}
else
if
(
flags
&
SWS_LANCZOS
)
{
double
p
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
3
.
0
;
coeff
=
(
d
?
sin
(
floatd
*
M_PI
)
*
sin
(
floatd
*
M_PI
/
p
)
/
(
floatd
*
floatd
*
M_PI
*
M_PI
/
p
)
:
1
.
0
)
*
fone
;
if
(
floatd
>
p
)
coeff
=
0
;
double
p
=
param
[
0
]
!=
SWS_PARAM_DEFAULT
?
param
[
0
]
:
3
.
0
;
coeff
=
(
d
?
sin
(
floatd
*
M_PI
)
*
sin
(
floatd
*
M_PI
/
p
)
/
(
floatd
*
floatd
*
M_PI
*
M_PI
/
p
)
:
1
.
0
)
*
fone
;
if
(
floatd
>
p
)
coeff
=
0
;
}
else
if
(
flags
&
SWS_BILINEAR
)
{
coeff
=
(
1
<<
30
)
-
d
;
if
(
coeff
<
0
)
coeff
=
0
;
coeff
=
(
1
<<
30
)
-
d
;
if
(
coeff
<
0
)
coeff
=
0
;
coeff
*=
fone
>>
30
;
}
else
if
(
flags
&
SWS_SPLINE
)
{
double
p
=
-
2
.
196152422706632
;
coeff
=
getSplineCoeff
(
1
.
0
,
0
.
0
,
p
,
-
p
-
1
.
0
,
floatd
)
*
fone
;
double
p
=
-
2
.
196152422706632
;
coeff
=
getSplineCoeff
(
1
.
0
,
0
.
0
,
p
,
-
p
-
1
.
0
,
floatd
)
*
fone
;
}
else
{
coeff
=
0
.
0
;
//
GCC warning killer
coeff
=
0
.
0
;
//
GCC warning killer
assert
(
0
);
}
filter
[
i
*
filterSize
+
j
]
=
coeff
;
filter
[
i
*
filterSize
+
j
]
=
coeff
;
xx
++
;
}
xDstInSrc
+=
2
*
xInc
;
xDstInSrc
+=
2
*
xInc
;
}
}
/* apply src & dst Filter to filter -> filter2
av_free(filter);
*/
assert
(
filterSize
>
0
);
filter2Size
=
filterSize
;
if
(
srcFilter
)
filter2Size
+=
srcFilter
->
length
-
1
;
if
(
dstFilter
)
filter2Size
+=
dstFilter
->
length
-
1
;
assert
(
filter2Size
>
0
);
FF_ALLOCZ_OR_GOTO
(
NULL
,
filter2
,
filter2Size
*
dstW
*
sizeof
(
*
filter2
),
fail
);
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
* av_free(filter);
*/
assert
(
filterSize
>
0
);
filter2Size
=
filterSize
;
if
(
srcFilter
)
filter2Size
+=
srcFilter
->
length
-
1
;
if
(
dstFilter
)
filter2Size
+=
dstFilter
->
length
-
1
;
assert
(
filter2Size
>
0
);
FF_ALLOCZ_OR_GOTO
(
NULL
,
filter2
,
filter2Size
*
dstW
*
sizeof
(
*
filter2
),
fail
);
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
,
k
;
if
(
srcFilter
)
{
for
(
k
=
0
;
k
<
srcFilter
->
length
;
k
++
)
{
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
filter2
[
i
*
filter2Size
+
k
+
j
]
+=
srcFilter
->
coeff
[
k
]
*
filter
[
i
*
filterSize
+
j
];
if
(
srcFilter
)
{
for
(
k
=
0
;
k
<
srcFilter
->
length
;
k
++
)
{
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
filter2
[
i
*
filter2Size
+
k
+
j
]
+=
srcFilter
->
coeff
[
k
]
*
filter
[
i
*
filterSize
+
j
];
}
}
else
{
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
filter2
[
i
*
filter2Size
+
j
]
=
filter
[
i
*
filterSize
+
j
];
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
filter2
[
i
*
filter2Size
+
j
]
=
filter
[
i
*
filterSize
+
j
];
}
//FIXME dstFilter
//
FIXME dstFilter
(
*
filterPos
)[
i
]
+=
(
filterSize
-
1
)
/
2
-
(
filter2Size
-
1
)
/
2
;
(
*
filterPos
)[
i
]
+=
(
filterSize
-
1
)
/
2
-
(
filter2Size
-
1
)
/
2
;
}
av_freep
(
&
filter
);
/* try to reduce the filter-size (step1 find size and shift left) */
// Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).
minFilterSize
=
0
;
for
(
i
=
dstW
-
1
;
i
>=
0
;
i
--
)
{
int
min
=
filter2Size
;
minFilterSize
=
0
;
for
(
i
=
dstW
-
1
;
i
>=
0
;
i
--
)
{
int
min
=
filter2Size
;
int
j
;
int64_t
cutOff
=
0
.
0
;
int64_t
cutOff
=
0
.
0
;
/* get rid of near zero elements on the left by shifting left */
for
(
j
=
0
;
j
<
filter2Size
;
j
++
)
{
for
(
j
=
0
;
j
<
filter2Size
;
j
++
)
{
int
k
;
cutOff
+=
FFABS
(
filter2
[
i
*
filter2Size
]);
cutOff
+=
FFABS
(
filter2
[
i
*
filter2Size
]);
if
(
cutOff
>
SWS_MAX_REDUCE_CUTOFF
*
fone
)
break
;
if
(
cutOff
>
SWS_MAX_REDUCE_CUTOFF
*
fone
)
break
;
/* preserve monotonicity because the core can't handle the filter otherwise */
if
(
i
<
dstW
-
1
&&
(
*
filterPos
)[
i
]
>=
(
*
filterPos
)[
i
+
1
])
break
;
/* preserve monotonicity because the core can't handle the
* filter otherwise */
if
(
i
<
dstW
-
1
&&
(
*
filterPos
)[
i
]
>=
(
*
filterPos
)[
i
+
1
])
break
;
// move filter coefficients left
for
(
k
=
1
;
k
<
filter2Size
;
k
++
)
filter2
[
i
*
filter2Size
+
k
-
1
]
=
filter2
[
i
*
filter2Size
+
k
];
filter2
[
i
*
filter2Size
+
k
-
1
]
=
0
;
for
(
k
=
1
;
k
<
filter2Size
;
k
++
)
filter2
[
i
*
filter2Size
+
k
-
1
]
=
filter2
[
i
*
filter2Size
+
k
];
filter2
[
i
*
filter2Size
+
k
-
1
]
=
0
;
(
*
filterPos
)[
i
]
++
;
}
cutOff
=
0
;
cutOff
=
0
;
/* count near zeros on the right */
for
(
j
=
filter2Size
-
1
;
j
>
0
;
j
--
)
{
cutOff
+=
FFABS
(
filter2
[
i
*
filter2Size
+
j
]);
for
(
j
=
filter2Size
-
1
;
j
>
0
;
j
--
)
{
cutOff
+=
FFABS
(
filter2
[
i
*
filter2Size
+
j
]);
if
(
cutOff
>
SWS_MAX_REDUCE_CUTOFF
*
fone
)
break
;
if
(
cutOff
>
SWS_MAX_REDUCE_CUTOFF
*
fone
)
break
;
min
--
;
}
if
(
min
>
minFilterSize
)
minFilterSize
=
min
;
if
(
min
>
minFilterSize
)
minFilterSize
=
min
;
}
if
(
HAVE_ALTIVEC
&&
cpu_flags
&
AV_CPU_FLAG_ALTIVEC
)
{
// we can handle the special case 4,
// so we don't want to go to the full 8
// we can handle the special case 4, so we don't want to go the full 8
if
(
minFilterSize
<
5
)
filterAlign
=
4
;
// We really don't want to waste our time
// doing useless computation, so fall back on
// the scalar C code for very small filters.
// Vectorizing is worth it only if you have a
// decent-sized vector.
/* We really don't want to waste our time doing useless computation, so
* fall back on the scalar C code for very small filters.
* Vectorizing is worth it only if you have a decent-sized vector. */
if
(
minFilterSize
<
3
)
filterAlign
=
1
;
}
...
...
@@ -432,34 +475,39 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSi
if
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
{
// special case for unscaled vertical filtering
if
(
minFilterSize
==
1
&&
filterAlign
==
2
)
filterAlign
=
1
;
filterAlign
=
1
;
}
assert
(
minFilterSize
>
0
);
filterSize
=
(
minFilterSize
+
(
filterAlign
-
1
))
&
(
~
(
filterAlign
-
1
));
filterSize
=
(
minFilterSize
+
(
filterAlign
-
1
))
&
(
~
(
filterAlign
-
1
));
assert
(
filterSize
>
0
);
filter
=
av_malloc
(
filterSize
*
dstW
*
sizeof
(
*
filter
));
if
(
filterSize
>=
MAX_FILTER_SIZE
*
16
/
((
flags
&
SWS_ACCURATE_RND
)
?
APCK_SIZE
:
16
)
||
!
filter
)
filter
=
av_malloc
(
filterSize
*
dstW
*
sizeof
(
*
filter
));
if
(
filterSize
>=
MAX_FILTER_SIZE
*
16
/
((
flags
&
SWS_ACCURATE_RND
)
?
APCK_SIZE
:
16
)
||
!
filter
)
goto
fail
;
*
outFilterSize
=
filterSize
;
*
outFilterSize
=
filterSize
;
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
NULL
,
AV_LOG_VERBOSE
,
"SwScaler: reducing / aligning filtersize %d -> %d
\n
"
,
filter2Size
,
filterSize
);
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
NULL
,
AV_LOG_VERBOSE
,
"SwScaler: reducing / aligning filtersize %d -> %d
\n
"
,
filter2Size
,
filterSize
);
/* try to reduce the filter-size (step2 reduce it) */
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
if
(
j
>=
filter2Size
)
filter
[
i
*
filterSize
+
j
]
=
0
;
else
filter
[
i
*
filterSize
+
j
]
=
filter2
[
i
*
filter2Size
+
j
];
if
((
flags
&
SWS_BITEXACT
)
&&
j
>=
minFilterSize
)
filter
[
i
*
filterSize
+
j
]
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
if
(
j
>=
filter2Size
)
filter
[
i
*
filterSize
+
j
]
=
0
;
else
filter
[
i
*
filterSize
+
j
]
=
filter2
[
i
*
filter2Size
+
j
];
if
((
flags
&
SWS_BITEXACT
)
&&
j
>=
minFilterSize
)
filter
[
i
*
filterSize
+
j
]
=
0
;
}
}
//FIXME try to align filterPos if possible
//
FIXME try to align filterPos if possible
//fix borders
//
fix borders
if
(
is_horizontal
)
{
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
...
...
@@ -468,7 +516,7 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSi
for
(
j
=
1
;
j
<
filterSize
;
j
++
)
{
int
left
=
FFMAX
(
j
+
(
*
filterPos
)[
i
],
0
);
filter
[
i
*
filterSize
+
left
]
+=
filter
[
i
*
filterSize
+
j
];
filter
[
i
*
filterSize
+
j
]
=
0
;
filter
[
i
*
filterSize
+
j
]
=
0
;
}
(
*
filterPos
)[
i
]
=
0
;
}
...
...
@@ -479,7 +527,7 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSi
for
(
j
=
filterSize
-
2
;
j
>=
0
;
j
--
)
{
int
right
=
FFMIN
(
j
+
shift
,
filterSize
-
1
);
filter
[
i
*
filterSize
+
right
]
+=
filter
[
i
*
filterSize
+
j
];
filter
[
i
*
filterSize
+
j
]
=
0
;
filter
[
i
*
filterSize
+
j
]
=
0
;
}
(
*
filterPos
)[
i
]
=
srcW
-
filterSize
;
}
...
...
@@ -488,37 +536,40 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSi
// Note the +1 is for the MMX scaler which reads over the end
/* align at 16 for AltiVec (needed by hScale_altivec_real) */
FF_ALLOCZ_OR_GOTO
(
NULL
,
*
outFilter
,
*
outFilterSize
*
(
dstW
+
3
)
*
sizeof
(
int16_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
NULL
,
*
outFilter
,
*
outFilterSize
*
(
dstW
+
3
)
*
sizeof
(
int16_t
),
fail
);
/* normalize & store in outFilter */
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
for
(
i
=
0
;
i
<
dstW
;
i
++
)
{
int
j
;
int64_t
error
=
0
;
int64_t
sum
=
0
;
int64_t
error
=
0
;
int64_t
sum
=
0
;
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
sum
+=
filter
[
i
*
filterSize
+
j
];
for
(
j
=
0
;
j
<
filterSize
;
j
++
)
{
sum
+=
filter
[
i
*
filterSize
+
j
];
}
sum
=
(
sum
+
one
/
2
)
/
one
;
for
(
j
=
0
;
j
<
*
outFilterSize
;
j
++
)
{
int64_t
v
=
filter
[
i
*
filterSize
+
j
]
+
error
;
int
intV
=
ROUNDED_DIV
(
v
,
sum
);
(
*
outFilter
)[
i
*
(
*
outFilterSize
)
+
j
]
=
intV
;
error
=
v
-
intV
*
sum
;
sum
=
(
sum
+
one
/
2
)
/
one
;
for
(
j
=
0
;
j
<
*
outFilterSize
;
j
++
)
{
int64_t
v
=
filter
[
i
*
filterSize
+
j
]
+
error
;
int
intV
=
ROUNDED_DIV
(
v
,
sum
);
(
*
outFilter
)[
i
*
(
*
outFilterSize
)
+
j
]
=
intV
;
error
=
v
-
intV
*
sum
;
}
}
(
*
filterPos
)[
dstW
+
0
]
=
(
*
filterPos
)[
dstW
+
1
]
=
(
*
filterPos
)[
dstW
+
2
]
=
(
*
filterPos
)[
dstW
-
1
];
// the MMX/SSE scaler will read over the end
for
(
i
=
0
;
i
<*
outFilterSize
;
i
++
)
{
int
k
=
(
dstW
-
1
)
*
(
*
outFilterSize
)
+
i
;
(
*
filterPos
)[
dstW
+
0
]
=
(
*
filterPos
)[
dstW
+
1
]
=
(
*
filterPos
)[
dstW
+
2
]
=
(
*
filterPos
)[
dstW
-
1
];
/* the MMX/SSE scaler will
* read over the end */
for
(
i
=
0
;
i
<
*
outFilterSize
;
i
++
)
{
int
k
=
(
dstW
-
1
)
*
(
*
outFilterSize
)
+
i
;
(
*
outFilter
)[
k
+
1
*
(
*
outFilterSize
)]
=
(
*
outFilter
)[
k
+
2
*
(
*
outFilterSize
)]
=
(
*
outFilter
)[
k
+
3
*
(
*
outFilterSize
)]
=
(
*
outFilter
)[
k
];
}
ret
=
0
;
ret
=
0
;
fail:
av_free
(
filter
);
av_free
(
filter2
);
...
...
@@ -526,7 +577,8 @@ fail:
}
#if HAVE_MMX2
static
int
initMMX2HScaler
(
int
dstW
,
int
xInc
,
uint8_t
*
filterCode
,
int16_t
*
filter
,
int32_t
*
filterPos
,
int
numSplits
)
static
int
initMMX2HScaler
(
int
dstW
,
int
xInc
,
uint8_t
*
filterCode
,
int16_t
*
filter
,
int32_t
*
filterPos
,
int
numSplits
)
{
uint8_t
*
fragmentA
;
x86_reg
imm8OfPShufW1A
;
...
...
@@ -541,18 +593,17 @@ static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *fil
int
xpos
,
i
;
// create an optimized horizontal scaling routine
/* This scaler is made of runtime-generated MMX2 code using specially
* tuned pshufw instructions. For every four output pixels, if four
* input pixels are enough for the fast bilinear scaling, then a chunk
* of fragmentB is used. If five input pixels are needed, then a chunk
* of fragmentA is used.
/* This scaler is made of runtime-generated MMX2 code using specially tuned
* pshufw instructions. For every four output pixels, if four input pixels
* are enough for the fast bilinear scaling, then a chunk of fragmentB is
* used. If five input pixels are needed, then a chunk of fragmentA is used.
*/
//code fragment
//
code fragment
__asm__
volatile
(
__asm__
volatile
(
"jmp 9f
\n\t
"
// Begin
// Begin
"0:
\n\t
"
"movq (%%"
REG_d
", %%"
REG_a
"), %%mm3
\n\t
"
"movd (%%"
REG_c
", %%"
REG_S
"), %%mm0
\n\t
"
...
...
@@ -572,27 +623,27 @@ static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *fil
"movq %%mm0, (%%"
REG_D
", %%"
REG_a
")
\n\t
"
"add $8, %%"
REG_a
"
\n\t
"
// End
// End
"9:
\n\t
"
//
"int $3 \n\t"
"lea
"
LOCAL_MANGLE
(
0
b
)
", %0
\n\t
"
"lea
"
LOCAL_MANGLE
(
1
b
)
", %1
\n\t
"
"lea
"
LOCAL_MANGLE
(
2
b
)
", %2
\n\t
"
//
"int $3 \n\t"
"lea
"
LOCAL_MANGLE
(
0
b
)
", %0
\n\t
"
"lea
"
LOCAL_MANGLE
(
1
b
)
", %1
\n\t
"
"lea
"
LOCAL_MANGLE
(
2
b
)
", %2
\n\t
"
"dec %1
\n\t
"
"dec %2
\n\t
"
"sub %0, %1
\n\t
"
"sub %0, %2
\n\t
"
"lea
"
LOCAL_MANGLE
(
9
b
)
", %3
\n\t
"
"lea
"
LOCAL_MANGLE
(
9
b
)
", %3
\n\t
"
"sub %0, %3
\n\t
"
:
"=r"
(
fragmentA
),
"=r"
(
imm8OfPShufW1A
),
"=r"
(
imm8OfPShufW2A
),
"=r"
(
fragmentLengthA
)
);
:
"=r"
(
fragmentA
),
"=r"
(
imm8OfPShufW1A
),
"=r"
(
imm8OfPShufW2A
),
"=r"
(
fragmentLengthA
)
);
__asm__
volatile
(
__asm__
volatile
(
"jmp 9f
\n\t
"
// Begin
// Begin
"0:
\n\t
"
"movq (%%"
REG_d
", %%"
REG_a
"), %%mm3
\n\t
"
"movd (%%"
REG_c
", %%"
REG_S
"), %%mm0
\n\t
"
...
...
@@ -610,76 +661,81 @@ static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *fil
"movq %%mm0, (%%"
REG_D
", %%"
REG_a
")
\n\t
"
"add $8, %%"
REG_a
"
\n\t
"
// End
// End
"9:
\n\t
"
//
"int $3 \n\t"
"lea
"
LOCAL_MANGLE
(
0
b
)
", %0
\n\t
"
"lea
"
LOCAL_MANGLE
(
1
b
)
", %1
\n\t
"
"lea
"
LOCAL_MANGLE
(
2
b
)
", %2
\n\t
"
//
"int $3 \n\t"
"lea
"
LOCAL_MANGLE
(
0
b
)
", %0
\n\t
"
"lea
"
LOCAL_MANGLE
(
1
b
)
", %1
\n\t
"
"lea
"
LOCAL_MANGLE
(
2
b
)
", %2
\n\t
"
"dec %1
\n\t
"
"dec %2
\n\t
"
"sub %0, %1
\n\t
"
"sub %0, %2
\n\t
"
"lea
"
LOCAL_MANGLE
(
9
b
)
", %3
\n\t
"
"lea
"
LOCAL_MANGLE
(
9
b
)
", %3
\n\t
"
"sub %0, %3
\n\t
"
:
"=r"
(
fragmentB
),
"=r"
(
imm8OfPShufW1B
),
"=r"
(
imm8OfPShufW2B
),
"=r"
(
fragmentLengthB
)
);
:
"=r"
(
fragmentB
),
"=r"
(
imm8OfPShufW1B
),
"=r"
(
imm8OfPShufW2B
),
"=r"
(
fragmentLengthB
)
);
xpos
=
0
;
//
lumXInc/2 - 0x8000; // difference between pixel centers
fragmentPos
=
0
;
xpos
=
0
;
//
lumXInc/2 - 0x8000; // difference between pixel centers
fragmentPos
=
0
;
for
(
i
=
0
;
i
<
dstW
/
numSplits
;
i
++
)
{
int
xx
=
xpos
>>
16
;
for
(
i
=
0
;
i
<
dstW
/
numSplits
;
i
++
)
{
int
xx
=
xpos
>>
16
;
if
((
i
&
3
)
==
0
)
{
int
a
=
0
;
int
b
=
((
xpos
+
xInc
)
>>
16
)
-
xx
;
int
c
=
((
xpos
+
xInc
*
2
)
>>
16
)
-
xx
;
int
d
=
((
xpos
+
xInc
*
3
)
>>
16
)
-
xx
;
int
inc
=
(
d
+
1
<
4
);
uint8_t
*
fragment
=
(
d
+
1
<
4
)
?
fragmentB
:
fragmentA
;
x86_reg
imm8OfPShufW1
=
(
d
+
1
<
4
)
?
imm8OfPShufW1B
:
imm8OfPShufW1A
;
x86_reg
imm8OfPShufW2
=
(
d
+
1
<
4
)
?
imm8OfPShufW2B
:
imm8OfPShufW2A
;
x86_reg
fragmentLength
=
(
d
+
1
<
4
)
?
fragmentLengthB
:
fragmentLengthA
;
int
maxShift
=
3
-
(
d
+
inc
);
int
shift
=
0
;
if
((
i
&
3
)
==
0
)
{
int
a
=
0
;
int
b
=
((
xpos
+
xInc
)
>>
16
)
-
xx
;
int
c
=
((
xpos
+
xInc
*
2
)
>>
16
)
-
xx
;
int
d
=
((
xpos
+
xInc
*
3
)
>>
16
)
-
xx
;
int
inc
=
(
d
+
1
<
4
);
uint8_t
*
fragment
=
(
d
+
1
<
4
)
?
fragmentB
:
fragmentA
;
x86_reg
imm8OfPShufW1
=
(
d
+
1
<
4
)
?
imm8OfPShufW1B
:
imm8OfPShufW1A
;
x86_reg
imm8OfPShufW2
=
(
d
+
1
<
4
)
?
imm8OfPShufW2B
:
imm8OfPShufW2A
;
x86_reg
fragmentLength
=
(
d
+
1
<
4
)
?
fragmentLengthB
:
fragmentLengthA
;
int
maxShift
=
3
-
(
d
+
inc
);
int
shift
=
0
;
if
(
filterCode
)
{
filter
[
i
]
=
((
xpos
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
1
]
=
(((
xpos
+
xInc
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
2
]
=
(((
xpos
+
xInc
*
2
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
3
]
=
(((
xpos
+
xInc
*
3
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filterPos
[
i
/
2
]
=
xx
;
filter
[
i
]
=
((
xpos
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
1
]
=
(((
xpos
+
xInc
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
2
]
=
(((
xpos
+
xInc
*
2
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filter
[
i
+
3
]
=
(((
xpos
+
xInc
*
3
)
&
0xFFFF
)
^
0xFFFF
)
>>
9
;
filterPos
[
i
/
2
]
=
xx
;
memcpy
(
filterCode
+
fragmentPos
,
fragment
,
fragmentLength
);
filterCode
[
fragmentPos
+
imm8OfPShufW1
]
=
(
a
+
inc
)
|
((
b
+
inc
)
<<
2
)
|
((
c
+
inc
)
<<
4
)
|
((
d
+
inc
)
<<
6
);
filterCode
[
fragmentPos
+
imm8OfPShufW2
]
=
a
|
(
b
<<
2
)
|
(
c
<<
4
)
|
(
d
<<
6
);
if
(
i
+
4
-
inc
>=
dstW
)
shift
=
maxShift
;
//avoid overread
else
if
((
filterPos
[
i
/
2
]
&
3
)
<=
maxShift
)
shift
=
filterPos
[
i
/
2
]
&
3
;
//Align
if
(
shift
&&
i
>=
shift
)
{
filterCode
[
fragmentPos
+
imm8OfPShufW1
]
+=
0x55
*
shift
;
filterCode
[
fragmentPos
+
imm8OfPShufW2
]
+=
0x55
*
shift
;
filterPos
[
i
/
2
]
-=
shift
;
filterCode
[
fragmentPos
+
imm8OfPShufW1
]
=
(
a
+
inc
)
|
((
b
+
inc
)
<<
2
)
|
((
c
+
inc
)
<<
4
)
|
((
d
+
inc
)
<<
6
);
filterCode
[
fragmentPos
+
imm8OfPShufW2
]
=
a
|
(
b
<<
2
)
|
(
c
<<
4
)
|
(
d
<<
6
);
if
(
i
+
4
-
inc
>=
dstW
)
shift
=
maxShift
;
// avoid overread
else
if
((
filterPos
[
i
/
2
]
&
3
)
<=
maxShift
)
shift
=
filterPos
[
i
/
2
]
&
3
;
// align
if
(
shift
&&
i
>=
shift
)
{
filterCode
[
fragmentPos
+
imm8OfPShufW1
]
+=
0x55
*
shift
;
filterCode
[
fragmentPos
+
imm8OfPShufW2
]
+=
0x55
*
shift
;
filterPos
[
i
/
2
]
-=
shift
;
}
}
fragmentPos
+=
fragmentLength
;
fragmentPos
+=
fragmentLength
;
if
(
filterCode
)
filterCode
[
fragmentPos
]
=
RET
;
filterCode
[
fragmentPos
]
=
RET
;
}
xpos
+=
xInc
;
xpos
+=
xInc
;
}
if
(
filterCode
)
filterPos
[((
i
/
2
)
+
1
)
&
(
~
1
)]
=
xpos
>>
16
;
// needed to jump to the next part
filterPos
[((
i
/
2
)
+
1
)
&
(
~
1
)]
=
xpos
>>
16
;
// needed to jump to the next part
return
fragmentPos
+
1
;
}
...
...
@@ -695,24 +751,27 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
int
srcRange
,
const
int
table
[
4
],
int
dstRange
,
int
brightness
,
int
contrast
,
int
saturation
)
{
memcpy
(
c
->
srcColorspaceTable
,
inv_table
,
sizeof
(
int
)
*
4
);
memcpy
(
c
->
dstColorspaceTable
,
table
,
sizeof
(
int
)
*
4
);
memcpy
(
c
->
srcColorspaceTable
,
inv_table
,
sizeof
(
int
)
*
4
);
memcpy
(
c
->
dstColorspaceTable
,
table
,
sizeof
(
int
)
*
4
);
c
->
brightness
=
brightness
;
c
->
contrast
=
contrast
;
c
->
saturation
=
saturation
;
c
->
srcRange
=
srcRange
;
c
->
dstRange
=
dstRange
;
if
(
isYUV
(
c
->
dstFormat
)
||
isGray
(
c
->
dstFormat
))
return
-
1
;
c
->
brightness
=
brightness
;
c
->
contrast
=
contrast
;
c
->
saturation
=
saturation
;
c
->
srcRange
=
srcRange
;
c
->
dstRange
=
dstRange
;
if
(
isYUV
(
c
->
dstFormat
)
||
isGray
(
c
->
dstFormat
))
return
-
1
;
c
->
dstFormatBpp
=
av_get_bits_per_pixel
(
&
av_pix_fmt_descriptors
[
c
->
dstFormat
]);
c
->
srcFormatBpp
=
av_get_bits_per_pixel
(
&
av_pix_fmt_descriptors
[
c
->
srcFormat
]);
ff_yuv2rgb_c_init_tables
(
c
,
inv_table
,
srcRange
,
brightness
,
contrast
,
saturation
);
//FIXME factorize
ff_yuv2rgb_c_init_tables
(
c
,
inv_table
,
srcRange
,
brightness
,
contrast
,
saturation
);
// FIXME factorize
if
(
HAVE_ALTIVEC
&&
av_get_cpu_flags
()
&
AV_CPU_FLAG_ALTIVEC
)
ff_yuv2rgb_init_tables_altivec
(
c
,
inv_table
,
brightness
,
contrast
,
saturation
);
ff_yuv2rgb_init_tables_altivec
(
c
,
inv_table
,
brightness
,
contrast
,
saturation
);
return
0
;
}
...
...
@@ -720,15 +779,16 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
int
*
srcRange
,
int
**
table
,
int
*
dstRange
,
int
*
brightness
,
int
*
contrast
,
int
*
saturation
)
{
if
(
isYUV
(
c
->
dstFormat
)
||
isGray
(
c
->
dstFormat
))
return
-
1
;
if
(
isYUV
(
c
->
dstFormat
)
||
isGray
(
c
->
dstFormat
))
return
-
1
;
*
inv_table
=
c
->
srcColorspaceTable
;
*
table
=
c
->
dstColorspaceTable
;
*
srcRange
=
c
->
srcRange
;
*
dstRange
=
c
->
dstRange
;
*
brightness
=
c
->
brightness
;
*
contrast
=
c
->
contrast
;
*
saturation
=
c
->
saturation
;
*
inv_table
=
c
->
srcColorspaceTable
;
*
table
=
c
->
dstColorspaceTable
;
*
srcRange
=
c
->
srcRange
;
*
dstRange
=
c
->
dstRange
;
*
brightness
=
c
->
brightness
;
*
contrast
=
c
->
contrast
;
*
saturation
=
c
->
saturation
;
return
0
;
}
...
...
@@ -736,17 +796,26 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
static
int
handle_jpeg
(
enum
PixelFormat
*
format
)
{
switch
(
*
format
)
{
case
PIX_FMT_YUVJ420P
:
*
format
=
PIX_FMT_YUV420P
;
return
1
;
case
PIX_FMT_YUVJ422P
:
*
format
=
PIX_FMT_YUV422P
;
return
1
;
case
PIX_FMT_YUVJ444P
:
*
format
=
PIX_FMT_YUV444P
;
return
1
;
case
PIX_FMT_YUVJ440P
:
*
format
=
PIX_FMT_YUV440P
;
return
1
;
default:
return
0
;
case
PIX_FMT_YUVJ420P
:
*
format
=
PIX_FMT_YUV420P
;
return
1
;
case
PIX_FMT_YUVJ422P
:
*
format
=
PIX_FMT_YUV422P
;
return
1
;
case
PIX_FMT_YUVJ444P
:
*
format
=
PIX_FMT_YUV444P
;
return
1
;
case
PIX_FMT_YUVJ440P
:
*
format
=
PIX_FMT_YUV440P
;
return
1
;
default:
return
0
;
}
}
SwsContext
*
sws_alloc_context
(
void
)
{
SwsContext
*
c
=
av_mallocz
(
sizeof
(
SwsContext
));
SwsContext
*
c
=
av_mallocz
(
sizeof
(
SwsContext
));
c
->
av_class
=
&
sws_context_class
;
av_opt_set_defaults
(
c
);
...
...
@@ -759,117 +828,133 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
int
i
;
int
usesVFilter
,
usesHFilter
;
int
unscaled
;
SwsFilter
dummyFilter
=
{
NULL
,
NULL
,
NULL
,
NULL
};
int
srcW
=
c
->
srcW
;
int
srcH
=
c
->
srcH
;
int
dstW
=
c
->
dstW
;
int
dstH
=
c
->
dstH
;
int
dst_stride
=
FFALIGN
(
dstW
*
sizeof
(
int16_t
)
+
16
,
16
),
dst_stride_px
=
dst_stride
>>
1
;
SwsFilter
dummyFilter
=
{
NULL
,
NULL
,
NULL
,
NULL
};
int
srcW
=
c
->
srcW
;
int
srcH
=
c
->
srcH
;
int
dstW
=
c
->
dstW
;
int
dstH
=
c
->
dstH
;
int
dst_stride
=
FFALIGN
(
dstW
*
sizeof
(
int16_t
)
+
16
,
16
);
int
dst_stride_px
=
dst_stride
>>
1
;
int
flags
,
cpu_flags
;
enum
PixelFormat
srcFormat
=
c
->
srcFormat
;
enum
PixelFormat
dstFormat
=
c
->
dstFormat
;
enum
PixelFormat
srcFormat
=
c
->
srcFormat
;
enum
PixelFormat
dstFormat
=
c
->
dstFormat
;
cpu_flags
=
av_get_cpu_flags
();
flags
=
c
->
flags
;
emms_c
();
if
(
!
rgb15to16
)
sws_rgb2rgb_init
();
if
(
!
rgb15to16
)
sws_rgb2rgb_init
();
unscaled
=
(
srcW
==
dstW
&&
srcH
==
dstH
);
if
(
!
sws_isSupportedInput
(
srcFormat
))
{
av_log
(
c
,
AV_LOG_ERROR
,
"%s is not supported as input pixel format
\n
"
,
sws_format_name
(
srcFormat
));
av_log
(
c
,
AV_LOG_ERROR
,
"%s is not supported as input pixel format
\n
"
,
sws_format_name
(
srcFormat
));
return
AVERROR
(
EINVAL
);
}
if
(
!
sws_isSupportedOutput
(
dstFormat
))
{
av_log
(
c
,
AV_LOG_ERROR
,
"%s is not supported as output pixel format
\n
"
,
sws_format_name
(
dstFormat
));
av_log
(
c
,
AV_LOG_ERROR
,
"%s is not supported as output pixel format
\n
"
,
sws_format_name
(
dstFormat
));
return
AVERROR
(
EINVAL
);
}
i
=
flags
&
(
SWS_POINT
|
SWS_AREA
|
SWS_BILINEAR
|
SWS_FAST_BILINEAR
|
SWS_BICUBIC
|
SWS_X
|
SWS_GAUSS
|
SWS_LANCZOS
|
SWS_SINC
|
SWS_SPLINE
|
SWS_BICUBLIN
);
if
(
!
i
||
(
i
&
(
i
-
1
)))
{
av_log
(
c
,
AV_LOG_ERROR
,
"Exactly one scaler algorithm must be chosen
\n
"
);
i
=
flags
&
(
SWS_POINT
|
SWS_AREA
|
SWS_BILINEAR
|
SWS_FAST_BILINEAR
|
SWS_BICUBIC
|
SWS_X
|
SWS_GAUSS
|
SWS_LANCZOS
|
SWS_SINC
|
SWS_SPLINE
|
SWS_BICUBLIN
);
if
(
!
i
||
(
i
&
(
i
-
1
)))
{
av_log
(
c
,
AV_LOG_ERROR
,
"Exactly one scaler algorithm must be chosen
\n
"
);
return
AVERROR
(
EINVAL
);
}
/* sanity check */
if
(
srcW
<
4
||
srcH
<
1
||
dstW
<
8
||
dstH
<
1
)
{
//FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code
if
(
srcW
<
4
||
srcH
<
1
||
dstW
<
8
||
dstH
<
1
)
{
/* FIXME check if these are enough and try to lower them after
* fixing the relevant parts of the code */
av_log
(
c
,
AV_LOG_ERROR
,
"%dx%d -> %dx%d is invalid scaling dimension
\n
"
,
srcW
,
srcH
,
dstW
,
dstH
);
return
AVERROR
(
EINVAL
);
}
if
(
!
dstFilter
)
dstFilter
=
&
dummyFilter
;
if
(
!
srcFilter
)
srcFilter
=
&
dummyFilter
;
if
(
!
dstFilter
)
dstFilter
=
&
dummyFilter
;
if
(
!
srcFilter
)
srcFilter
=
&
dummyFilter
;
c
->
lumXInc
=
(((
int64_t
)
srcW
<<
16
)
+
(
dstW
>>
1
))
/
dstW
;
c
->
lumYInc
=
(((
int64_t
)
srcH
<<
16
)
+
(
dstH
>>
1
))
/
dstH
;
c
->
lumXInc
=
(((
int64_t
)
srcW
<<
16
)
+
(
dstW
>>
1
))
/
dstW
;
c
->
lumYInc
=
(((
int64_t
)
srcH
<<
16
)
+
(
dstH
>>
1
))
/
dstH
;
c
->
dstFormatBpp
=
av_get_bits_per_pixel
(
&
av_pix_fmt_descriptors
[
dstFormat
]);
c
->
srcFormatBpp
=
av_get_bits_per_pixel
(
&
av_pix_fmt_descriptors
[
srcFormat
]);
c
->
vRounder
=
4
*
0x0001000100010001ULL
;
c
->
vRounder
=
4
*
0x0001000100010001ULL
;
usesVFilter
=
(
srcFilter
->
lumV
&&
srcFilter
->
lumV
->
length
>
1
)
||
(
srcFilter
->
chrV
&&
srcFilter
->
chrV
->
length
>
1
)
||
(
dstFilter
->
lumV
&&
dstFilter
->
lumV
->
length
>
1
)
||
(
dstFilter
->
chrV
&&
dstFilter
->
chrV
->
length
>
1
);
usesHFilter
=
(
srcFilter
->
lumH
&&
srcFilter
->
lumH
->
length
>
1
)
||
(
srcFilter
->
chrH
&&
srcFilter
->
chrH
->
length
>
1
)
||
(
dstFilter
->
lumH
&&
dstFilter
->
lumH
->
length
>
1
)
||
(
dstFilter
->
chrH
&&
dstFilter
->
chrH
->
length
>
1
);
usesVFilter
=
(
srcFilter
->
lumV
&&
srcFilter
->
lumV
->
length
>
1
)
||
(
srcFilter
->
chrV
&&
srcFilter
->
chrV
->
length
>
1
)
||
(
dstFilter
->
lumV
&&
dstFilter
->
lumV
->
length
>
1
)
||
(
dstFilter
->
chrV
&&
dstFilter
->
chrV
->
length
>
1
);
usesHFilter
=
(
srcFilter
->
lumH
&&
srcFilter
->
lumH
->
length
>
1
)
||
(
srcFilter
->
chrH
&&
srcFilter
->
chrH
->
length
>
1
)
||
(
dstFilter
->
lumH
&&
dstFilter
->
lumH
->
length
>
1
)
||
(
dstFilter
->
chrH
&&
dstFilter
->
chrH
->
length
>
1
);
getSubSampleFactors
(
&
c
->
chrSrcHSubSample
,
&
c
->
chrSrcVSubSample
,
srcFormat
);
getSubSampleFactors
(
&
c
->
chrDstHSubSample
,
&
c
->
chrDstVSubSample
,
dstFormat
);
// reuse chroma for 2 pixels RGB/BGR unless user wants full chroma interpolation
/* reuse chroma for 2 pixels RGB/BGR unless user wants full
* chroma interpolation */
if
(
flags
&
SWS_FULL_CHR_H_INT
&&
isAnyRGB
(
dstFormat
)
&&
dstFormat
!=
PIX_FMT_RGBA
&&
dstFormat
!=
PIX_FMT_ARGB
&&
dstFormat
!=
PIX_FMT_BGRA
&&
dstFormat
!=
PIX_FMT_ABGR
&&
isAnyRGB
(
dstFormat
)
&&
dstFormat
!=
PIX_FMT_RGBA
&&
dstFormat
!=
PIX_FMT_ARGB
&&
dstFormat
!=
PIX_FMT_BGRA
&&
dstFormat
!=
PIX_FMT_ABGR
&&
dstFormat
!=
PIX_FMT_RGB24
&&
dstFormat
!=
PIX_FMT_BGR24
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"full chroma interpolation for destination format '%s' not yet implemented
\n
"
,
sws_format_name
(
dstFormat
));
flags
&=
~
SWS_FULL_CHR_H_INT
;
flags
&=
~
SWS_FULL_CHR_H_INT
;
c
->
flags
=
flags
;
}
if
(
isAnyRGB
(
dstFormat
)
&&
!
(
flags
&
SWS_FULL_CHR_H_INT
))
c
->
chrDstHSubSample
=
1
;
if
(
isAnyRGB
(
dstFormat
)
&&
!
(
flags
&
SWS_FULL_CHR_H_INT
))
c
->
chrDstHSubSample
=
1
;
// drop some chroma lines if the user wants it
c
->
vChrDrop
=
(
flags
&
SWS_SRC_V_CHR_DROP_MASK
)
>>
SWS_SRC_V_CHR_DROP_SHIFT
;
c
->
chrSrcVSubSample
+=
c
->
vChrDrop
;
// drop every other pixel for chroma calculation unless user wants full chroma
if
(
isAnyRGB
(
srcFormat
)
&&
!
(
flags
&
SWS_FULL_CHR_H_INP
)
&&
srcFormat
!=
PIX_FMT_RGB8
&&
srcFormat
!=
PIX_FMT_BGR8
&&
srcFormat
!=
PIX_FMT_RGB4
&&
srcFormat
!=
PIX_FMT_BGR4
&&
srcFormat
!=
PIX_FMT_RGB4_BYTE
&&
srcFormat
!=
PIX_FMT_BGR4_BYTE
&&
((
dstW
>>
c
->
chrDstHSubSample
)
<=
(
srcW
>>
1
)
||
(
flags
&
SWS_FAST_BILINEAR
)))
c
->
chrSrcHSubSample
=
1
;
c
->
vChrDrop
=
(
flags
&
SWS_SRC_V_CHR_DROP_MASK
)
>>
SWS_SRC_V_CHR_DROP_SHIFT
;
c
->
chrSrcVSubSample
+=
c
->
vChrDrop
;
/* drop every other pixel for chroma calculation unless user
* wants full chroma */
if
(
isAnyRGB
(
srcFormat
)
&&
!
(
flags
&
SWS_FULL_CHR_H_INP
)
&&
srcFormat
!=
PIX_FMT_RGB8
&&
srcFormat
!=
PIX_FMT_BGR8
&&
srcFormat
!=
PIX_FMT_RGB4
&&
srcFormat
!=
PIX_FMT_BGR4
&&
srcFormat
!=
PIX_FMT_RGB4_BYTE
&&
srcFormat
!=
PIX_FMT_BGR4_BYTE
&&
((
dstW
>>
c
->
chrDstHSubSample
)
<=
(
srcW
>>
1
)
||
(
flags
&
SWS_FAST_BILINEAR
)))
c
->
chrSrcHSubSample
=
1
;
// Note the -((-x)>>y) is so that we always round toward +inf.
c
->
chrSrcW
=
-
((
-
srcW
)
>>
c
->
chrSrcHSubSample
);
c
->
chrSrcH
=
-
((
-
srcH
)
>>
c
->
chrSrcVSubSample
);
c
->
chrDstW
=
-
((
-
dstW
)
>>
c
->
chrDstHSubSample
);
c
->
chrDstH
=
-
((
-
dstH
)
>>
c
->
chrDstVSubSample
);
c
->
chrSrcW
=
-
((
-
srcW
)
>>
c
->
chrSrcHSubSample
);
c
->
chrSrcH
=
-
((
-
srcH
)
>>
c
->
chrSrcVSubSample
);
c
->
chrDstW
=
-
((
-
dstW
)
>>
c
->
chrDstHSubSample
);
c
->
chrDstH
=
-
((
-
dstH
)
>>
c
->
chrDstVSubSample
);
/* unscaled special cases */
if
(
unscaled
&&
!
usesHFilter
&&
!
usesVFilter
&&
(
c
->
srcRange
==
c
->
dstRange
||
isAnyRGB
(
dstFormat
)))
{
if
(
unscaled
&&
!
usesHFilter
&&
!
usesVFilter
&&
(
c
->
srcRange
==
c
->
dstRange
||
isAnyRGB
(
dstFormat
)))
{
ff_get_unscaled_swscale
(
c
);
if
(
c
->
swScale
)
{
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
c
,
AV_LOG_INFO
,
"using unscaled %s -> %s special converter
\n
"
,
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
c
,
AV_LOG_INFO
,
"using unscaled %s -> %s special converter
\n
"
,
sws_format_name
(
srcFormat
),
sws_format_name
(
dstFormat
));
return
0
;
}
...
...
@@ -886,35 +971,40 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
FF_ALLOC_OR_GOTO
(
c
,
c
->
formatConvBuffer
,
(
FFALIGN
(
srcW
,
16
)
*
2
*
FFALIGN
(
c
->
srcBpc
,
8
)
>>
3
)
+
16
,
fail
);
if
(
HAVE_MMX2
&&
cpu_flags
&
AV_CPU_FLAG_MMX2
&&
c
->
srcBpc
==
8
&&
c
->
dstBpc
<=
10
)
{
c
->
canMMX2BeUsed
=
(
dstW
>=
srcW
&&
(
dstW
&
31
)
==
0
&&
(
srcW
&
15
)
==
0
)
?
1
:
0
;
if
(
!
c
->
canMMX2BeUsed
&&
dstW
>=
srcW
&&
(
srcW
&
15
)
==
0
&&
(
flags
&
SWS_FAST_BILINEAR
))
{
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
c
,
AV_LOG_INFO
,
"output width is not a multiple of 32 -> no MMX2 scaler
\n
"
);
if
(
HAVE_MMX2
&&
cpu_flags
&
AV_CPU_FLAG_MMX2
&&
c
->
srcBpc
==
8
&&
c
->
dstBpc
<=
10
)
{
c
->
canMMX2BeUsed
=
(
dstW
>=
srcW
&&
(
dstW
&
31
)
==
0
&&
(
srcW
&
15
)
==
0
)
?
1
:
0
;
if
(
!
c
->
canMMX2BeUsed
&&
dstW
>=
srcW
&&
(
srcW
&
15
)
==
0
&&
(
flags
&
SWS_FAST_BILINEAR
))
{
if
(
flags
&
SWS_PRINT_INFO
)
av_log
(
c
,
AV_LOG_INFO
,
"output width is not a multiple of 32 -> no MMX2 scaler
\n
"
);
}
if
(
usesHFilter
)
c
->
canMMX2BeUsed
=
0
;
}
else
c
->
canMMX2BeUsed
=
0
;
c
->
chrXInc
=
(((
int64_t
)
c
->
chrSrcW
<<
16
)
+
(
c
->
chrDstW
>>
1
))
/
c
->
chrDstW
;
c
->
chrYInc
=
(((
int64_t
)
c
->
chrSrcH
<<
16
)
+
(
c
->
chrDstH
>>
1
))
/
c
->
chrDstH
;
// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst
// but only for the FAST_BILINEAR mode otherwise do correct scaling
// n-2 is the last chrominance sample available
// this is not perfect, but no one should notice the difference, the more correct variant
// would be like the vertical one, but that would require some special code for the
// first and last pixel
if
(
flags
&
SWS_FAST_BILINEAR
)
{
if
(
usesHFilter
)
c
->
canMMX2BeUsed
=
0
;
}
else
c
->
canMMX2BeUsed
=
0
;
c
->
chrXInc
=
(((
int64_t
)
c
->
chrSrcW
<<
16
)
+
(
c
->
chrDstW
>>
1
))
/
c
->
chrDstW
;
c
->
chrYInc
=
(((
int64_t
)
c
->
chrSrcH
<<
16
)
+
(
c
->
chrDstH
>>
1
))
/
c
->
chrDstH
;
/* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src
* to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do
* correct scaling.
* n-2 is the last chrominance sample available.
* This is not perfect, but no one should notice the difference, the more
* correct variant would be like the vertical one, but that would require
* some special code for the first and last pixel */
if
(
flags
&
SWS_FAST_BILINEAR
)
{
if
(
c
->
canMMX2BeUsed
)
{
c
->
lumXInc
+=
20
;
c
->
chrXInc
+=
20
;
c
->
lumXInc
+=
20
;
c
->
chrXInc
+=
20
;
}
//we don't use the x86 asm scaler if MMX is available
//
we don't use the x86 asm scaler if MMX is available
else
if
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
{
c
->
lumXInc
=
((
int64_t
)(
srcW
-
2
)
<<
16
)
/
(
dstW
-
2
)
-
20
;
c
->
chrXInc
=
((
int64_t
)(
c
->
chrSrcW
-
2
)
<<
16
)
/
(
c
->
chrDstW
-
2
)
-
20
;
c
->
lumXInc
=
((
int64_t
)(
srcW
-
2
)
<<
16
)
/
(
dstW
-
2
)
-
20
;
c
->
chrXInc
=
((
int64_t
)(
c
->
chrSrcW
-
2
)
<<
16
)
/
(
c
->
chrDstW
-
2
)
-
20
;
}
}
...
...
@@ -923,8 +1013,10 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
#if HAVE_MMX2
// can't downscale !!!
if
(
c
->
canMMX2BeUsed
&&
(
flags
&
SWS_FAST_BILINEAR
))
{
c
->
lumMmx2FilterCodeSize
=
initMMX2HScaler
(
dstW
,
c
->
lumXInc
,
NULL
,
NULL
,
NULL
,
8
);
c
->
chrMmx2FilterCodeSize
=
initMMX2HScaler
(
c
->
chrDstW
,
c
->
chrXInc
,
NULL
,
NULL
,
NULL
,
4
);
c
->
lumMmx2FilterCodeSize
=
initMMX2HScaler
(
dstW
,
c
->
lumXInc
,
NULL
,
NULL
,
NULL
,
8
);
c
->
chrMmx2FilterCodeSize
=
initMMX2HScaler
(
c
->
chrDstW
,
c
->
chrXInc
,
NULL
,
NULL
,
NULL
,
4
);
#ifdef MAP_ANONYMOUS
c
->
lumMmx2FilterCode
=
mmap
(
NULL
,
c
->
lumMmx2FilterCodeSize
,
PROT_READ
|
PROT_WRITE
,
MAP_PRIVATE
|
MAP_ANONYMOUS
,
-
1
,
0
);
...
...
@@ -939,13 +1031,15 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
if
(
!
c
->
lumMmx2FilterCode
||
!
c
->
chrMmx2FilterCode
)
return
AVERROR
(
ENOMEM
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hLumFilter
,
(
dstW
/
8
+
8
)
*
sizeof
(
int16_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hChrFilter
,
(
c
->
chrDstW
/
4
+
8
)
*
sizeof
(
int16_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hLumFilterPos
,
(
dstW
/
2
/
8
+
8
)
*
sizeof
(
int32_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hChrFilterPos
,
(
c
->
chrDstW
/
2
/
4
+
8
)
*
sizeof
(
int32_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hLumFilter
,
(
dstW
/
8
+
8
)
*
sizeof
(
int16_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hChrFilter
,
(
c
->
chrDstW
/
4
+
8
)
*
sizeof
(
int16_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hLumFilterPos
,
(
dstW
/
2
/
8
+
8
)
*
sizeof
(
int32_t
),
fail
);
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
hChrFilterPos
,
(
c
->
chrDstW
/
2
/
4
+
8
)
*
sizeof
(
int32_t
),
fail
);
initMMX2HScaler
(
dstW
,
c
->
lumXInc
,
c
->
lumMmx2FilterCode
,
c
->
hLumFilter
,
c
->
hLumFilterPos
,
8
);
initMMX2HScaler
(
c
->
chrDstW
,
c
->
chrXInc
,
c
->
chrMmx2FilterCode
,
c
->
hChrFilter
,
c
->
hChrFilterPos
,
4
);
initMMX2HScaler
(
dstW
,
c
->
lumXInc
,
c
->
lumMmx2FilterCode
,
c
->
hLumFilter
,
c
->
hLumFilterPos
,
8
);
initMMX2HScaler
(
c
->
chrDstW
,
c
->
chrXInc
,
c
->
chrMmx2FilterCode
,
c
->
hChrFilter
,
c
->
hChrFilterPos
,
4
);
#ifdef MAP_ANONYMOUS
mprotect
(
c
->
lumMmx2FilterCode
,
c
->
lumMmx2FilterCodeSize
,
PROT_EXEC
|
PROT_READ
);
...
...
@@ -954,182 +1048,221 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
}
else
#endif
/* HAVE_MMX2 */
{
const
int
filterAlign
=
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
?
4
:
const
int
filterAlign
=
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
?
4
:
(
HAVE_ALTIVEC
&&
cpu_flags
&
AV_CPU_FLAG_ALTIVEC
)
?
8
:
1
;
if
(
initFilter
(
&
c
->
hLumFilter
,
&
c
->
hLumFilterPos
,
&
c
->
hLumFilterSize
,
c
->
lumXInc
,
srcW
,
dstW
,
filterAlign
,
1
<<
14
,
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BICUBIC
)
:
flags
,
cpu_flags
,
srcFilter
->
lumH
,
dstFilter
->
lumH
,
c
->
param
,
1
)
<
0
)
if
(
initFilter
(
&
c
->
hLumFilter
,
&
c
->
hLumFilterPos
,
&
c
->
hLumFilterSize
,
c
->
lumXInc
,
srcW
,
dstW
,
filterAlign
,
1
<<
14
,
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BICUBIC
)
:
flags
,
cpu_flags
,
srcFilter
->
lumH
,
dstFilter
->
lumH
,
c
->
param
,
1
)
<
0
)
goto
fail
;
if
(
initFilter
(
&
c
->
hChrFilter
,
&
c
->
hChrFilterPos
,
&
c
->
hChrFilterSize
,
c
->
chrXInc
,
c
->
chrSrcW
,
c
->
chrDstW
,
filterAlign
,
1
<<
14
,
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BILINEAR
)
:
flags
,
cpu_flags
,
srcFilter
->
chrH
,
dstFilter
->
chrH
,
c
->
param
,
1
)
<
0
)
if
(
initFilter
(
&
c
->
hChrFilter
,
&
c
->
hChrFilterPos
,
&
c
->
hChrFilterSize
,
c
->
chrXInc
,
c
->
chrSrcW
,
c
->
chrDstW
,
filterAlign
,
1
<<
14
,
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BILINEAR
)
:
flags
,
cpu_flags
,
srcFilter
->
chrH
,
dstFilter
->
chrH
,
c
->
param
,
1
)
<
0
)
goto
fail
;
}
}
// initialize horizontal stuff
/* precalculate vertical scaler filter coefficients */
{
const
int
filterAlign
=
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
?
2
:
const
int
filterAlign
=
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
?
2
:
(
HAVE_ALTIVEC
&&
cpu_flags
&
AV_CPU_FLAG_ALTIVEC
)
?
8
:
1
;
if
(
initFilter
(
&
c
->
vLumFilter
,
&
c
->
vLumFilterPos
,
&
c
->
vLumFilterSize
,
c
->
lumYInc
,
srcH
,
dstH
,
filterAlign
,
(
1
<<
12
),
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BICUBIC
)
:
flags
,
cpu_flags
,
srcFilter
->
lumV
,
dstFilter
->
lumV
,
c
->
param
,
0
)
<
0
)
if
(
initFilter
(
&
c
->
vLumFilter
,
&
c
->
vLumFilterPos
,
&
c
->
vLumFilterSize
,
c
->
lumYInc
,
srcH
,
dstH
,
filterAlign
,
(
1
<<
12
),
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BICUBIC
)
:
flags
,
cpu_flags
,
srcFilter
->
lumV
,
dstFilter
->
lumV
,
c
->
param
,
0
)
<
0
)
goto
fail
;
if
(
initFilter
(
&
c
->
vChrFilter
,
&
c
->
vChrFilterPos
,
&
c
->
vChrFilterSize
,
c
->
chrYInc
,
c
->
chrSrcH
,
c
->
chrDstH
,
filterAlign
,
(
1
<<
12
),
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BILINEAR
)
:
flags
,
cpu_flags
,
srcFilter
->
chrV
,
dstFilter
->
chrV
,
c
->
param
,
0
)
<
0
)
if
(
initFilter
(
&
c
->
vChrFilter
,
&
c
->
vChrFilterPos
,
&
c
->
vChrFilterSize
,
c
->
chrYInc
,
c
->
chrSrcH
,
c
->
chrDstH
,
filterAlign
,
(
1
<<
12
),
(
flags
&
SWS_BICUBLIN
)
?
(
flags
|
SWS_BILINEAR
)
:
flags
,
cpu_flags
,
srcFilter
->
chrV
,
dstFilter
->
chrV
,
c
->
param
,
0
)
<
0
)
goto
fail
;
#if HAVE_ALTIVEC
FF_ALLOC_OR_GOTO
(
c
,
c
->
vYCoeffsBank
,
sizeof
(
vector
signed
short
)
*
c
->
vLumFilterSize
*
c
->
dstH
,
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
vCCoeffsBank
,
sizeof
(
vector
signed
short
)
*
c
->
vChrFilterSize
*
c
->
chrDstH
,
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
vYCoeffsBank
,
sizeof
(
vector
signed
short
)
*
c
->
vLumFilterSize
*
c
->
dstH
,
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
vCCoeffsBank
,
sizeof
(
vector
signed
short
)
*
c
->
vChrFilterSize
*
c
->
chrDstH
,
fail
);
for
(
i
=
0
;
i
<
c
->
vLumFilterSize
*
c
->
dstH
;
i
++
)
{
for
(
i
=
0
;
i
<
c
->
vLumFilterSize
*
c
->
dstH
;
i
++
)
{
int
j
;
short
*
p
=
(
short
*
)
&
c
->
vYCoeffsBank
[
i
];
for
(
j
=
0
;
j
<
8
;
j
++
)
for
(
j
=
0
;
j
<
8
;
j
++
)
p
[
j
]
=
c
->
vLumFilter
[
i
];
}
for
(
i
=
0
;
i
<
c
->
vChrFilterSize
*
c
->
chrDstH
;
i
++
)
{
for
(
i
=
0
;
i
<
c
->
vChrFilterSize
*
c
->
chrDstH
;
i
++
)
{
int
j
;
short
*
p
=
(
short
*
)
&
c
->
vCCoeffsBank
[
i
];
for
(
j
=
0
;
j
<
8
;
j
++
)
for
(
j
=
0
;
j
<
8
;
j
++
)
p
[
j
]
=
c
->
vChrFilter
[
i
];
}
#endif
}
// calculate buffer sizes so that they won't run out while handling these damn slices
c
->
vLumBufSize
=
c
->
vLumFilterSize
;
c
->
vChrBufSize
=
c
->
vChrFilterSize
;
for
(
i
=
0
;
i
<
dstH
;
i
++
)
{
int
chrI
=
(
int64_t
)
i
*
c
->
chrDstH
/
dstH
;
int
nextSlice
=
FFMAX
(
c
->
vLumFilterPos
[
i
]
+
c
->
vLumFilterSize
-
1
,
((
c
->
vChrFilterPos
[
chrI
]
+
c
->
vChrFilterSize
-
1
)
<<
c
->
chrSrcVSubSample
));
nextSlice
>>=
c
->
chrSrcVSubSample
;
nextSlice
<<=
c
->
chrSrcVSubSample
;
if
(
c
->
vLumFilterPos
[
i
]
+
c
->
vLumBufSize
<
nextSlice
)
c
->
vLumBufSize
=
nextSlice
-
c
->
vLumFilterPos
[
i
];
if
(
c
->
vChrFilterPos
[
chrI
]
+
c
->
vChrBufSize
<
(
nextSlice
>>
c
->
chrSrcVSubSample
))
c
->
vChrBufSize
=
(
nextSlice
>>
c
->
chrSrcVSubSample
)
-
c
->
vChrFilterPos
[
chrI
];
c
->
vLumBufSize
=
c
->
vLumFilterSize
;
c
->
vChrBufSize
=
c
->
vChrFilterSize
;
for
(
i
=
0
;
i
<
dstH
;
i
++
)
{
int
chrI
=
(
int64_t
)
i
*
c
->
chrDstH
/
dstH
;
int
nextSlice
=
FFMAX
(
c
->
vLumFilterPos
[
i
]
+
c
->
vLumFilterSize
-
1
,
((
c
->
vChrFilterPos
[
chrI
]
+
c
->
vChrFilterSize
-
1
)
<<
c
->
chrSrcVSubSample
));
nextSlice
>>=
c
->
chrSrcVSubSample
;
nextSlice
<<=
c
->
chrSrcVSubSample
;
if
(
c
->
vLumFilterPos
[
i
]
+
c
->
vLumBufSize
<
nextSlice
)
c
->
vLumBufSize
=
nextSlice
-
c
->
vLumFilterPos
[
i
];
if
(
c
->
vChrFilterPos
[
chrI
]
+
c
->
vChrBufSize
<
(
nextSlice
>>
c
->
chrSrcVSubSample
))
c
->
vChrBufSize
=
(
nextSlice
>>
c
->
chrSrcVSubSample
)
-
c
->
vChrFilterPos
[
chrI
];
}
/
/ allocate pixbufs (we use dynamic allocation because otherwise we would need to
// allocate several megabytes to handle all possible cases)
FF_ALLOC_OR_GOTO
(
c
,
c
->
lumPixBuf
,
c
->
vLumBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrUPixBuf
,
c
->
vChrBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrVPixBuf
,
c
->
vChrBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
/
* Allocate pixbufs (we use dynamic allocation because otherwise we would
* need to allocate several megabytes to handle all possible cases) */
FF_ALLOC_OR_GOTO
(
c
,
c
->
lumPixBuf
,
c
->
vLumBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrUPixBuf
,
c
->
vChrBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrVPixBuf
,
c
->
vChrBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
if
(
CONFIG_SWSCALE_ALPHA
&&
isALPHA
(
c
->
srcFormat
)
&&
isALPHA
(
c
->
dstFormat
))
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
alpPixBuf
,
c
->
vLumBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
//Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000)
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
alpPixBuf
,
c
->
vLumBufSize
*
3
*
sizeof
(
int16_t
*
),
fail
);
/* Note we need at least one pixel more at the end because of the MMX code
* (just in case someone wants to replace the 4000/8000). */
/* align at 16 bytes for AltiVec */
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
{
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
lumPixBuf
[
i
+
c
->
vLumBufSize
],
dst_stride
+
16
,
fail
);
c
->
lumPixBuf
[
i
]
=
c
->
lumPixBuf
[
i
+
c
->
vLumBufSize
];
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
{
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
lumPixBuf
[
i
+
c
->
vLumBufSize
],
dst_stride
+
16
,
fail
);
c
->
lumPixBuf
[
i
]
=
c
->
lumPixBuf
[
i
+
c
->
vLumBufSize
];
}
// 64 / (c->dstBpc & ~7) is the same as 16 / sizeof(scaling_intermediate)
c
->
uv_off_px
=
dst_stride_px
+
64
/
(
c
->
dstBpc
&
~
7
);
c
->
uv_off_px
=
dst_stride_px
+
64
/
(
c
->
dstBpc
&
~
7
);
c
->
uv_off_byte
=
dst_stride
+
16
;
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
{
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrUPixBuf
[
i
+
c
->
vChrBufSize
],
dst_stride
*
2
+
32
,
fail
);
c
->
chrUPixBuf
[
i
]
=
c
->
chrUPixBuf
[
i
+
c
->
vChrBufSize
];
c
->
chrVPixBuf
[
i
]
=
c
->
chrVPixBuf
[
i
+
c
->
vChrBufSize
]
=
c
->
chrUPixBuf
[
i
]
+
(
dst_stride
>>
1
)
+
8
;
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
{
FF_ALLOC_OR_GOTO
(
c
,
c
->
chrUPixBuf
[
i
+
c
->
vChrBufSize
],
dst_stride
*
2
+
32
,
fail
);
c
->
chrUPixBuf
[
i
]
=
c
->
chrUPixBuf
[
i
+
c
->
vChrBufSize
];
c
->
chrVPixBuf
[
i
]
=
c
->
chrVPixBuf
[
i
+
c
->
vChrBufSize
]
=
c
->
chrUPixBuf
[
i
]
+
(
dst_stride
>>
1
)
+
8
;
}
if
(
CONFIG_SWSCALE_ALPHA
&&
c
->
alpPixBuf
)
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
{
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
alpPixBuf
[
i
+
c
->
vLumBufSize
],
dst_stride
+
16
,
fail
);
c
->
alpPixBuf
[
i
]
=
c
->
alpPixBuf
[
i
+
c
->
vLumBufSize
];
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
{
FF_ALLOCZ_OR_GOTO
(
c
,
c
->
alpPixBuf
[
i
+
c
->
vLumBufSize
],
dst_stride
+
16
,
fail
);
c
->
alpPixBuf
[
i
]
=
c
->
alpPixBuf
[
i
+
c
->
vLumBufSize
];
}
//try to avoid drawing green stuff between the right end and the stride end
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
memset
(
c
->
chrUPixBuf
[
i
],
64
,
dst_stride
*
2
+
1
);
//
try to avoid drawing green stuff between the right end and the stride end
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
memset
(
c
->
chrUPixBuf
[
i
],
64
,
dst_stride
*
2
+
1
);
assert
(
c
->
chrDstH
<=
dstH
);
if
(
flags
&
SWS_PRINT_INFO
)
{
if
(
flags
&
SWS_FAST_BILINEAR
)
av_log
(
c
,
AV_LOG_INFO
,
"FAST_BILINEAR scaler, "
);
else
if
(
flags
&
SWS_BILINEAR
)
av_log
(
c
,
AV_LOG_INFO
,
"BILINEAR scaler, "
);
else
if
(
flags
&
SWS_BICUBIC
)
av_log
(
c
,
AV_LOG_INFO
,
"BICUBIC scaler, "
);
else
if
(
flags
&
SWS_X
)
av_log
(
c
,
AV_LOG_INFO
,
"Experimental scaler, "
);
else
if
(
flags
&
SWS_POINT
)
av_log
(
c
,
AV_LOG_INFO
,
"Nearest Neighbor / POINT scaler, "
);
else
if
(
flags
&
SWS_AREA
)
av_log
(
c
,
AV_LOG_INFO
,
"Area Averaging scaler, "
);
else
if
(
flags
&
SWS_BICUBLIN
)
av_log
(
c
,
AV_LOG_INFO
,
"luma BICUBIC / chroma BILINEAR scaler, "
);
else
if
(
flags
&
SWS_GAUSS
)
av_log
(
c
,
AV_LOG_INFO
,
"Gaussian scaler, "
);
else
if
(
flags
&
SWS_SINC
)
av_log
(
c
,
AV_LOG_INFO
,
"Sinc scaler, "
);
else
if
(
flags
&
SWS_LANCZOS
)
av_log
(
c
,
AV_LOG_INFO
,
"Lanczos scaler, "
);
else
if
(
flags
&
SWS_SPLINE
)
av_log
(
c
,
AV_LOG_INFO
,
"Bicubic spline scaler, "
);
else
av_log
(
c
,
AV_LOG_INFO
,
"ehh flags invalid?! "
);
if
(
flags
&
SWS_PRINT_INFO
)
{
if
(
flags
&
SWS_FAST_BILINEAR
)
av_log
(
c
,
AV_LOG_INFO
,
"FAST_BILINEAR scaler, "
);
else
if
(
flags
&
SWS_BILINEAR
)
av_log
(
c
,
AV_LOG_INFO
,
"BILINEAR scaler, "
);
else
if
(
flags
&
SWS_BICUBIC
)
av_log
(
c
,
AV_LOG_INFO
,
"BICUBIC scaler, "
);
else
if
(
flags
&
SWS_X
)
av_log
(
c
,
AV_LOG_INFO
,
"Experimental scaler, "
);
else
if
(
flags
&
SWS_POINT
)
av_log
(
c
,
AV_LOG_INFO
,
"Nearest Neighbor / POINT scaler, "
);
else
if
(
flags
&
SWS_AREA
)
av_log
(
c
,
AV_LOG_INFO
,
"Area Averaging scaler, "
);
else
if
(
flags
&
SWS_BICUBLIN
)
av_log
(
c
,
AV_LOG_INFO
,
"luma BICUBIC / chroma BILINEAR scaler, "
);
else
if
(
flags
&
SWS_GAUSS
)
av_log
(
c
,
AV_LOG_INFO
,
"Gaussian scaler, "
);
else
if
(
flags
&
SWS_SINC
)
av_log
(
c
,
AV_LOG_INFO
,
"Sinc scaler, "
);
else
if
(
flags
&
SWS_LANCZOS
)
av_log
(
c
,
AV_LOG_INFO
,
"Lanczos scaler, "
);
else
if
(
flags
&
SWS_SPLINE
)
av_log
(
c
,
AV_LOG_INFO
,
"Bicubic spline scaler, "
);
else
av_log
(
c
,
AV_LOG_INFO
,
"ehh flags invalid?! "
);
av_log
(
c
,
AV_LOG_INFO
,
"from %s to %s%s "
,
sws_format_name
(
srcFormat
),
#ifdef DITHER1XBPP
dstFormat
==
PIX_FMT_BGR555
||
dstFormat
==
PIX_FMT_BGR565
||
dstFormat
==
PIX_FMT_BGR555
||
dstFormat
==
PIX_FMT_BGR565
||
dstFormat
==
PIX_FMT_RGB444BE
||
dstFormat
==
PIX_FMT_RGB444LE
||
dstFormat
==
PIX_FMT_BGR444BE
||
dstFormat
==
PIX_FMT_BGR444LE
?
"dithered "
:
""
,
dstFormat
==
PIX_FMT_BGR444BE
||
dstFormat
==
PIX_FMT_BGR444LE
?
"dithered "
:
""
,
#else
""
,
#endif
sws_format_name
(
dstFormat
));
if
(
HAVE_MMX2
&&
cpu_flags
&
AV_CPU_FLAG_MMX2
)
av_log
(
c
,
AV_LOG_INFO
,
"using MMX2
\n
"
);
else
if
(
HAVE_AMD3DNOW
&&
cpu_flags
&
AV_CPU_FLAG_3DNOW
)
av_log
(
c
,
AV_LOG_INFO
,
"using 3DNOW
\n
"
);
else
if
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
av_log
(
c
,
AV_LOG_INFO
,
"using MMX
\n
"
);
else
if
(
HAVE_ALTIVEC
&&
cpu_flags
&
AV_CPU_FLAG_ALTIVEC
)
av_log
(
c
,
AV_LOG_INFO
,
"using AltiVec
\n
"
);
else
av_log
(
c
,
AV_LOG_INFO
,
"using C
\n
"
);
if
(
HAVE_MMX2
&&
cpu_flags
&
AV_CPU_FLAG_MMX2
)
av_log
(
c
,
AV_LOG_INFO
,
"using MMX2
\n
"
);
else
if
(
HAVE_AMD3DNOW
&&
cpu_flags
&
AV_CPU_FLAG_3DNOW
)
av_log
(
c
,
AV_LOG_INFO
,
"using 3DNOW
\n
"
);
else
if
(
HAVE_MMX
&&
cpu_flags
&
AV_CPU_FLAG_MMX
)
av_log
(
c
,
AV_LOG_INFO
,
"using MMX
\n
"
);
else
if
(
HAVE_ALTIVEC
&&
cpu_flags
&
AV_CPU_FLAG_ALTIVEC
)
av_log
(
c
,
AV_LOG_INFO
,
"using AltiVec
\n
"
);
else
av_log
(
c
,
AV_LOG_INFO
,
"using C
\n
"
);
av_log
(
c
,
AV_LOG_VERBOSE
,
"%dx%d -> %dx%d
\n
"
,
srcW
,
srcH
,
dstW
,
dstH
);
av_log
(
c
,
AV_LOG_DEBUG
,
"lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d
\n
"
,
av_log
(
c
,
AV_LOG_DEBUG
,
"lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d
\n
"
,
c
->
srcW
,
c
->
srcH
,
c
->
dstW
,
c
->
dstH
,
c
->
lumXInc
,
c
->
lumYInc
);
av_log
(
c
,
AV_LOG_DEBUG
,
"chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d
\n
"
,
c
->
chrSrcW
,
c
->
chrSrcH
,
c
->
chrDstW
,
c
->
chrDstH
,
c
->
chrXInc
,
c
->
chrYInc
);
av_log
(
c
,
AV_LOG_DEBUG
,
"chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d
\n
"
,
c
->
chrSrcW
,
c
->
chrSrcH
,
c
->
chrDstW
,
c
->
chrDstH
,
c
->
chrXInc
,
c
->
chrYInc
);
}
c
->
swScale
=
ff_getSwsFunc
(
c
);
c
->
swScale
=
ff_getSwsFunc
(
c
);
return
0
;
fail:
//FIXME replace things by appropriate error codes
fail:
//
FIXME replace things by appropriate error codes
return
-
1
;
}
#if FF_API_SWS_GETCONTEXT
SwsContext
*
sws_getContext
(
int
srcW
,
int
srcH
,
enum
PixelFormat
srcFormat
,
int
dstW
,
int
dstH
,
enum
PixelFormat
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
const
double
*
param
)
int
dstW
,
int
dstH
,
enum
PixelFormat
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
const
double
*
param
)
{
SwsContext
*
c
;
if
(
!
(
c
=
sws_alloc_context
()))
if
(
!
(
c
=
sws_alloc_context
()))
return
NULL
;
c
->
flags
=
flags
;
c
->
srcW
=
srcW
;
c
->
srcH
=
srcH
;
c
->
dstW
=
dstW
;
c
->
dstH
=
dstH
;
c
->
srcRange
=
handle_jpeg
(
&
srcFormat
);
c
->
dstRange
=
handle_jpeg
(
&
dstFormat
);
c
->
srcFormat
=
srcFormat
;
c
->
dstFormat
=
dstFormat
;
c
->
flags
=
flags
;
c
->
srcW
=
srcW
;
c
->
srcH
=
srcH
;
c
->
dstW
=
dstW
;
c
->
dstH
=
dstH
;
c
->
srcRange
=
handle_jpeg
(
&
srcFormat
);
c
->
dstRange
=
handle_jpeg
(
&
dstFormat
);
c
->
srcFormat
=
srcFormat
;
c
->
dstFormat
=
dstFormat
;
if
(
param
)
{
c
->
param
[
0
]
=
param
[
0
];
c
->
param
[
1
]
=
param
[
1
];
}
sws_setColorspaceDetails
(
c
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
],
c
->
srcRange
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
]
/* FIXME*/
,
c
->
dstRange
,
0
,
1
<<
16
,
1
<<
16
);
sws_setColorspaceDetails
(
c
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
],
c
->
srcRange
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
]
/* FIXME*/
,
c
->
dstRange
,
0
,
1
<<
16
,
1
<<
16
);
if
(
sws_init_context
(
c
,
srcFilter
,
dstFilter
)
<
0
)
{
if
(
sws_init_context
(
c
,
srcFilter
,
dstFilter
)
<
0
)
{
sws_freeContext
(
c
);
return
NULL
;
}
...
...
@@ -1143,28 +1276,28 @@ SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
float
chromaHShift
,
float
chromaVShift
,
int
verbose
)
{
SwsFilter
*
filter
=
av_malloc
(
sizeof
(
SwsFilter
));
SwsFilter
*
filter
=
av_malloc
(
sizeof
(
SwsFilter
));
if
(
!
filter
)
return
NULL
;
if
(
lumaGBlur
!=
0
.
0
)
{
filter
->
lumH
=
sws_getGaussianVec
(
lumaGBlur
,
3
.
0
);
filter
->
lumV
=
sws_getGaussianVec
(
lumaGBlur
,
3
.
0
);
if
(
lumaGBlur
!=
0
.
0
)
{
filter
->
lumH
=
sws_getGaussianVec
(
lumaGBlur
,
3
.
0
);
filter
->
lumV
=
sws_getGaussianVec
(
lumaGBlur
,
3
.
0
);
}
else
{
filter
->
lumH
=
sws_getIdentityVec
();
filter
->
lumV
=
sws_getIdentityVec
();
filter
->
lumH
=
sws_getIdentityVec
();
filter
->
lumV
=
sws_getIdentityVec
();
}
if
(
chromaGBlur
!=
0
.
0
)
{
filter
->
chrH
=
sws_getGaussianVec
(
chromaGBlur
,
3
.
0
);
filter
->
chrV
=
sws_getGaussianVec
(
chromaGBlur
,
3
.
0
);
if
(
chromaGBlur
!=
0
.
0
)
{
filter
->
chrH
=
sws_getGaussianVec
(
chromaGBlur
,
3
.
0
);
filter
->
chrV
=
sws_getGaussianVec
(
chromaGBlur
,
3
.
0
);
}
else
{
filter
->
chrH
=
sws_getIdentityVec
();
filter
->
chrV
=
sws_getIdentityVec
();
filter
->
chrH
=
sws_getIdentityVec
();
filter
->
chrV
=
sws_getIdentityVec
();
}
if
(
chromaSharpen
!=
0
.
0
)
{
SwsVector
*
id
=
sws_getIdentityVec
();
if
(
chromaSharpen
!=
0
.
0
)
{
SwsVector
*
id
=
sws_getIdentityVec
();
sws_scaleVec
(
filter
->
chrH
,
-
chromaSharpen
);
sws_scaleVec
(
filter
->
chrV
,
-
chromaSharpen
);
sws_addVec
(
filter
->
chrH
,
id
);
...
...
@@ -1172,8 +1305,8 @@ SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
sws_freeVec
(
id
);
}
if
(
lumaSharpen
!=
0
.
0
)
{
SwsVector
*
id
=
sws_getIdentityVec
();
if
(
lumaSharpen
!=
0
.
0
)
{
SwsVector
*
id
=
sws_getIdentityVec
();
sws_scaleVec
(
filter
->
lumH
,
-
lumaSharpen
);
sws_scaleVec
(
filter
->
lumV
,
-
lumaSharpen
);
sws_addVec
(
filter
->
lumH
,
id
);
...
...
@@ -1182,18 +1315,20 @@ SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
}
if
(
chromaHShift
!=
0
.
0
)
sws_shiftVec
(
filter
->
chrH
,
(
int
)(
chromaHShift
+
0
.
5
));
sws_shiftVec
(
filter
->
chrH
,
(
int
)(
chromaHShift
+
0
.
5
));
if
(
chromaVShift
!=
0
.
0
)
sws_shiftVec
(
filter
->
chrV
,
(
int
)(
chromaVShift
+
0
.
5
));
sws_shiftVec
(
filter
->
chrV
,
(
int
)(
chromaVShift
+
0
.
5
));
sws_normalizeVec
(
filter
->
chrH
,
1
.
0
);
sws_normalizeVec
(
filter
->
chrV
,
1
.
0
);
sws_normalizeVec
(
filter
->
lumH
,
1
.
0
);
sws_normalizeVec
(
filter
->
lumV
,
1
.
0
);
if
(
verbose
)
sws_printVec2
(
filter
->
chrH
,
NULL
,
AV_LOG_DEBUG
);
if
(
verbose
)
sws_printVec2
(
filter
->
lumH
,
NULL
,
AV_LOG_DEBUG
);
if
(
verbose
)
sws_printVec2
(
filter
->
chrH
,
NULL
,
AV_LOG_DEBUG
);
if
(
verbose
)
sws_printVec2
(
filter
->
lumH
,
NULL
,
AV_LOG_DEBUG
);
return
filter
;
}
...
...
@@ -1212,17 +1347,18 @@ SwsVector *sws_allocVec(int length)
SwsVector
*
sws_getGaussianVec
(
double
variance
,
double
quality
)
{
const
int
length
=
(
int
)(
variance
*
quality
+
0
.
5
)
|
1
;
const
int
length
=
(
int
)(
variance
*
quality
+
0
.
5
)
|
1
;
int
i
;
double
middle
=
(
length
-
1
)
*
0
.
5
;
SwsVector
*
vec
=
sws_allocVec
(
length
);
double
middle
=
(
length
-
1
)
*
0
.
5
;
SwsVector
*
vec
=
sws_allocVec
(
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
length
;
i
++
)
{
double
dist
=
i
-
middle
;
vec
->
coeff
[
i
]
=
exp
(
-
dist
*
dist
/
(
2
*
variance
*
variance
))
/
sqrt
(
2
*
variance
*
M_PI
);
for
(
i
=
0
;
i
<
length
;
i
++
)
{
double
dist
=
i
-
middle
;
vec
->
coeff
[
i
]
=
exp
(
-
dist
*
dist
/
(
2
*
variance
*
variance
))
/
sqrt
(
2
*
variance
*
M_PI
);
}
sws_normalizeVec
(
vec
,
1
.
0
);
...
...
@@ -1233,13 +1369,13 @@ SwsVector *sws_getGaussianVec(double variance, double quality)
SwsVector
*
sws_getConstVec
(
double
c
,
int
length
)
{
int
i
;
SwsVector
*
vec
=
sws_allocVec
(
length
);
SwsVector
*
vec
=
sws_allocVec
(
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
length
;
i
++
)
vec
->
coeff
[
i
]
=
c
;
for
(
i
=
0
;
i
<
length
;
i
++
)
vec
->
coeff
[
i
]
=
c
;
return
vec
;
}
...
...
@@ -1252,10 +1388,10 @@ SwsVector *sws_getIdentityVec(void)
static
double
sws_dcVec
(
SwsVector
*
a
)
{
int
i
;
double
sum
=
0
;
double
sum
=
0
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
sum
+=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
sum
+=
a
->
coeff
[
i
];
return
sum
;
}
...
...
@@ -1264,27 +1400,27 @@ void sws_scaleVec(SwsVector *a, double scalar)
{
int
i
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
a
->
coeff
[
i
]
*=
scalar
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
a
->
coeff
[
i
]
*=
scalar
;
}
void
sws_normalizeVec
(
SwsVector
*
a
,
double
height
)
{
sws_scaleVec
(
a
,
height
/
sws_dcVec
(
a
));
sws_scaleVec
(
a
,
height
/
sws_dcVec
(
a
));
}
static
SwsVector
*
sws_getConvVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
int
length
=
a
->
length
+
b
->
length
-
1
;
int
length
=
a
->
length
+
b
->
length
-
1
;
int
i
,
j
;
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
for
(
j
=
0
;
j
<
b
->
length
;
j
++
)
{
vec
->
coeff
[
i
+
j
]
+=
a
->
coeff
[
i
]
*
b
->
coeff
[
j
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
for
(
j
=
0
;
j
<
b
->
length
;
j
++
)
{
vec
->
coeff
[
i
+
j
]
+=
a
->
coeff
[
i
]
*
b
->
coeff
[
j
];
}
}
...
...
@@ -1293,30 +1429,34 @@ static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b)
static
SwsVector
*
sws_sumVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
int
length
=
FFMAX
(
a
->
length
,
b
->
length
);
int
length
=
FFMAX
(
a
->
length
,
b
->
length
);
int
i
;
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
]
+=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
b
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
b
->
length
-
1
)
/
2
]
+=
b
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
]
+=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
b
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
b
->
length
-
1
)
/
2
]
+=
b
->
coeff
[
i
];
return
vec
;
}
static
SwsVector
*
sws_diffVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
int
length
=
FFMAX
(
a
->
length
,
b
->
length
);
int
length
=
FFMAX
(
a
->
length
,
b
->
length
);
int
i
;
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
]
+=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
b
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
b
->
length
-
1
)
/
2
]
-=
b
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
]
+=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
b
->
length
;
i
++
)
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
b
->
length
-
1
)
/
2
]
-=
b
->
coeff
[
i
];
return
vec
;
}
...
...
@@ -1324,15 +1464,16 @@ static SwsVector *sws_diffVec(SwsVector *a, SwsVector *b)
/* shift left / or right if "shift" is negative */
static
SwsVector
*
sws_getShiftedVec
(
SwsVector
*
a
,
int
shift
)
{
int
length
=
a
->
length
+
FFABS
(
shift
)
*
2
;
int
length
=
a
->
length
+
FFABS
(
shift
)
*
2
;
int
i
;
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
SwsVector
*
vec
=
sws_getConstVec
(
0
.
0
,
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
-
shift
]
=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
vec
->
coeff
[
i
+
(
length
-
1
)
/
2
-
(
a
->
length
-
1
)
/
2
-
shift
]
=
a
->
coeff
[
i
];
}
return
vec
;
...
...
@@ -1340,49 +1481,50 @@ static SwsVector *sws_getShiftedVec(SwsVector *a, int shift)
void
sws_shiftVec
(
SwsVector
*
a
,
int
shift
)
{
SwsVector
*
shifted
=
sws_getShiftedVec
(
a
,
shift
);
SwsVector
*
shifted
=
sws_getShiftedVec
(
a
,
shift
);
av_free
(
a
->
coeff
);
a
->
coeff
=
shifted
->
coeff
;
a
->
length
=
shifted
->
length
;
a
->
coeff
=
shifted
->
coeff
;
a
->
length
=
shifted
->
length
;
av_free
(
shifted
);
}
void
sws_addVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
SwsVector
*
sum
=
sws_sumVec
(
a
,
b
);
SwsVector
*
sum
=
sws_sumVec
(
a
,
b
);
av_free
(
a
->
coeff
);
a
->
coeff
=
sum
->
coeff
;
a
->
length
=
sum
->
length
;
a
->
coeff
=
sum
->
coeff
;
a
->
length
=
sum
->
length
;
av_free
(
sum
);
}
void
sws_subVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
SwsVector
*
diff
=
sws_diffVec
(
a
,
b
);
SwsVector
*
diff
=
sws_diffVec
(
a
,
b
);
av_free
(
a
->
coeff
);
a
->
coeff
=
diff
->
coeff
;
a
->
length
=
diff
->
length
;
a
->
coeff
=
diff
->
coeff
;
a
->
length
=
diff
->
length
;
av_free
(
diff
);
}
void
sws_convVec
(
SwsVector
*
a
,
SwsVector
*
b
)
{
SwsVector
*
conv
=
sws_getConvVec
(
a
,
b
);
SwsVector
*
conv
=
sws_getConvVec
(
a
,
b
);
av_free
(
a
->
coeff
);
a
->
coeff
=
conv
->
coeff
;
a
->
length
=
conv
->
length
;
a
->
coeff
=
conv
->
coeff
;
a
->
length
=
conv
->
length
;
av_free
(
conv
);
}
SwsVector
*
sws_cloneVec
(
SwsVector
*
a
)
{
int
i
;
SwsVector
*
vec
=
sws_allocVec
(
a
->
length
);
SwsVector
*
vec
=
sws_allocVec
(
a
->
length
);
if
(
!
vec
)
return
NULL
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
]
=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
vec
->
coeff
[
i
]
=
a
->
coeff
[
i
];
return
vec
;
}
...
...
@@ -1390,65 +1532,75 @@ SwsVector *sws_cloneVec(SwsVector *a)
void
sws_printVec2
(
SwsVector
*
a
,
AVClass
*
log_ctx
,
int
log_level
)
{
int
i
;
double
max
=
0
;
double
min
=
0
;
double
max
=
0
;
double
min
=
0
;
double
range
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
if
(
a
->
coeff
[
i
]
>
max
)
max
=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
if
(
a
->
coeff
[
i
]
>
max
)
max
=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
if
(
a
->
coeff
[
i
]
<
min
)
min
=
a
->
coeff
[
i
];
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
if
(
a
->
coeff
[
i
]
<
min
)
min
=
a
->
coeff
[
i
];
range
=
max
-
min
;
range
=
max
-
min
;
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
int
x
=
(
int
)((
a
->
coeff
[
i
]
-
min
)
*
60
.
0
/
range
+
0
.
5
);
for
(
i
=
0
;
i
<
a
->
length
;
i
++
)
{
int
x
=
(
int
)((
a
->
coeff
[
i
]
-
min
)
*
60
.
0
/
range
+
0
.
5
);
av_log
(
log_ctx
,
log_level
,
"%1.3f "
,
a
->
coeff
[
i
]);
for
(;
x
>
0
;
x
--
)
av_log
(
log_ctx
,
log_level
,
" "
);
for
(;
x
>
0
;
x
--
)
av_log
(
log_ctx
,
log_level
,
" "
);
av_log
(
log_ctx
,
log_level
,
"|
\n
"
);
}
}
void
sws_freeVec
(
SwsVector
*
a
)
{
if
(
!
a
)
return
;
if
(
!
a
)
return
;
av_freep
(
&
a
->
coeff
);
a
->
length
=
0
;
a
->
length
=
0
;
av_free
(
a
);
}
void
sws_freeFilter
(
SwsFilter
*
filter
)
{
if
(
!
filter
)
return
;
if
(
filter
->
lumH
)
sws_freeVec
(
filter
->
lumH
);
if
(
filter
->
lumV
)
sws_freeVec
(
filter
->
lumV
);
if
(
filter
->
chrH
)
sws_freeVec
(
filter
->
chrH
);
if
(
filter
->
chrV
)
sws_freeVec
(
filter
->
chrV
);
if
(
!
filter
)
return
;
if
(
filter
->
lumH
)
sws_freeVec
(
filter
->
lumH
);
if
(
filter
->
lumV
)
sws_freeVec
(
filter
->
lumV
);
if
(
filter
->
chrH
)
sws_freeVec
(
filter
->
chrH
);
if
(
filter
->
chrV
)
sws_freeVec
(
filter
->
chrV
);
av_free
(
filter
);
}
void
sws_freeContext
(
SwsContext
*
c
)
{
int
i
;
if
(
!
c
)
return
;
if
(
!
c
)
return
;
if
(
c
->
lumPixBuf
)
{
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
av_freep
(
&
c
->
lumPixBuf
[
i
]);
av_freep
(
&
c
->
lumPixBuf
);
}
if
(
c
->
chrUPixBuf
)
{
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
for
(
i
=
0
;
i
<
c
->
vChrBufSize
;
i
++
)
av_freep
(
&
c
->
chrUPixBuf
[
i
]);
av_freep
(
&
c
->
chrUPixBuf
);
av_freep
(
&
c
->
chrVPixBuf
);
}
if
(
CONFIG_SWSCALE_ALPHA
&&
c
->
alpPixBuf
)
{
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
for
(
i
=
0
;
i
<
c
->
vLumBufSize
;
i
++
)
av_freep
(
&
c
->
alpPixBuf
[
i
]);
av_freep
(
&
c
->
alpPixBuf
);
}
...
...
@@ -1469,17 +1621,21 @@ void sws_freeContext(SwsContext *c)
#if HAVE_MMX
#ifdef MAP_ANONYMOUS
if
(
c
->
lumMmx2FilterCode
)
munmap
(
c
->
lumMmx2FilterCode
,
c
->
lumMmx2FilterCodeSize
);
if
(
c
->
chrMmx2FilterCode
)
munmap
(
c
->
chrMmx2FilterCode
,
c
->
chrMmx2FilterCodeSize
);
if
(
c
->
lumMmx2FilterCode
)
munmap
(
c
->
lumMmx2FilterCode
,
c
->
lumMmx2FilterCodeSize
);
if
(
c
->
chrMmx2FilterCode
)
munmap
(
c
->
chrMmx2FilterCode
,
c
->
chrMmx2FilterCodeSize
);
#elif HAVE_VIRTUALALLOC
if
(
c
->
lumMmx2FilterCode
)
VirtualFree
(
c
->
lumMmx2FilterCode
,
0
,
MEM_RELEASE
);
if
(
c
->
chrMmx2FilterCode
)
VirtualFree
(
c
->
chrMmx2FilterCode
,
0
,
MEM_RELEASE
);
if
(
c
->
lumMmx2FilterCode
)
VirtualFree
(
c
->
lumMmx2FilterCode
,
0
,
MEM_RELEASE
);
if
(
c
->
chrMmx2FilterCode
)
VirtualFree
(
c
->
chrMmx2FilterCode
,
0
,
MEM_RELEASE
);
#else
av_free
(
c
->
lumMmx2FilterCode
);
av_free
(
c
->
chrMmx2FilterCode
);
#endif
c
->
lumMmx2FilterCode
=
NULL
;
c
->
chrMmx2FilterCode
=
NULL
;
c
->
lumMmx2FilterCode
=
NULL
;
c
->
chrMmx2FilterCode
=
NULL
;
#endif
/* HAVE_MMX */
av_freep
(
&
c
->
yuvTable
);
...
...
@@ -1488,12 +1644,16 @@ void sws_freeContext(SwsContext *c)
av_free
(
c
);
}
struct
SwsContext
*
sws_getCachedContext
(
struct
SwsContext
*
context
,
int
srcW
,
int
srcH
,
enum
PixelFormat
srcFormat
,
int
dstW
,
int
dstH
,
enum
PixelFormat
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
const
double
*
param
)
struct
SwsContext
*
sws_getCachedContext
(
struct
SwsContext
*
context
,
int
srcW
,
int
srcH
,
enum
PixelFormat
srcFormat
,
int
dstW
,
int
dstH
,
enum
PixelFormat
dstFormat
,
int
flags
,
SwsFilter
*
srcFilter
,
SwsFilter
*
dstFilter
,
const
double
*
param
)
{
static
const
double
default_param
[
2
]
=
{
SWS_PARAM_DEFAULT
,
SWS_PARAM_DEFAULT
};
static
const
double
default_param
[
2
]
=
{
SWS_PARAM_DEFAULT
,
SWS_PARAM_DEFAULT
};
if
(
!
param
)
param
=
default_param
;
...
...
@@ -1526,7 +1686,10 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context,
context
->
flags
=
flags
;
context
->
param
[
0
]
=
param
[
0
];
context
->
param
[
1
]
=
param
[
1
];
sws_setColorspaceDetails
(
context
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
],
context
->
srcRange
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
]
/* FIXME*/
,
context
->
dstRange
,
0
,
1
<<
16
,
1
<<
16
);
sws_setColorspaceDetails
(
context
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
],
context
->
srcRange
,
ff_yuv2rgb_coeffs
[
SWS_CS_DEFAULT
]
/* FIXME*/
,
context
->
dstRange
,
0
,
1
<<
16
,
1
<<
16
);
if
(
sws_init_context
(
context
,
srcFilter
,
dstFilter
)
<
0
)
{
sws_freeContext
(
context
);
return
NULL
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment