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.
...
@@ -4077,9 +4077,21 @@ Perform various types of temporal field interlacing.
Frames are counted starting from 1, so the first input frame is
Frames are counted starting from 1, so the first input frame is
considered odd.
considered odd.
This filter accepts a single option @option{mode} specifying the mode,
This filter accepts options in the form of @var{key}=@var{value} pairs
which can be specified either by specyfing @code{mode=VALUE} either
separated by ":".
specifying the value alone. Available values are:
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
@table @samp
@item merge, 0
@item merge, 0
...
@@ -4119,6 +4131,25 @@ compatibility reasons.
...
@@ -4119,6 +4131,25 @@ compatibility reasons.
Default mode is @code{merge}.
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
@section transpose
Transpose rows with columns in the input video and optionally flip it.
Transpose rows with columns in the input video and optionally flip it.
...
...
libavfilter/version.h
View file @
8997a0fa
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 30
#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, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
LIBAVFILTER_VERSION_MINOR, \
...
...
libavfilter/vf_tinterlace.c
View file @
8997a0fa
...
@@ -45,6 +45,7 @@ enum TInterlaceMode {
...
@@ -45,6 +45,7 @@ enum TInterlaceMode {
typedef
struct
{
typedef
struct
{
const
AVClass
*
class
;
const
AVClass
*
class
;
enum
TInterlaceMode
mode
;
///< interlace mode selected
enum
TInterlaceMode
mode
;
///< interlace mode selected
int
flags
;
///< flags affecting interlacing algorithm
int
frame
;
///< number of the output frame
int
frame
;
///< number of the output frame
int
vsub
;
///< chroma vertical subsampling
int
vsub
;
///< chroma vertical subsampling
AVFilterBufferRef
*
cur
;
AVFilterBufferRef
*
cur
;
...
@@ -55,6 +56,7 @@ typedef struct {
...
@@ -55,6 +56,7 @@ typedef struct {
#define OFFSET(x) offsetof(TInterlaceContext, x)
#define OFFSET(x) offsetof(TInterlaceContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
#define TINTERLACE_FLAG_VLPF 01
static
const
AVOption
tinterlace_options
[]
=
{
static
const
AVOption
tinterlace_options
[]
=
{
{
"mode"
,
"select interlace mode"
,
OFFSET
(
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
MODE_MERGE
},
0
,
MODE_NB
-
1
,
FLAGS
,
"mode"
},
{
"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[] = {
...
@@ -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"
},
{
"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"
},
{
"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
}
{
NULL
}
};
};
...
@@ -142,8 +148,16 @@ static int config_out_props(AVFilterLink *outlink)
...
@@ -142,8 +148,16 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace
->
black_linesize
[
i
]
*
h
);
tinterlace
->
black_linesize
[
i
]
*
h
);
}
}
}
}
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"mode:%d h:%d -> h:%d
\n
"
,
if
((
tinterlace
->
flags
&
TINTERLACE_FLAG_VLPF
)
tinterlace
->
mode
,
inlink
->
h
,
outlink
->
h
);
&&
!
(
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
;
return
0
;
}
}
...
@@ -159,12 +173,14 @@ static int config_out_props(AVFilterLink *outlink)
...
@@ -159,12 +173,14 @@ static int config_out_props(AVFilterLink *outlink)
* @param interleave leave a padding line between each copied line
* @param interleave leave a padding line between each copied line
* @param dst_field copy to upper or lower field,
* @param dst_field copy to upper or lower field,
* only meaningful when interleave is selected
* only meaningful when interleave is selected
* @param flags context flags
*/
*/
static
inline
static
inline
void
copy_picture_field
(
uint8_t
*
dst
[
4
],
int
dst_linesize
[
4
],
void
copy_picture_field
(
uint8_t
*
dst
[
4
],
int
dst_linesize
[
4
],
const
uint8_t
*
src
[
4
],
int
src_linesize
[
4
],
const
uint8_t
*
src
[
4
],
int
src_linesize
[
4
],
enum
AVPixelFormat
format
,
int
w
,
int
src_h
,
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
);
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
format
);
int
plane
,
vsub
=
desc
->
log2_chroma_h
;
int
plane
,
vsub
=
desc
->
log2_chroma_h
;
...
@@ -184,8 +200,30 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
...
@@ -184,8 +200,30 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
srcp
+=
src_linesize
[
plane
];
srcp
+=
src_linesize
[
plane
];
if
(
interleave
&&
dst_field
==
FIELD_LOWER
)
if
(
interleave
&&
dst_field
==
FIELD_LOWER
)
dstp
+=
dst_linesize
[
plane
];
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
);
srcp
,
src_linesize
[
plane
]
*
k
,
linesize
,
lines
);
}
}
}
}
}
...
@@ -222,12 +260,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
...
@@ -222,12 +260,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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 */
/* write even frame lines into the lower field of the new frame */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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
);
avfilter_unref_bufferp
(
&
tinterlace
->
next
);
break
;
break
;
...
@@ -248,12 +286,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
...
@@ -248,12 +286,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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 */
/* pad with black the other field */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
tinterlace
->
black_data
,
tinterlace
->
black_linesize
,
(
const
uint8_t
**
)
tinterlace
->
black_data
,
tinterlace
->
black_linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
FIELD_UPPER_AND_LOWER
,
1
,
!
field
);
FIELD_UPPER_AND_LOWER
,
1
,
!
field
,
tinterlace
->
flags
);
break
;
break
;
/* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
/* 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)
...
@@ -272,12 +310,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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 lower/upper field from next */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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
);
avfilter_unref_bufferp
(
&
tinterlace
->
next
);
break
;
break
;
case
MODE_INTERLACEX2
:
/* re-interlace preserving image height, double frame rate */
case
MODE_INTERLACEX2
:
/* re-interlace preserving image height, double frame rate */
...
@@ -302,12 +342,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
...
@@ -302,12 +342,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
(
const
uint8_t
**
)
cur
->
data
,
cur
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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 */
/* write next frame first field lines into the first field of the new frame */
copy_picture_field
(
out
->
data
,
out
->
linesize
,
copy_picture_field
(
out
->
data
,
out
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
(
const
uint8_t
**
)
next
->
data
,
next
->
linesize
,
inlink
->
format
,
inlink
->
w
,
inlink
->
h
,
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
;
break
;
default:
default:
av_assert0
(
0
);
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