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
8997a0fa
Commit
8997a0fa
authored
Dec 30, 2012
by
Mark Himsley
Committed by
Stefano Sabatini
Dec 30, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi/tinterlace: add low-pass-filter for top/bottom interleave modes
Signed-off-by:
Stefano Sabatini
<
stefasab@gmail.com
>
parent
9e3b6285
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
16 deletions
+89
-16
filters.texi
doc/filters.texi
+34
-3
version.h
libavfilter/version.h
+1
-1
vf_tinterlace.c
libavfilter/vf_tinterlace.c
+54
-12
No files found.
doc/filters.texi
View file @
8997a0fa
...
...
@@ -4077,9 +4077,21 @@ Perform various types of temporal field interlacing.
Frames are counted starting from 1, so the first input frame is
considered odd.
This filter accepts a single option @option{mode} specifying the mode,
which can be specified either by specyfing @code{mode=VALUE} either
specifying the value alone. Available values are:
This filter accepts options in the form of @var{key}=@var{value} pairs
separated by ":".
Alternatively, the @var{mode} option can be specified as a value alone,
optionally followed by a ":" and further ":" separated @var{key}=@var{value}
pairs.
A description of the accepted options follows.
@table @option
@item mode
Specify the mode of the interlacing. This option can also be specified
as a value alone. See below for a list of values for this option.
Available values are:
@table @samp
@item merge, 0
...
...
@@ -4119,6 +4131,25 @@ compatibility reasons.
Default mode is @code{merge}.
@item flags
Specify flags influencing the filter process.
Available value for @var{flags} is:
@table @option
@item low_pass_filter, vlfp
Enable vertical low-pass filtering in the filter.
Vertical low-pass filtering is required when creating an interlaced
destination from a progressive source which contains high-frequency
vertical detail. Filtering will reduce interlace 'twitter' and Moire
patterning.
Vertical low-pass filtering can only be enabled for @option{mode}
@var{interleave_top} and @var{interleave_bottom}.
@end table
@end table
@section transpose
Transpose rows with columns in the input video and optionally flip it.
...
...
libavfilter/version.h
View file @
8997a0fa
...
...
@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 30
#define LIBAVFILTER_VERSION_MICRO 10
1
#define LIBAVFILTER_VERSION_MICRO 10
2
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
...
...
libavfilter/vf_tinterlace.c
View file @
8997a0fa
...
...
@@ -45,6 +45,7 @@ enum TInterlaceMode {
typedef
struct
{
const
AVClass
*
class
;
enum
TInterlaceMode
mode
;
///< interlace mode selected
int
flags
;
///< flags affecting interlacing algorithm
int
frame
;
///< number of the output frame
int
vsub
;
///< chroma vertical subsampling
AVFilterBufferRef
*
cur
;
...
...
@@ -55,6 +56,7 @@ typedef struct {
#define OFFSET(x) offsetof(TInterlaceContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
#define TINTERLACE_FLAG_VLPF 01
static
const
AVOption
tinterlace_options
[]
=
{
{
"mode"
,
"select interlace mode"
,
OFFSET
(
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
MODE_MERGE
},
0
,
MODE_NB
-
1
,
FLAGS
,
"mode"
},
...
...
@@ -66,6 +68,10 @@ static const AVOption tinterlace_options[] = {
{
"interleave_bottom"
,
"interleave bottom and top fields"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_INTERLEAVE_BOTTOM
},
INT_MIN
,
INT_MAX
,
FLAGS
,
"mode"
},
{
"interlacex2"
,
"interlace fields from two consecutive frames"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_INTERLACEX2
},
INT_MIN
,
INT_MAX
,
FLAGS
,
"mode"
},
{
"flags"
,
"set flags"
,
OFFSET
(
flags
),
AV_OPT_TYPE_FLAGS
,
{.
i64
=
0
},
0
,
INT_MAX
,
0
,
"flags"
},
{
"low_pass_filter"
,
"enable vertical low-pass filter"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
TINTERLACE_FLAG_VLPF
},
INT_MIN
,
INT_MAX
,
FLAGS
,
"flags"
},
{
"vlpf"
,
"enable vertical low-pass filter"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
TINTERLACE_FLAG_VLPF
},
INT_MIN
,
INT_MAX
,
FLAGS
,
"flags"
},
{
NULL
}
};
...
...
@@ -142,8 +148,16 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace
->
black_linesize
[
i
]
*
h
);
}
}
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"mode:%d h:%d -> h:%d
\n
"
,
tinterlace
->
mode
,
inlink
->
h
,
outlink
->
h
);
if
((
tinterlace
->
flags
&
TINTERLACE_FLAG_VLPF
)
&&
!
(
tinterlace
->
mode
==
MODE_INTERLEAVE_TOP
||
tinterlace
->
mode
==
MODE_INTERLEAVE_BOTTOM
))
{
av_log
(
ctx
,
AV_LOG_WARNING
,
"low_pass_filter flag ignored with mode %d
\n
"
,
tinterlace
->
mode
);
tinterlace
->
flags
&=
!
TINTERLACE_FLAG_VLPF
;
}
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"mode:%d filter:%s h:%d -> h:%d
\n
"
,
tinterlace
->
mode
,
(
tinterlace
->
flags
&
TINTERLACE_FLAG_VLPF
)
?
"on"
:
"off"
,
inlink
->
h
,
outlink
->
h
);
return
0
;
}
...
...
@@ -159,12 +173,14 @@ static int config_out_props(AVFilterLink *outlink)
* @param interleave leave a padding line between each copied line
* @param dst_field copy to upper or lower field,
* only meaningful when interleave is selected
* @param flags context flags
*/
static
inline
void
copy_picture_field
(
uint8_t
*
dst
[
4
],
int
dst_linesize
[
4
],
const
uint8_t
*
src
[
4
],
int
src_linesize
[
4
],
enum
AVPixelFormat
format
,
int
w
,
int
src_h
,
int
src_field
,
int
interleave
,
int
dst_field
)
int
src_field
,
int
interleave
,
int
dst_field
,
int
flags
)
{
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
format
);
int
plane
,
vsub
=
desc
->
log2_chroma_h
;
...
...
@@ -184,8 +200,30 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
srcp
+=
src_linesize
[
plane
];
if
(
interleave
&&
dst_field
==
FIELD_LOWER
)
dstp
+=
dst_linesize
[
plane
];
av_image_copy_plane
(
dstp
,
dst_linesize
[
plane
]
*
(
interleave
?
2
:
1
),
if
(
flags
&
TINTERLACE_FLAG_VLPF
)
{
// Low-pass filtering is required when creating an interlaced destination from
// a progressive source which contains high-frequency vertical detail.
// Filtering will reduce interlace 'twitter' and Moire patterning.
int
srcp_linesize
=
src_linesize
[
plane
]
*
k
;
int
dstp_linesize
=
dst_linesize
[
plane
]
*
(
interleave
?
2
:
1
);
for
(
int
h
=
lines
;
h
>
0
;
h
--
)
{
const
uint8_t
*
srcp_above
=
srcp
-
src_linesize
[
plane
];
const
uint8_t
*
srcp_below
=
srcp
+
src_linesize
[
plane
];
if
(
h
==
lines
)
srcp_above
=
srcp
;
// there is no line above
if
(
h
==
1
)
srcp_below
=
srcp
;
// there is no line below
for
(
int
i
=
0
;
i
<
linesize
;
i
++
)
{
// this calculation is an integer representation of
// '0.5 * current + 0.25 * above + 0.25 + below'
// '1 +' is for rounding. */
dstp
[
i
]
=
(
1
+
srcp
[
i
]
+
srcp
[
i
]
+
srcp_above
[
i
]
+
srcp_below
[
i
])
>>
2
;
}
dstp
+=
dstp_linesize
;
srcp
+=
srcp_linesize
;
}
}
else
{
av_image_copy_plane
(
dstp
,
dst_linesize
[
plane
]
*
(
interleave
?
2
:
1
),
srcp
,
src_linesize
[
plane
]
*
k
,
linesize
,
lines
);
}
}
}
...
...
@@ -222,12 +260,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
FIELD_UPPER_AND_LOWER
,
1
,
FIELD_UPPER
);
FIELD_UPPER_AND_LOWER
,
1
,
FIELD_UPPER
,
tinterlace
->
flags
);
/* write even frame lines into the lower field of the new frame */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
FIELD_UPPER_AND_LOWER
,
1
,
FIELD_LOWER
);
FIELD_UPPER_AND_LOWER
,
1
,
FIELD_LOWER
,
tinterlace
->
flags
);
avfilter_unref_bufferp
(
&
tinterlace
->
next
);
break
;
...
...
@@ -248,12 +286,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
FIELD_UPPER_AND_LOWER
,
1
,
field
);
FIELD_UPPER_AND_LOWER
,
1
,
field
,
tinterlace
->
flags
);
/* pad with black the other field */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
tinterlace
->
black_data
,
tinterlace
->
black_linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
FIELD_UPPER_AND_LOWER
,
1
,
!
field
);
FIELD_UPPER_AND_LOWER
,
1
,
!
field
,
tinterlace
->
flags
);
break
;
/* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
...
...
@@ -272,12 +310,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
1
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
);
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
1
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
tinterlace
->
flags
);
/* copy lower/upper field from next */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
1
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
);
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
1
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
tinterlace
->
flags
);
avfilter_unref_bufferp
(
&
tinterlace
->
next
);
break
;
case
MODE_INTERLACEX2
:
/* re-interlace preserving image height, double frame rate */
...
...
@@ -302,12 +342,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
1
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
);
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
1
,
tff
?
FIELD_LOWER
:
FIELD_UPPER
,
tinterlace
->
flags
);
/* write next frame first field lines into the first field of the new frame */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
1
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
);
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
1
,
tff
?
FIELD_UPPER
:
FIELD_LOWER
,
tinterlace
->
flags
);
break
;
default:
av_assert0
(
0
);
...
...
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