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
661e284b
Commit
661e284b
authored
Apr 06, 2013
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
telecine filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
2844ea86
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
327 additions
and
1 deletion
+327
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+39
-0
Makefile
libavfilter/Makefile
+1
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
avfilter.c
libavfilter/avfilter.c
+1
-0
version.h
libavfilter/version.h
+1
-1
vf_telecine.c
libavfilter/vf_telecine.c
+283
-0
No files found.
Changelog
View file @
661e284b
...
@@ -19,6 +19,7 @@ version <next>:
...
@@ -19,6 +19,7 @@ version <next>:
- separatefields filter
- separatefields filter
- libquvi demuxer
- libquvi demuxer
- uniform options syntax across all filters
- uniform options syntax across all filters
- telecine filter
version 1.2:
version 1.2:
...
...
doc/filters.texi
View file @
661e284b
...
@@ -458,6 +458,45 @@ slope
...
@@ -458,6 +458,45 @@ slope
Determine how steep is the filter's shelf transition.
Determine how steep is the filter's shelf transition.
@end table
@end table
@section telecine
Apply telecine process to the video.
This filter accepts the following options:
@table @option
@item first_field
@table @samp
@item top, t
top field first
@item bottom, b
bottom field first
The default value is @code{top}.
@end table
@item pattern
A string of numbers representing the pulldown pattern you wish to apply.
The default value is @code{23}.
@end table
@example
Some typical patterns:
NTSC output (30i):
27.5p: 32222
24p: 23 (classic)
24p: 2332 (preferred)
20p: 33
18p: 334
16p: 3444
PAL output (25i):
27.5p: 12222
24p: 222222222223 ("Euro pulldown")
16.67p: 33
16p: 33333334
@end example
@section treble
@section treble
Boost or cut treble (upper) frequencies of the audio using a two-pole
Boost or cut treble (upper) frequencies of the audio using a two-pole
...
...
libavfilter/Makefile
View file @
661e284b
...
@@ -164,6 +164,7 @@ OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o
...
@@ -164,6 +164,7 @@ OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o
OBJS-$(CONFIG_SUBTITLES_FILTER)
+=
vf_subtitles.o
OBJS-$(CONFIG_SUBTITLES_FILTER)
+=
vf_subtitles.o
OBJS-$(CONFIG_SUPER2XSAI_FILTER)
+=
vf_super2xsai.o
OBJS-$(CONFIG_SUPER2XSAI_FILTER)
+=
vf_super2xsai.o
OBJS-$(CONFIG_SWAPUV_FILTER)
+=
vf_swapuv.o
OBJS-$(CONFIG_SWAPUV_FILTER)
+=
vf_swapuv.o
OBJS-$(CONFIG_TELECINE_FILTER)
+=
vf_telecine.o
OBJS-$(CONFIG_THUMBNAIL_FILTER)
+=
vf_thumbnail.o
OBJS-$(CONFIG_THUMBNAIL_FILTER)
+=
vf_thumbnail.o
OBJS-$(CONFIG_TILE_FILTER)
+=
vf_tile.o
OBJS-$(CONFIG_TILE_FILTER)
+=
vf_tile.o
OBJS-$(CONFIG_TINTERLACE_FILTER)
+=
vf_tinterlace.o
OBJS-$(CONFIG_TINTERLACE_FILTER)
+=
vf_tinterlace.o
...
...
libavfilter/allfilters.c
View file @
661e284b
...
@@ -159,6 +159,7 @@ void avfilter_register_all(void)
...
@@ -159,6 +159,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
SUBTITLES
,
subtitles
,
vf
);
REGISTER_FILTER
(
SUBTITLES
,
subtitles
,
vf
);
REGISTER_FILTER
(
SUPER2XSAI
,
super2xsai
,
vf
);
REGISTER_FILTER
(
SUPER2XSAI
,
super2xsai
,
vf
);
REGISTER_FILTER
(
SWAPUV
,
swapuv
,
vf
);
REGISTER_FILTER
(
SWAPUV
,
swapuv
,
vf
);
REGISTER_FILTER
(
TELECINE
,
telecine
,
vf
);
REGISTER_FILTER
(
THUMBNAIL
,
thumbnail
,
vf
);
REGISTER_FILTER
(
THUMBNAIL
,
thumbnail
,
vf
);
REGISTER_FILTER
(
TILE
,
tile
,
vf
);
REGISTER_FILTER
(
TILE
,
tile
,
vf
);
REGISTER_FILTER
(
TINTERLACE
,
tinterlace
,
vf
);
REGISTER_FILTER
(
TINTERLACE
,
tinterlace
,
vf
);
...
...
libavfilter/avfilter.c
View file @
661e284b
...
@@ -759,6 +759,7 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
...
@@ -759,6 +759,7 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
!
strcmp
(
filter
->
filter
->
name
,
"split"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"split"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"stereo3d"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"stereo3d"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"subtitles"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"subtitles"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"telecine"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"testsrc"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"testsrc"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"thumbnail"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"thumbnail"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"tile"
)
||
!
strcmp
(
filter
->
filter
->
name
,
"tile"
)
||
...
...
libavfilter/version.h
View file @
661e284b
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#include "libavutil/avutil.h"
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 5
1
#define LIBAVFILTER_VERSION_MINOR 5
2
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
...
...
libavfilter/vf_telecine.c
0 → 100644
View file @
661e284b
/*
* Copyright (c) 2012 Rudolf Polzer
* Copyright (c) 2013 Paul B Mahol
*
* 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
*/
/**
* @file telecine filter, heavily based from mpv-player:TOOLS/vf_dlopen/telecine.c by
* Rudolf Polzer.
*/
#include "libavutil/avstring.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"
typedef
struct
{
const
AVClass
*
class
;
int
first_field
;
char
*
pattern
;
unsigned
int
pattern_pos
;
AVRational
pts
;
double
ts_unit
;
int
out_cnt
;
int
occupied
;
int64_t
frame_count
;
int
nb_planes
;
int
planeheight
[
4
];
int
stride
[
4
];
AVFrame
*
frame
[
5
];
AVFrame
*
temp
;
}
TelecineContext
;
#define OFFSET(x) offsetof(TelecineContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static
const
AVOption
telecine_options
[]
=
{
{
"first_field"
,
"select first field"
,
OFFSET
(
first_field
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
1
,
FLAGS
,
"field"
},
{
"top"
,
"select top field first"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
0
},
0
,
0
,
FLAGS
,
"field"
},
{
"t"
,
"select top field first"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
0
},
0
,
0
,
FLAGS
,
"field"
},
{
"bottom"
,
"select bottom field first"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
1
},
0
,
0
,
FLAGS
,
"field"
},
{
"b"
,
"select bottom field first"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
1
},
0
,
0
,
FLAGS
,
"field"
},
{
"pattern"
,
"pattern that describe for how many fields a frame is to be displayed"
,
OFFSET
(
pattern
),
AV_OPT_TYPE_STRING
,
{.
str
=
"23"
},
0
,
0
,
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
telecine
);
static
av_cold
int
init
(
AVFilterContext
*
ctx
,
const
char
*
args
)
{
TelecineContext
*
tc
=
ctx
->
priv
;
const
char
*
p
;
int
max
=
0
;
if
(
!
strlen
(
tc
->
pattern
))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"No pattern provided.
\n
"
);
return
AVERROR_INVALIDDATA
;
}
for
(
p
=
tc
->
pattern
;
*
p
;
p
++
)
{
if
(
!
av_isdigit
(
*
p
))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Provided pattern includes non-numeric characters.
\n
"
);
return
AVERROR_INVALIDDATA
;
}
max
=
FFMAX
(
*
p
-
'0'
,
max
);
tc
->
pts
.
num
+=
2
;
tc
->
pts
.
den
+=
*
p
-
'0'
;
}
tc
->
out_cnt
=
(
max
+
1
)
/
2
;
av_log
(
ctx
,
AV_LOG_INFO
,
"Telecine pattern %s yields up to %d frames per frame, pts advance factor: %d/%d
\n
"
,
tc
->
pattern
,
tc
->
out_cnt
,
tc
->
pts
.
num
,
tc
->
pts
.
den
);
return
0
;
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
AVFilterFormats
*
pix_fmts
=
NULL
;
int
fmt
;
for
(
fmt
=
0
;
fmt
<
AV_PIX_FMT_NB
;
fmt
++
)
{
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
fmt
);
if
(
!
(
desc
->
flags
&
PIX_FMT_HWACCEL
))
ff_add_format
(
&
pix_fmts
,
fmt
);
}
ff_set_common_formats
(
ctx
,
pix_fmts
);
return
0
;
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
TelecineContext
*
tc
=
inlink
->
dst
->
priv
;
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
int
i
,
ret
;
tc
->
temp
=
ff_get_video_buffer
(
inlink
,
inlink
->
w
,
inlink
->
h
);
if
(
!
tc
->
temp
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
tc
->
out_cnt
;
i
++
)
{
tc
->
frame
[
i
]
=
ff_get_video_buffer
(
inlink
,
inlink
->
w
,
inlink
->
h
);
if
(
!
tc
->
frame
[
i
])
return
AVERROR
(
ENOMEM
);
}
if
((
ret
=
av_image_fill_linesizes
(
tc
->
stride
,
inlink
->
format
,
inlink
->
w
))
<
0
)
return
ret
;
tc
->
planeheight
[
1
]
=
tc
->
planeheight
[
2
]
=
inlink
->
h
>>
desc
->
log2_chroma_h
;
tc
->
planeheight
[
0
]
=
tc
->
planeheight
[
3
]
=
inlink
->
h
;
tc
->
nb_planes
=
av_pix_fmt_count_planes
(
inlink
->
format
);
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
TelecineContext
*
tc
=
ctx
->
priv
;
const
AVFilterLink
*
inlink
=
ctx
->
inputs
[
0
];
AVRational
fps
=
inlink
->
frame_rate
;
if
(
!
fps
.
num
||
!
fps
.
den
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"The input needs a constant frame rate; "
"current rate of %d/%d is invalid
\n
"
,
fps
.
num
,
fps
.
den
);
return
AVERROR
(
EINVAL
);
}
fps
=
av_mul_q
(
fps
,
av_inv_q
(
tc
->
pts
));
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"FPS: %d/%d -> %d/%d
\n
"
,
inlink
->
frame_rate
.
num
,
inlink
->
frame_rate
.
den
,
fps
.
num
,
fps
.
den
);
outlink
->
flags
|=
FF_LINK_FLAG_REQUEST_LOOP
;
outlink
->
frame_rate
=
fps
;
outlink
->
time_base
=
av_mul_q
(
inlink
->
time_base
,
tc
->
pts
);
tc
->
ts_unit
=
av_q2d
(
av_inv_q
(
av_mul_q
(
fps
,
outlink
->
time_base
)));
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
inpicref
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
TelecineContext
*
tc
=
ctx
->
priv
;
int
i
,
len
,
ret
=
0
,
nout
=
0
;
len
=
tc
->
pattern
[
tc
->
pattern_pos
]
-
'0'
;
tc
->
pattern_pos
++
;
if
(
!
tc
->
pattern
[
tc
->
pattern_pos
])
tc
->
pattern_pos
=
0
;
if
(
!
len
)
{
// do not output any field from this frame
av_frame_free
(
&
inpicref
);
return
0
;
}
if
(
tc
->
occupied
)
{
for
(
i
=
0
;
i
<
tc
->
nb_planes
;
i
++
)
{
// fill in the EARLIER field from the buffered pic
av_image_copy_plane
(
tc
->
frame
[
nout
]
->
data
[
i
]
+
tc
->
frame
[
nout
]
->
linesize
[
i
]
*
tc
->
first_field
,
tc
->
frame
[
nout
]
->
linesize
[
i
]
*
2
,
tc
->
temp
->
data
[
i
]
+
tc
->
temp
->
linesize
[
i
]
*
tc
->
first_field
,
tc
->
temp
->
linesize
[
i
]
*
2
,
tc
->
stride
[
i
],
(
tc
->
planeheight
[
i
]
-
tc
->
first_field
+
1
)
/
2
);
// fill in the LATER field from the new pic
av_image_copy_plane
(
tc
->
frame
[
nout
]
->
data
[
i
]
+
tc
->
frame
[
nout
]
->
linesize
[
i
]
*
!
tc
->
first_field
,
tc
->
frame
[
nout
]
->
linesize
[
i
]
*
2
,
inpicref
->
data
[
i
]
+
inpicref
->
linesize
[
i
]
*
!
tc
->
first_field
,
inpicref
->
linesize
[
i
]
*
2
,
tc
->
stride
[
i
],
(
tc
->
planeheight
[
i
]
-
!
tc
->
first_field
+
1
)
/
2
);
}
nout
++
;
len
--
;
tc
->
occupied
=
0
;
}
while
(
len
>=
2
)
{
// output THIS image as-is
for
(
i
=
0
;
i
<
tc
->
nb_planes
;
i
++
)
av_image_copy_plane
(
tc
->
frame
[
nout
]
->
data
[
i
],
tc
->
frame
[
nout
]
->
linesize
[
i
],
inpicref
->
data
[
i
],
inpicref
->
linesize
[
i
],
tc
->
stride
[
i
],
tc
->
planeheight
[
i
]);
nout
++
;
len
-=
2
;
}
if
(
len
>=
1
)
{
// copy THIS image to the buffer, we need it later
for
(
i
=
0
;
i
<
tc
->
nb_planes
;
i
++
)
av_image_copy_plane
(
tc
->
temp
->
data
[
i
],
tc
->
temp
->
linesize
[
i
],
inpicref
->
data
[
i
],
inpicref
->
linesize
[
i
],
tc
->
stride
[
i
],
tc
->
planeheight
[
i
]);
tc
->
occupied
=
1
;
}
for
(
i
=
0
;
i
<
nout
;
i
++
)
{
AVFrame
*
frame
=
av_frame_clone
(
tc
->
frame
[
i
]);
if
(
!
frame
)
{
av_frame_free
(
&
inpicref
);
return
AVERROR
(
ENOMEM
);
}
av_frame_copy_props
(
frame
,
inpicref
);
frame
->
pts
=
tc
->
frame_count
++
*
tc
->
ts_unit
;
ret
=
ff_filter_frame
(
outlink
,
frame
);
}
av_frame_free
(
&
inpicref
);
return
ret
;
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
TelecineContext
*
tc
=
ctx
->
priv
;
int
i
;
av_frame_free
(
&
tc
->
temp
);
for
(
i
=
0
;
i
<
tc
->
out_cnt
;
i
++
)
av_frame_free
(
&
tc
->
frame
[
i
]);
}
static
const
AVFilterPad
telecine_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
},
{
NULL
}
};
static
const
AVFilterPad
telecine_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
AVFilter
avfilter_vf_telecine
=
{
.
name
=
"telecine"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Apply a telecine pattern."
),
.
priv_size
=
sizeof
(
TelecineContext
),
.
priv_class
=
&
telecine_class
,
.
init
=
init
,
.
uninit
=
uninit
,
.
query_formats
=
query_formats
,
.
inputs
=
telecine_inputs
,
.
outputs
=
telecine_outputs
,
};
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