Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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