Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
62d176de
Commit
62d176de
authored
Aug 18, 2015
by
Pedro Arthur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
swscale: refactor vertical scaler
parent
fffae8e6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
380 additions
and
42 deletions
+380
-42
Makefile
libswscale/Makefile
+1
-0
slice.c
libswscale/slice.c
+17
-3
swscale.c
libswscale/swscale.c
+53
-35
swscale_internal.h
libswscale/swscale_internal.h
+19
-1
vscale.c
libswscale/vscale.c
+287
-0
swscale.c
libswscale/x86/swscale.c
+3
-3
No files found.
libswscale/Makefile
View file @
62d176de
...
...
@@ -17,6 +17,7 @@ OBJS = alphablend.o \
yuv2rgb.o
\
slice.o
\
hscale.o
\
vscale.o
\
OBJS-$(CONFIG_SHARED)
+=
log2_tab.o
...
...
libswscale/slice.c
View file @
62d176de
...
...
@@ -214,6 +214,7 @@ int ff_init_filters(SwsContext * c)
int
index
;
int
num_ydesc
;
int
num_cdesc
;
int
num_vdesc
=
isPlanarYUV
(
c
->
dstFormat
)
&&
!
isGray
(
c
->
dstFormat
)
?
2
:
1
;
int
need_lum_conv
=
c
->
lumToYV12
||
c
->
readLumPlanar
||
c
->
alpToYV12
||
c
->
readAlpPlanar
;
int
need_chr_conv
=
c
->
chrToYV12
||
c
->
readChrPlanar
;
int
srcIdx
,
dstIdx
;
...
...
@@ -228,8 +229,8 @@ int ff_init_filters(SwsContext * c)
num_ydesc
=
need_lum_conv
?
2
:
1
;
num_cdesc
=
need_chr_conv
?
2
:
1
;
c
->
numSlice
=
FFMAX
(
num_ydesc
,
num_cdesc
)
+
1
;
c
->
numDesc
=
num_ydesc
+
num_cdesc
;
c
->
numSlice
=
FFMAX
(
num_ydesc
,
num_cdesc
)
+
2
;
c
->
numDesc
=
num_ydesc
+
num_cdesc
+
num_vdesc
;
c
->
descIndex
[
0
]
=
num_ydesc
;
c
->
descIndex
[
1
]
=
num_ydesc
+
num_cdesc
;
...
...
@@ -243,12 +244,13 @@ int ff_init_filters(SwsContext * c)
res
=
alloc_slice
(
&
c
->
slice
[
0
],
c
->
srcFormat
,
c
->
srcH
,
c
->
chrSrcH
,
c
->
chrSrcHSubSample
,
c
->
chrSrcVSubSample
,
0
);
if
(
res
<
0
)
goto
cleanup
;
for
(
i
=
1
;
i
<
c
->
numSlice
-
1
;
++
i
)
{
for
(
i
=
1
;
i
<
c
->
numSlice
-
2
;
++
i
)
{
res
=
alloc_slice
(
&
c
->
slice
[
i
],
c
->
srcFormat
,
c
->
vLumFilterSize
+
MAX_LINES_AHEAD
,
c
->
vChrFilterSize
+
MAX_LINES_AHEAD
,
c
->
chrSrcHSubSample
,
c
->
chrSrcVSubSample
,
0
);
if
(
res
<
0
)
goto
cleanup
;
res
=
alloc_lines
(
&
c
->
slice
[
i
],
FFALIGN
(
c
->
srcW
*
2
+
78
,
16
),
c
->
srcW
);
if
(
res
<
0
)
goto
cleanup
;
}
// horizontal scaler output
res
=
alloc_slice
(
&
c
->
slice
[
i
],
c
->
srcFormat
,
c
->
vLumFilterSize
+
MAX_LINES_AHEAD
,
c
->
vChrFilterSize
+
MAX_LINES_AHEAD
,
c
->
chrDstHSubSample
,
c
->
chrDstVSubSample
,
1
);
if
(
res
<
0
)
goto
cleanup
;
res
=
alloc_lines
(
&
c
->
slice
[
i
],
dst_stride
,
c
->
dstW
);
...
...
@@ -256,6 +258,11 @@ int ff_init_filters(SwsContext * c)
fill_ones
(
&
c
->
slice
[
i
],
dst_stride
>>
1
,
c
->
dstBpc
==
16
);
// vertical scaler output
++
i
;
res
=
alloc_slice
(
&
c
->
slice
[
i
],
c
->
dstFormat
,
c
->
dstH
,
c
->
chrDstH
,
c
->
chrDstHSubSample
,
c
->
chrDstVSubSample
,
0
);
if
(
res
<
0
)
goto
cleanup
;
index
=
0
;
srcIdx
=
0
;
dstIdx
=
1
;
...
...
@@ -290,6 +297,13 @@ int ff_init_filters(SwsContext * c)
ff_init_desc_no_chr
(
&
c
->
desc
[
index
],
&
c
->
slice
[
srcIdx
],
&
c
->
slice
[
dstIdx
]);
}
++
index
;
{
srcIdx
=
c
->
numSlice
-
2
;
dstIdx
=
c
->
numSlice
-
1
;
ff_init_vscale
(
c
,
c
->
desc
+
index
,
c
->
slice
+
srcIdx
,
c
->
slice
+
dstIdx
);
}
return
0
;
cleanup:
...
...
libswscale/swscale.c
View file @
62d176de
...
...
@@ -326,8 +326,8 @@ static int swscale(SwsContext *c, const uint8_t *src[],
#endif
const
int
dstW
=
c
->
dstW
;
const
int
dstH
=
c
->
dstH
;
const
int
chrDstW
=
c
->
chrDstW
;
#ifndef NEW_FILTER
const
int
chrDstW
=
c
->
chrDstW
;
const
int
chrSrcW
=
c
->
chrSrcW
;
const
int
lumXInc
=
c
->
lumXInc
;
const
int
chrXInc
=
c
->
chrXInc
;
...
...
@@ -341,9 +341,9 @@ static int swscale(SwsContext *c, const uint8_t *src[],
int32_t
*
hChrFilterPos
=
c
->
hChrFilterPos
;
int16_t
*
hLumFilter
=
c
->
hLumFilter
;
int16_t
*
hChrFilter
=
c
->
hChrFilter
;
#endif
int32_t
*
lumMmxFilter
=
c
->
lumMmxFilter
;
int32_t
*
chrMmxFilter
=
c
->
chrMmxFilter
;
#endif
const
int
vLumFilterSize
=
c
->
vLumFilterSize
;
const
int
vChrFilterSize
=
c
->
vChrFilterSize
;
#ifndef NEW_FILTER
...
...
@@ -381,13 +381,18 @@ static int swscale(SwsContext *c, const uint8_t *src[],
int
lastInChrBuf
=
c
->
lastInChrBuf
;
// int perform_gamma = c->is_internal_gamma;
#ifdef NEW_FILTER
int
lumStart
=
0
;
int
lumEnd
=
c
->
descIndex
[
0
];
int
chrStart
=
lumEnd
;
int
chrEnd
=
c
->
descIndex
[
1
];
int
vStart
=
chrEnd
;
int
vEnd
=
c
->
numDesc
;
SwsSlice
*
src_slice
=
&
c
->
slice
[
lumStart
];
SwsSlice
*
dst_slice
=
&
c
->
slice
[
c
->
numSlice
-
1
];
SwsSlice
*
hout_slice
=
&
c
->
slice
[
c
->
numSlice
-
2
];
SwsSlice
*
vout_slice
=
&
c
->
slice
[
c
->
numSlice
-
1
];
SwsFilterDescriptor
*
desc
=
c
->
desc
;
#endif
int
hasLumHoles
=
1
;
int
hasChrHoles
=
1
;
...
...
@@ -460,20 +465,28 @@ static int swscale(SwsContext *c, const uint8_t *src[],
}
lastDstY
=
dstY
;
ff_init_slice_from_src
(
src_slice
,
(
uint8_t
**
)
src
,
srcStride
,
c
->
srcW
,
srcSliceY
,
srcSliceH
,
chrSrcSliceY
,
chrSrcSliceH
);
dst_slice
->
plane
[
0
].
sliceY
=
lastInLumBuf
+
1
;
dst_slice
->
plane
[
1
].
sliceY
=
lastInChrBuf
+
1
;
dst_slice
->
plane
[
2
].
sliceY
=
lastInChrBuf
+
1
;
dst_slice
->
plane
[
3
].
sliceY
=
lastInLumBuf
+
1
;
#ifdef NEW_FILTER
ff_init_vscale_pfn
(
c
,
yuv2plane1
,
yuv2planeX
,
yuv2nv12cX
,
yuv2packed1
,
yuv2packed2
,
yuv2packedX
,
yuv2anyX
,
c
->
use_mmx_vfilter
);
dst_slice
->
plane
[
0
].
sliceH
=
dst_slice
->
plane
[
1
].
sliceH
=
dst_slice
->
plane
[
2
].
sliceH
=
dst_slice
->
plane
[
3
].
sliceH
=
0
;
dst_slice
->
width
=
dstW
;
ff_init_slice_from_src
(
src_slice
,
(
uint8_t
**
)
src
,
srcStride
,
c
->
srcW
,
srcSliceY
,
srcSliceH
,
chrSrcSliceY
,
chrSrcSliceH
);
ff_init_slice_from_src
(
vout_slice
,
(
uint8_t
**
)
dst
,
dstStride
,
c
->
dstW
,
dstY
,
dstH
,
dstY
>>
c
->
chrDstVSubSample
,
FF_CEIL_RSHIFT
(
dstH
,
c
->
chrDstVSubSample
));
hout_slice
->
plane
[
0
].
sliceY
=
lastInLumBuf
+
1
;
hout_slice
->
plane
[
1
].
sliceY
=
lastInChrBuf
+
1
;
hout_slice
->
plane
[
2
].
sliceY
=
lastInChrBuf
+
1
;
hout_slice
->
plane
[
3
].
sliceY
=
lastInLumBuf
+
1
;
hout_slice
->
plane
[
0
].
sliceH
=
hout_slice
->
plane
[
1
].
sliceH
=
hout_slice
->
plane
[
2
].
sliceH
=
hout_slice
->
plane
[
3
].
sliceH
=
0
;
hout_slice
->
width
=
dstW
;
#endif
for
(;
dstY
<
dstH
;
dstY
++
)
{
const
int
chrDstY
=
dstY
>>
c
->
chrDstVSubSample
;
...
...
@@ -496,29 +509,35 @@ static int swscale(SwsContext *c, const uint8_t *src[],
int
lastLumSrcY2
=
FFMIN
(
c
->
srcH
,
firstLumSrcY2
+
vLumFilterSize
)
-
1
;
int
lastChrSrcY
=
FFMIN
(
c
->
chrSrcH
,
firstChrSrcY
+
vChrFilterSize
)
-
1
;
int
enough_lines
;
#ifdef NEW_FILTER
int
i
;
int
posY
,
cPosY
,
firstPosY
,
lastPosY
,
firstCPosY
,
lastCPosY
;
#endif
// handle holes (FAST_BILINEAR & weird filters)
if
(
firstLumSrcY
>
lastInLumBuf
)
{
#ifdef NEW_FILTER
hasLumHoles
=
lastInLumBuf
!=
firstLumSrcY
-
1
;
lastInLumBuf
=
firstLumSrcY
-
1
;
if
(
hasLumHoles
)
{
ds
t_slice
->
plane
[
0
].
sliceY
=
lastInLumBuf
+
1
;
ds
t_slice
->
plane
[
3
].
sliceY
=
lastInLumBuf
+
1
;
ds
t_slice
->
plane
[
0
].
sliceH
=
ds
t_slice
->
plane
[
3
].
sliceH
=
0
;
hou
t_slice
->
plane
[
0
].
sliceY
=
lastInLumBuf
+
1
;
hou
t_slice
->
plane
[
3
].
sliceY
=
lastInLumBuf
+
1
;
hou
t_slice
->
plane
[
0
].
sliceH
=
hou
t_slice
->
plane
[
3
].
sliceH
=
0
;
}
#endif
lastInLumBuf
=
firstLumSrcY
-
1
;
}
if
(
firstChrSrcY
>
lastInChrBuf
)
{
#ifdef NEW_FILTER
hasChrHoles
=
lastInChrBuf
!=
firstChrSrcY
-
1
;
lastInChrBuf
=
firstChrSrcY
-
1
;
if
(
hasChrHoles
)
{
ds
t_slice
->
plane
[
1
].
sliceY
=
lastInChrBuf
+
1
;
ds
t_slice
->
plane
[
2
].
sliceY
=
lastInChrBuf
+
1
;
ds
t_slice
->
plane
[
1
].
sliceH
=
ds
t_slice
->
plane
[
2
].
sliceH
=
0
;
hou
t_slice
->
plane
[
1
].
sliceY
=
lastInChrBuf
+
1
;
hou
t_slice
->
plane
[
2
].
sliceY
=
lastInChrBuf
+
1
;
hou
t_slice
->
plane
[
1
].
sliceH
=
hou
t_slice
->
plane
[
2
].
sliceH
=
0
;
}
#endif
lastInChrBuf
=
firstChrSrcY
-
1
;
}
av_assert0
(
firstLumSrcY
>=
lastInLumBuf
-
vLumBufSize
+
1
);
av_assert0
(
firstChrSrcY
>=
lastInChrBuf
-
vChrBufSize
+
1
);
...
...
@@ -541,7 +560,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
}
#ifdef NEW_FILTER
posY
=
dst_slice
->
plane
[
0
].
sliceY
+
ds
t_slice
->
plane
[
0
].
sliceH
;
posY
=
hout_slice
->
plane
[
0
].
sliceY
+
hou
t_slice
->
plane
[
0
].
sliceH
;
if
(
posY
<=
lastLumSrcY
&&
!
hasLumHoles
)
{
firstPosY
=
FFMAX
(
firstLumSrcY
,
posY
);
lastPosY
=
FFMIN
(
lastLumSrcY
+
MAX_LINES_AHEAD
,
srcSliceY
+
srcSliceH
-
1
);
...
...
@@ -550,7 +569,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
lastPosY
=
lastLumSrcY
;
}
cPosY
=
dst_slice
->
plane
[
1
].
sliceY
+
ds
t_slice
->
plane
[
1
].
sliceH
;
cPosY
=
hout_slice
->
plane
[
1
].
sliceY
+
hou
t_slice
->
plane
[
1
].
sliceH
;
if
(
cPosY
<=
lastChrSrcY
&&
!
hasChrHoles
)
{
firstCPosY
=
FFMAX
(
firstChrSrcY
,
cPosY
);
lastCPosY
=
FFMIN
(
lastChrSrcY
+
MAX_LINES_AHEAD
,
FF_CEIL_RSHIFT
(
srcSliceY
+
srcSliceH
,
c
->
chrSrcVSubSample
)
-
1
);
...
...
@@ -559,7 +578,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
lastCPosY
=
lastChrSrcY
;
}
ff_rotate_slice
(
ds
t_slice
,
lastPosY
,
lastCPosY
);
ff_rotate_slice
(
hou
t_slice
,
lastPosY
,
lastCPosY
);
if
(
posY
<
lastLumSrcY
+
1
)
{
for
(
i
=
lumStart
;
i
<
lumEnd
;
++
i
)
...
...
@@ -650,22 +669,20 @@ static int swscale(SwsContext *c, const uint8_t *src[],
ff_sws_init_output_funcs
(
c
,
&
yuv2plane1
,
&
yuv2planeX
,
&
yuv2nv12cX
,
&
yuv2packed1
,
&
yuv2packed2
,
&
yuv2packedX
,
&
yuv2anyX
);
use_mmx_vfilter
=
0
;
ff_init_vscale_pfn
(
c
,
yuv2plane1
,
yuv2planeX
,
yuv2nv12cX
,
yuv2packed1
,
yuv2packed2
,
yuv2packedX
,
yuv2anyX
,
use_mmx_vfilter
);
}
{
#ifdef NEW_FILTER
const
int16_t
**
lumSrcPtr
=
(
const
int16_t
**
)(
void
*
)
dst_slice
->
plane
[
0
].
line
+
firstLumSrcY
-
dst_slice
->
plane
[
0
].
sliceY
;
const
int16_t
**
chrUSrcPtr
=
(
const
int16_t
**
)(
void
*
)
dst_slice
->
plane
[
1
].
line
+
firstChrSrcY
-
dst_slice
->
plane
[
1
].
sliceY
;
const
int16_t
**
chrVSrcPtr
=
(
const
int16_t
**
)(
void
*
)
dst_slice
->
plane
[
2
].
line
+
firstChrSrcY
-
dst_slice
->
plane
[
2
].
sliceY
;
const
int16_t
**
alpSrcPtr
=
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
?
(
const
int16_t
**
)(
void
*
)
dst_slice
->
plane
[
3
].
line
+
firstLumSrcY
-
dst_slice
->
plane
[
3
].
sliceY
:
NULL
;
for
(
i
=
vStart
;
i
<
vEnd
;
++
i
)
desc
[
i
].
process
(
c
,
&
desc
[
i
],
dstY
,
1
);
#else
const
int16_t
**
lumSrcPtr
=
(
const
int16_t
**
)(
void
*
)
lumPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
;
const
int16_t
**
chrUSrcPtr
=
(
const
int16_t
**
)(
void
*
)
chrUPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
chrVSrcPtr
=
(
const
int16_t
**
)(
void
*
)
chrVPixBuf
+
chrBufIndex
+
firstChrSrcY
-
lastInChrBuf
+
vChrBufSize
;
const
int16_t
**
alpSrcPtr
=
(
CONFIG_SWSCALE_ALPHA
&&
alpPixBuf
)
?
(
const
int16_t
**
)(
void
*
)
alpPixBuf
+
lumBufIndex
+
firstLumSrcY
-
lastInLumBuf
+
vLumBufSize
:
NULL
;
#endif
int16_t
*
vLumFilter
=
c
->
vLumFilter
;
int16_t
*
vChrFilter
=
c
->
vChrFilter
;
...
...
@@ -766,6 +783,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
chrUSrcPtr
,
chrVSrcPtr
,
vChrFilterSize
,
alpSrcPtr
,
dest
,
dstW
,
dstY
);
}
#endif
//if (perform_gamma)
// gamma_convert(dest, dstW, c->gamma);
}
...
...
libswscale/swscale_internal.h
View file @
62d176de
...
...
@@ -1002,6 +1002,15 @@ typedef struct FilterContext
int
xInc
;
}
FilterContext
;
typedef
struct
VScalerContext
{
uint16_t
*
filter
[
2
];
int32_t
*
filter_pos
;
int
filter_size
;
int
isMMX
;
void
*
pfn
;
}
VScalerContext
;
// warp input lines in the form (src + width*i + j) to slice format (line[i][j])
int
ff_init_slice_from_src
(
SwsSlice
*
s
,
uint8_t
*
src
[
4
],
int
stride
[
4
],
int
srcW
,
int
lumY
,
int
lumH
,
int
chrY
,
int
chrH
);
...
...
@@ -1033,9 +1042,18 @@ int ff_init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst
int
ff_init_desc_no_chr
(
SwsFilterDescriptor
*
desc
,
SwsSlice
*
src
,
SwsSlice
*
dst
);
/// initializes vertical scaling descriptors
int
ff_init_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
SwsSlice
*
src
,
SwsSlice
*
dst
);
/// setup vertical scaler functions
void
ff_init_vscale_pfn
(
SwsContext
*
c
,
yuv2planar1_fn
yuv2plane1
,
yuv2planarX_fn
yuv2planeX
,
yuv2interleavedX_fn
yuv2nv12cX
,
yuv2packed1_fn
yuv2packed1
,
yuv2packed2_fn
yuv2packed2
,
yuv2packedX_fn
yuv2packedX
,
yuv2anyX_fn
yuv2anyX
,
int
use_mmx
);
//number of extra lines to process
#define MAX_LINES_AHEAD 4
// enable use of refactored scaler code
#define NEW_FILTER
#endif
/* SWSCALE_SWSCALE_INTERNAL_H */
libswscale/vscale.c
0 → 100644
View file @
62d176de
/*
* Copyright (C) 2015 Pedro Arthur <bygrandao@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "swscale_internal.h"
static
int
lum_planar_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
int
sliceY
,
int
sliceH
)
{
VScalerContext
*
inst
=
desc
->
instance
;
int
dstW
=
desc
->
dst
->
width
;
int
first
=
FFMAX
(
1
-
inst
->
filter_size
,
inst
->
filter_pos
[
sliceY
]);
int
sp
=
first
-
desc
->
src
->
plane
[
0
].
sliceY
;
int
dp
=
sliceY
-
desc
->
dst
->
plane
[
0
].
sliceY
;
uint8_t
**
src
=
desc
->
src
->
plane
[
0
].
line
+
sp
;
uint8_t
**
dst
=
desc
->
dst
->
plane
[
0
].
line
+
dp
;
uint16_t
*
filter
=
inst
->
filter
[
0
]
+
(
inst
->
isMMX
?
0
:
sliceY
*
inst
->
filter_size
);
if
(
inst
->
filter_size
==
1
)
((
yuv2planar1_fn
)
inst
->
pfn
)((
const
int16_t
*
)
src
[
0
],
dst
[
0
],
dstW
,
c
->
lumDither8
,
0
);
else
((
yuv2planarX_fn
)
inst
->
pfn
)(
filter
,
inst
->
filter_size
,
(
const
int16_t
**
)
src
,
dst
[
0
],
dstW
,
c
->
lumDither8
,
0
);
if
(
desc
->
alpha
)
{
int
sp
=
first
-
desc
->
src
->
plane
[
3
].
sliceY
;
int
dp
=
sliceY
-
desc
->
dst
->
plane
[
3
].
sliceY
;
uint8_t
**
src
=
desc
->
src
->
plane
[
3
].
line
+
sp
;
uint8_t
**
dst
=
desc
->
dst
->
plane
[
3
].
line
+
dp
;
uint16_t
*
filter
=
inst
->
filter
[
1
]
+
(
inst
->
isMMX
?
0
:
sliceY
*
inst
->
filter_size
);
if
(
inst
->
filter_size
==
1
)
((
yuv2planar1_fn
)
inst
->
pfn
)((
const
int16_t
*
)
src
[
0
],
dst
[
0
],
dstW
,
c
->
lumDither8
,
0
);
else
((
yuv2planarX_fn
)
inst
->
pfn
)(
filter
,
inst
->
filter_size
,
(
const
int16_t
**
)
src
,
dst
[
0
],
dstW
,
c
->
lumDither8
,
0
);
}
return
1
;
}
static
int
chr_planar_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
int
sliceY
,
int
sliceH
)
{
const
int
chrSkipMask
=
(
1
<<
desc
->
dst
->
v_chr_sub_sample
)
-
1
;
if
(
sliceY
&
chrSkipMask
)
return
0
;
else
{
VScalerContext
*
inst
=
desc
->
instance
;
int
dstW
=
FF_CEIL_RSHIFT
(
desc
->
dst
->
width
,
desc
->
dst
->
h_chr_sub_sample
);
int
chrSliceY
=
sliceY
>>
desc
->
dst
->
v_chr_sub_sample
;
int
first
=
FFMAX
(
1
-
inst
->
filter_size
,
inst
->
filter_pos
[
chrSliceY
]);
int
sp1
=
first
-
desc
->
src
->
plane
[
1
].
sliceY
;
int
sp2
=
first
-
desc
->
src
->
plane
[
2
].
sliceY
;
int
dp1
=
chrSliceY
-
desc
->
dst
->
plane
[
1
].
sliceY
;
int
dp2
=
chrSliceY
-
desc
->
dst
->
plane
[
2
].
sliceY
;
uint8_t
**
src1
=
desc
->
src
->
plane
[
1
].
line
+
sp1
;
uint8_t
**
src2
=
desc
->
src
->
plane
[
2
].
line
+
sp2
;
uint8_t
**
dst1
=
desc
->
dst
->
plane
[
1
].
line
+
dp1
;
uint8_t
**
dst2
=
desc
->
dst
->
plane
[
2
].
line
+
dp2
;
uint16_t
*
filter
=
inst
->
filter
[
0
]
+
(
inst
->
isMMX
?
0
:
chrSliceY
*
inst
->
filter_size
);
if
(
c
->
yuv2nv12cX
)
{
((
yuv2interleavedX_fn
)
inst
->
pfn
)(
c
,
filter
,
inst
->
filter_size
,
(
const
int16_t
**
)
src1
,
(
const
int16_t
**
)
src2
,
dst1
[
0
],
dstW
);
}
else
if
(
inst
->
filter_size
==
1
)
{
((
yuv2planar1_fn
)
inst
->
pfn
)((
const
int16_t
*
)
src1
[
0
],
dst1
[
0
],
dstW
,
c
->
chrDither8
,
0
);
((
yuv2planar1_fn
)
inst
->
pfn
)((
const
int16_t
*
)
src2
[
0
],
dst2
[
0
],
dstW
,
c
->
chrDither8
,
3
);
}
else
{
((
yuv2planarX_fn
)
inst
->
pfn
)(
filter
,
inst
->
filter_size
,
(
const
int16_t
**
)
src1
,
dst1
[
0
],
dstW
,
c
->
chrDither8
,
0
);
((
yuv2planarX_fn
)
inst
->
pfn
)(
filter
,
inst
->
filter_size
,
(
const
int16_t
**
)
src2
,
dst2
[
0
],
dstW
,
c
->
chrDither8
,
inst
->
isMMX
?
(
c
->
uv_offx2
>>
1
)
:
3
);
}
}
return
1
;
}
static
int
packed_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
int
sliceY
,
int
sliceH
)
{
VScalerContext
*
inst
=
desc
->
instance
;
int
dstW
=
desc
->
dst
->
width
;
int
chrSliceY
=
sliceY
>>
desc
->
dst
->
v_chr_sub_sample
;
int
lum_fsize
=
inst
[
0
].
filter_size
;
int
chr_fsize
=
inst
[
1
].
filter_size
;
uint16_t
*
lum_filter
=
inst
[
0
].
filter
[
0
];
uint16_t
*
chr_filter
=
inst
[
1
].
filter
[
0
];
int
firstLum
=
FFMAX
(
1
-
lum_fsize
,
inst
[
0
].
filter_pos
[
chrSliceY
]);
int
firstChr
=
FFMAX
(
1
-
chr_fsize
,
inst
[
1
].
filter_pos
[
chrSliceY
]);
int
sp0
=
firstLum
-
desc
->
src
->
plane
[
0
].
sliceY
;
int
sp1
=
firstChr
-
desc
->
src
->
plane
[
1
].
sliceY
;
int
sp2
=
firstChr
-
desc
->
src
->
plane
[
2
].
sliceY
;
int
sp3
=
firstLum
-
desc
->
src
->
plane
[
3
].
sliceY
;
int
dp
=
sliceY
-
desc
->
dst
->
plane
[
0
].
sliceY
;
uint8_t
**
src0
=
desc
->
src
->
plane
[
0
].
line
+
sp0
;
uint8_t
**
src1
=
desc
->
src
->
plane
[
1
].
line
+
sp1
;
uint8_t
**
src2
=
desc
->
src
->
plane
[
2
].
line
+
sp2
;
uint8_t
**
src3
=
desc
->
alpha
?
desc
->
src
->
plane
[
3
].
line
+
sp3
:
NULL
;
uint8_t
**
dst
=
desc
->
dst
->
plane
[
0
].
line
+
dp
;
if
(
c
->
yuv2packed1
&&
lum_fsize
==
1
&&
chr_fsize
<=
2
)
{
// unscaled RGB
int
chrAlpha
=
chr_fsize
==
1
?
0
:
chr_filter
[
2
*
sliceY
+
1
];
((
yuv2packed1_fn
)
inst
->
pfn
)(
c
,
(
const
int16_t
*
)
*
src0
,
(
const
int16_t
**
)
src1
,
(
const
int16_t
**
)
src2
,
(
const
int16_t
*
)(
desc
->
alpha
?
*
src3
:
NULL
),
*
dst
,
dstW
,
chrAlpha
,
sliceY
);
}
else
if
(
c
->
yuv2packed2
&&
lum_fsize
==
2
&&
chr_fsize
==
2
)
{
// bilinear upscale RGB
int
lumAlpha
=
lum_filter
[
2
*
sliceY
+
1
];
int
chrAlpha
=
chr_filter
[
2
*
sliceY
+
1
];
c
->
lumMmxFilter
[
2
]
=
c
->
lumMmxFilter
[
3
]
=
lum_filter
[
2
*
sliceY
]
*
0x10001
;
c
->
chrMmxFilter
[
2
]
=
c
->
chrMmxFilter
[
3
]
=
chr_filter
[
2
*
chrSliceY
]
*
0x10001
;
((
yuv2packed2_fn
)
inst
->
pfn
)(
c
,
(
const
int16_t
**
)
src0
,
(
const
int16_t
**
)
src1
,
(
const
int16_t
**
)
src2
,
(
const
int16_t
**
)
src3
,
*
dst
,
dstW
,
lumAlpha
,
chrAlpha
,
sliceY
);
}
else
{
// general RGB
((
yuv2packedX_fn
)
inst
->
pfn
)(
c
,
lum_filter
+
sliceY
*
lum_fsize
,
(
const
int16_t
**
)
src0
,
lum_fsize
,
chr_filter
+
sliceY
*
chr_fsize
,
(
const
int16_t
**
)
src1
,
(
const
int16_t
**
)
src2
,
chr_fsize
,
(
const
int16_t
**
)
src3
,
*
dst
,
dstW
,
sliceY
);
}
return
1
;
}
static
int
any_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
int
sliceY
,
int
sliceH
)
{
VScalerContext
*
inst
=
desc
->
instance
;
int
dstW
=
desc
->
dst
->
width
;
int
chrSliceY
=
sliceY
>>
desc
->
dst
->
v_chr_sub_sample
;
int
lum_fsize
=
inst
[
0
].
filter_size
;
int
chr_fsize
=
inst
[
1
].
filter_size
;
uint16_t
*
lum_filter
=
inst
[
0
].
filter
[
0
];
uint16_t
*
chr_filter
=
inst
[
1
].
filter
[
0
];
int
firstLum
=
FFMAX
(
1
-
lum_fsize
,
inst
[
0
].
filter_pos
[
chrSliceY
]);
int
firstChr
=
FFMAX
(
1
-
chr_fsize
,
inst
[
1
].
filter_pos
[
chrSliceY
]);
int
sp0
=
firstLum
-
desc
->
src
->
plane
[
0
].
sliceY
;
int
sp1
=
firstChr
-
desc
->
src
->
plane
[
1
].
sliceY
;
int
sp2
=
firstChr
-
desc
->
src
->
plane
[
2
].
sliceY
;
int
sp3
=
firstLum
-
desc
->
src
->
plane
[
3
].
sliceY
;
int
dp0
=
sliceY
-
desc
->
dst
->
plane
[
0
].
sliceY
;
int
dp1
=
chrSliceY
-
desc
->
dst
->
plane
[
1
].
sliceY
;
int
dp2
=
chrSliceY
-
desc
->
dst
->
plane
[
2
].
sliceY
;
int
dp3
=
sliceY
-
desc
->
dst
->
plane
[
3
].
sliceY
;
uint8_t
**
src0
=
desc
->
src
->
plane
[
0
].
line
+
sp0
;
uint8_t
**
src1
=
desc
->
src
->
plane
[
1
].
line
+
sp1
;
uint8_t
**
src2
=
desc
->
src
->
plane
[
2
].
line
+
sp2
;
uint8_t
**
src3
=
desc
->
alpha
?
desc
->
src
->
plane
[
3
].
line
+
sp3
:
NULL
;
uint8_t
*
dst
[
4
]
=
{
desc
->
dst
->
plane
[
0
].
line
[
dp0
],
desc
->
dst
->
plane
[
1
].
line
[
dp1
],
desc
->
dst
->
plane
[
2
].
line
[
dp2
],
desc
->
alpha
?
desc
->
dst
->
plane
[
3
].
line
[
dp3
]
:
NULL
};
av_assert1
(
!
c
->
yuv2packed1
&&
!
c
->
yuv2packed2
);
((
yuv2anyX_fn
)
inst
->
pfn
)(
c
,
lum_filter
+
sliceY
*
lum_fsize
,
(
const
int16_t
**
)
src0
,
lum_fsize
,
chr_filter
+
sliceY
*
chr_fsize
,
(
const
int16_t
**
)
src1
,
(
const
int16_t
**
)
src2
,
chr_fsize
,
(
const
int16_t
**
)
src3
,
dst
,
dstW
,
sliceY
);
return
1
;
}
int
ff_init_vscale
(
SwsContext
*
c
,
SwsFilterDescriptor
*
desc
,
SwsSlice
*
src
,
SwsSlice
*
dst
)
{
VScalerContext
*
lumCtx
=
NULL
;
VScalerContext
*
chrCtx
=
NULL
;
if
(
isPlanarYUV
(
c
->
dstFormat
)
||
(
isGray
(
c
->
dstFormat
)
&&
!
isALPHA
(
c
->
dstFormat
)))
{
lumCtx
=
av_mallocz
(
sizeof
(
VScalerContext
));
if
(
!
lumCtx
)
return
AVERROR
(
ENOMEM
);
desc
[
0
].
process
=
lum_planar_vscale
;
desc
[
0
].
instance
=
lumCtx
;
desc
[
0
].
src
=
src
;
desc
[
0
].
dst
=
dst
;
desc
[
0
].
alpha
=
c
->
alpPixBuf
!=
0
;
if
(
!
isGray
(
c
->
dstFormat
))
{
chrCtx
=
av_mallocz
(
sizeof
(
VScalerContext
));
if
(
!
chrCtx
)
return
AVERROR
(
ENOMEM
);
desc
[
1
].
process
=
chr_planar_vscale
;
desc
[
1
].
instance
=
chrCtx
;
desc
[
1
].
src
=
src
;
desc
[
1
].
dst
=
dst
;
}
}
else
{
lumCtx
=
av_mallocz_array
(
sizeof
(
VScalerContext
),
2
);
if
(
!
lumCtx
)
return
AVERROR
(
ENOMEM
);
chrCtx
=
&
lumCtx
[
1
];
desc
[
0
].
process
=
c
->
yuv2packedX
?
packed_vscale
:
any_vscale
;
desc
[
0
].
instance
=
lumCtx
;
desc
[
0
].
src
=
src
;
desc
[
0
].
dst
=
dst
;
desc
[
0
].
alpha
=
c
->
alpPixBuf
!=
0
;
}
ff_init_vscale_pfn
(
c
,
c
->
yuv2plane1
,
c
->
yuv2planeX
,
c
->
yuv2nv12cX
,
c
->
yuv2packed1
,
c
->
yuv2packed2
,
c
->
yuv2packedX
,
c
->
yuv2anyX
,
c
->
use_mmx_vfilter
);
return
0
;
}
void
ff_init_vscale_pfn
(
SwsContext
*
c
,
yuv2planar1_fn
yuv2plane1
,
yuv2planarX_fn
yuv2planeX
,
yuv2interleavedX_fn
yuv2nv12cX
,
yuv2packed1_fn
yuv2packed1
,
yuv2packed2_fn
yuv2packed2
,
yuv2packedX_fn
yuv2packedX
,
yuv2anyX_fn
yuv2anyX
,
int
use_mmx
)
{
VScalerContext
*
lumCtx
=
NULL
;
VScalerContext
*
chrCtx
=
NULL
;
int
idx
=
c
->
numDesc
-
1
;
if
(
isPlanarYUV
(
c
->
dstFormat
)
||
(
isGray
(
c
->
dstFormat
)
&&
!
isALPHA
(
c
->
dstFormat
)))
{
if
(
!
isGray
(
c
->
dstFormat
))
{
chrCtx
=
c
->
desc
[
idx
].
instance
;
chrCtx
->
filter
[
0
]
=
use_mmx
?
(
int16_t
*
)
c
->
chrMmxFilter
:
c
->
vChrFilter
;
chrCtx
->
filter_size
=
c
->
vChrFilterSize
;
chrCtx
->
filter_pos
=
c
->
vChrFilterPos
;
chrCtx
->
isMMX
=
use_mmx
;
--
idx
;
if
(
yuv2nv12cX
)
chrCtx
->
pfn
=
yuv2nv12cX
;
else
if
(
c
->
vChrFilterSize
==
1
)
chrCtx
->
pfn
=
yuv2plane1
;
else
chrCtx
->
pfn
=
yuv2planeX
;
}
lumCtx
=
c
->
desc
[
idx
].
instance
;
lumCtx
->
filter
[
0
]
=
use_mmx
?
(
int16_t
*
)
c
->
lumMmxFilter
:
c
->
vLumFilter
;
lumCtx
->
filter
[
1
]
=
use_mmx
?
(
int16_t
*
)
c
->
alpMmxFilter
:
c
->
vLumFilter
;
lumCtx
->
filter_size
=
c
->
vLumFilterSize
;
lumCtx
->
filter_pos
=
c
->
vLumFilterPos
;
lumCtx
->
isMMX
=
use_mmx
;
if
(
c
->
vLumFilterSize
==
1
)
lumCtx
->
pfn
=
yuv2plane1
;
else
lumCtx
->
pfn
=
yuv2planeX
;
}
else
{
lumCtx
=
c
->
desc
[
idx
].
instance
;
chrCtx
=
&
lumCtx
[
1
];
lumCtx
->
filter
[
0
]
=
c
->
vLumFilter
;
lumCtx
->
filter_size
=
c
->
vLumFilterSize
;
lumCtx
->
filter_pos
=
c
->
vLumFilterPos
;
chrCtx
->
filter
[
0
]
=
c
->
vChrFilter
;
chrCtx
->
filter_size
=
c
->
vChrFilterSize
;
chrCtx
->
filter_pos
=
c
->
vChrFilterPos
;
lumCtx
->
isMMX
=
use_mmx
;
chrCtx
->
isMMX
=
use_mmx
;
if
(
yuv2packedX
)
{
if
(
c
->
yuv2packed1
&&
c
->
vLumFilterSize
==
1
&&
c
->
vChrFilterSize
<=
2
)
lumCtx
->
pfn
=
yuv2packed1
;
else
if
(
c
->
yuv2packed2
&&
c
->
vLumFilterSize
==
2
&&
c
->
vChrFilterSize
==
2
)
lumCtx
->
pfn
=
yuv2packed2
;
else
lumCtx
->
pfn
=
yuv2packedX
;
}
else
lumCtx
->
pfn
=
yuv2anyX
;
}
}
libswscale/x86/swscale.c
View file @
62d176de
...
...
@@ -86,9 +86,9 @@ void ff_updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrB
const
int
dstH
=
c
->
dstH
;
const
int
flags
=
c
->
flags
;
#ifdef NEW_FILTER
SwsPlane
*
lumPlane
=
&
c
->
slice
[
c
->
numSlice
-
1
].
plane
[
0
];
SwsPlane
*
chrUPlane
=
&
c
->
slice
[
c
->
numSlice
-
1
].
plane
[
1
];
SwsPlane
*
alpPlane
=
&
c
->
slice
[
c
->
numSlice
-
1
].
plane
[
3
];
SwsPlane
*
lumPlane
=
&
c
->
slice
[
c
->
numSlice
-
2
].
plane
[
0
];
SwsPlane
*
chrUPlane
=
&
c
->
slice
[
c
->
numSlice
-
2
].
plane
[
1
];
SwsPlane
*
alpPlane
=
&
c
->
slice
[
c
->
numSlice
-
2
].
plane
[
3
];
#else
int16_t
**
lumPixBuf
=
c
->
lumPixBuf
;
int16_t
**
chrUPixBuf
=
c
->
chrUPixBuf
;
...
...
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