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
73f234fd
Commit
73f234fd
authored
May 03, 2019
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/f_interleave: switch to activate
parent
fcc01ba3
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
63 additions
and
74 deletions
+63
-74
f_interleave.c
libavfilter/f_interleave.c
+63
-74
No files found.
libavfilter/f_interleave.c
View file @
73f234fd
...
...
@@ -27,12 +27,9 @@
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#define FF_INTERNAL_FIELDS 1
#include "framequeue.h"
#include "avfilter.h"
#include "bufferqueue.h"
#include "formats.h"
#include "filters.h"
#include "internal.h"
#include "audio.h"
#include "video.h"
...
...
@@ -40,7 +37,7 @@
typedef
struct
InterleaveContext
{
const
AVClass
*
class
;
int
nb_inputs
;
struct
FFBufQueue
*
queue
s
;
int64_t
pt
s
;
}
InterleaveContext
;
#define OFFSET(x) offsetof(InterleaveContext, x)
...
...
@@ -52,58 +49,78 @@ static const AVOption filt_name##_options[] = { \
{ NULL } \
}
inline
static
int
push_fram
e
(
AVFilterContext
*
ctx
)
static
int
activat
e
(
AVFilterContext
*
ctx
)
{
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
InterleaveContext
*
s
=
ctx
->
priv
;
AVFrame
*
frame
;
int
i
,
queue_idx
=
-
1
;
int64_t
pts_min
=
INT64_MAX
;
int64_t
q_pts
,
pts
=
INT64_MAX
;
int
i
,
nb_eofs
=
0
,
input_idx
=
-
1
;
FF_FILTER_FORWARD_STATUS_BACK_ALL
(
outlink
,
ctx
);
/* look for oldest frame */
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
{
struct
FFBufQueue
*
q
=
&
s
->
queues
[
i
];
if
(
!
ff_outlink_get_status
(
ctx
->
inputs
[
i
])
&&
!
ff_inlink_queued_frames
(
ctx
->
inputs
[
i
]))
break
;
}
if
(
!
q
->
available
&&
!
ctx
->
inputs
[
i
]
->
status_out
)
return
0
;
if
(
q
->
available
)
{
frame
=
ff_bufqueue_peek
(
q
,
0
);
if
(
frame
->
pts
<
pts_min
)
{
pts_min
=
frame
->
pts
;
queue_idx
=
i
;
if
(
i
==
ctx
->
nb_inputs
)
{
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
{
AVFrame
*
frame
;
if
(
ff_outlink_get_status
(
ctx
->
inputs
[
i
]))
continue
;
frame
=
ff_inlink_peek_frame
(
ctx
->
inputs
[
i
],
0
);
if
(
frame
->
pts
==
AV_NOPTS_VALUE
)
{
int
ret
;
av_log
(
ctx
,
AV_LOG_WARNING
,
"NOPTS value for input frame cannot be accepted, frame discarded
\n
"
);
ret
=
ff_inlink_consume_frame
(
ctx
->
inputs
[
i
],
&
frame
);
if
(
ret
<
0
)
return
ret
;
av_frame_free
(
&
frame
);
return
AVERROR_INVALIDDATA
;
}
q_pts
=
av_rescale_q
(
frame
->
pts
,
ctx
->
inputs
[
i
]
->
time_base
,
AV_TIME_BASE_Q
);
if
(
q_pts
<
pts
)
{
pts
=
q_pts
;
input_idx
=
i
;
}
}
}
/* all inputs are closed */
if
(
queue_idx
<
0
)
return
AVERROR_EOF
;
if
(
input_idx
>=
0
)
{
AVFrame
*
frame
;
int
ret
;
frame
=
ff_bufqueue_get
(
&
s
->
queues
[
queue_idx
]);
av_log
(
ctx
,
AV_LOG_DEBUG
,
"queue:%d -> frame time:%f
\n
"
,
queue_idx
,
frame
->
pts
*
av_q2d
(
AV_TIME_BASE_Q
));
return
ff_filter_frame
(
ctx
->
outputs
[
0
],
frame
);
}
ret
=
ff_inlink_consume_frame
(
ctx
->
inputs
[
input_idx
],
&
frame
);
if
(
ret
<
0
)
return
ret
;
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
frame
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
InterleaveContext
*
s
=
ctx
->
priv
;
unsigned
in_no
=
FF_INLINK_IDX
(
inlink
);
frame
->
pts
=
s
->
pts
=
pts
;
return
ff_filter_frame
(
outlink
,
frame
);
}
}
if
(
frame
->
pts
==
AV_NOPTS_VALUE
)
{
av_log
(
ctx
,
AV_LOG_WARNING
,
"NOPTS value for input frame cannot be accepted, frame discarded
\n
"
);
av_frame_free
(
&
frame
);
return
AVERROR_INVALIDDATA
;
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
{
if
(
ff_inlink_queued_frames
(
ctx
->
inputs
[
i
]))
continue
;
if
(
ff_outlink_frame_wanted
(
outlink
)
&&
!
ff_outlink_get_status
(
ctx
->
inputs
[
i
]))
{
ff_inlink_request_frame
(
ctx
->
inputs
[
i
]);
return
0
;
}
nb_eofs
++
;
}
/* queue frame */
frame
->
pts
=
av_rescale_q
(
frame
->
pts
,
inlink
->
time_base
,
AV_TIME_BASE_Q
);
av_log
(
ctx
,
AV_LOG_DEBUG
,
"frame pts:%f -> queue idx:%d available:%d
\n
"
,
frame
->
pts
*
av_q2d
(
AV_TIME_BASE_Q
),
in_no
,
s
->
queues
[
in_no
].
available
);
ff_bufqueue_add
(
ctx
,
&
s
->
queues
[
in_no
],
frame
);
if
(
nb_eofs
==
ctx
->
nb_inputs
)
{
ff_outlink_set_status
(
outlink
,
AVERROR_EOF
,
s
->
pts
);
return
0
;
}
return
push_frame
(
ctx
)
;
return
FFERROR_NOT_READY
;
}
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
...
...
@@ -112,10 +129,6 @@ static av_cold int init(AVFilterContext *ctx)
const
AVFilterPad
*
outpad
=
&
ctx
->
filter
->
outputs
[
0
];
int
i
,
ret
;
s
->
queues
=
av_calloc
(
s
->
nb_inputs
,
sizeof
(
s
->
queues
[
0
]));
if
(
!
s
->
queues
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
s
->
nb_inputs
;
i
++
)
{
AVFilterPad
inpad
=
{
0
};
...
...
@@ -123,7 +136,6 @@ static av_cold int init(AVFilterContext *ctx)
if
(
!
inpad
.
name
)
return
AVERROR
(
ENOMEM
);
inpad
.
type
=
outpad
->
type
;
inpad
.
filter_frame
=
filter_frame
;
switch
(
outpad
->
type
)
{
case
AVMEDIA_TYPE_VIDEO
:
...
...
@@ -144,14 +156,8 @@ static av_cold int init(AVFilterContext *ctx)
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
InterleaveContext
*
s
=
ctx
->
priv
;
int
i
;
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
{
ff_bufqueue_discard_all
(
&
s
->
queues
[
i
]);
av_freep
(
&
s
->
queues
[
i
]);
for
(
int
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
av_freep
(
&
ctx
->
input_pads
[
i
].
name
);
}
}
static
int
config_output
(
AVFilterLink
*
outlink
)
...
...
@@ -190,23 +196,6 @@ static int config_output(AVFilterLink *outlink)
return
0
;
}
static
int
request_frame
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
InterleaveContext
*
s
=
ctx
->
priv
;
int
i
,
ret
;
for
(
i
=
0
;
i
<
ctx
->
nb_inputs
;
i
++
)
{
if
(
!
s
->
queues
[
i
].
available
&&
!
ctx
->
inputs
[
i
]
->
status_out
)
{
ret
=
ff_request_frame
(
ctx
->
inputs
[
i
]);
if
(
ret
!=
AVERROR_EOF
)
return
ret
;
}
}
return
push_frame
(
ctx
);
}
#if CONFIG_INTERLEAVE_FILTER
DEFINE_OPTIONS
(
interleave
,
AV_OPT_FLAG_VIDEO_PARAM
|
AV_OPT_FLAG_FILTERING_PARAM
);
...
...
@@ -217,7 +206,6 @@ static const AVFilterPad interleave_outputs[] = {
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
config_output
,
.
request_frame
=
request_frame
,
},
{
NULL
}
};
...
...
@@ -228,6 +216,7 @@ AVFilter ff_vf_interleave = {
.
priv_size
=
sizeof
(
InterleaveContext
),
.
init
=
init
,
.
uninit
=
uninit
,
.
activate
=
activate
,
.
outputs
=
interleave_outputs
,
.
priv_class
=
&
interleave_class
,
.
flags
=
AVFILTER_FLAG_DYNAMIC_INPUTS
,
...
...
@@ -245,7 +234,6 @@ static const AVFilterPad ainterleave_outputs[] = {
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
config_props
=
config_output
,
.
request_frame
=
request_frame
,
},
{
NULL
}
};
...
...
@@ -256,6 +244,7 @@ AVFilter ff_af_ainterleave = {
.
priv_size
=
sizeof
(
InterleaveContext
),
.
init
=
init
,
.
uninit
=
uninit
,
.
activate
=
activate
,
.
outputs
=
ainterleave_outputs
,
.
priv_class
=
&
ainterleave_class
,
.
flags
=
AVFILTER_FLAG_DYNAMIC_INPUTS
,
...
...
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