FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
dualinput.c
Go to the documentation of this file.
1
/*
2
* This file is part of FFmpeg.
3
*
4
* FFmpeg is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* FFmpeg is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with FFmpeg; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
*/
18
19
#define MAIN 0
20
#define SECOND 1
21
22
#include "
dualinput.h
"
23
#include "
libavutil/timestamp.h
"
24
25
static
int
try_filter_frame
(
FFDualInputContext
*
s
,
26
AVFilterContext
*ctx,
AVFrame
*mainpic)
27
{
28
int
ret
;
29
30
/* Discard obsolete second frames: if there is a next second frame with pts
31
* before the main frame, we can drop the current second. */
32
while
(1) {
33
AVFrame
*next_overpic =
ff_bufqueue_peek
(&s->
queue
[
SECOND
], 0);
34
if
(!next_overpic && s->
second_eof
&& !s->
repeatlast
) {
35
av_frame_free
(&s->
second_frame
);
36
break
;
37
}
38
if
(!next_overpic ||
av_compare_ts
(next_overpic->
pts
, ctx->
inputs
[
SECOND
]->
time_base
,
39
mainpic->
pts
, ctx->
inputs
[
MAIN
]->
time_base
) > 0)
40
break
;
41
ff_bufqueue_get
(&s->
queue
[
SECOND
]);
42
av_frame_free
(&s->
second_frame
);
43
s->
second_frame
= next_overpic;
44
}
45
46
/* If there is no next frame and no EOF and the second frame is before
47
* the main frame, we can not know yet if it will be superseded. */
48
if
(!s->
queue
[
SECOND
].
available
&& !s->
second_eof
&&
49
(!s->
second_frame
||
av_compare_ts
(s->
second_frame
->
pts
, ctx->
inputs
[
SECOND
]->
time_base
,
50
mainpic->
pts
, ctx->
inputs
[
MAIN
]->
time_base
) < 0))
51
return
AVERROR
(EAGAIN);
52
53
/* At this point, we know that the current second frame extends to the
54
* time of the main frame. */
55
av_dlog
(ctx,
"main_pts:%s main_pts_time:%s"
,
56
av_ts2str
(mainpic->
pts
),
av_ts2timestr
(mainpic->
pts
, &ctx->
inputs
[
MAIN
]->
time_base
));
57
if
(s->
second_frame
)
58
av_dlog
(ctx,
" second_pts:%s second_pts_time:%s"
,
59
av_ts2str
(s->
second_frame
->
pts
),
av_ts2timestr
(s->
second_frame
->
pts
, &ctx->
inputs
[
SECOND
]->
time_base
));
60
av_dlog
(ctx,
"\n"
);
61
62
if
(s->
second_frame
&& !ctx->
is_disabled
)
63
mainpic = s->
process
(ctx, mainpic, s->
second_frame
);
64
ret =
ff_filter_frame
(ctx->
outputs
[0], mainpic);
65
av_assert1
(ret !=
AVERROR
(EAGAIN));
66
s->
frame_requested
= 0;
67
return
ret
;
68
}
69
70
static
int
try_filter_next_frame
(
FFDualInputContext
*
s
,
AVFilterContext
*ctx)
71
{
72
AVFrame
*next_mainpic =
ff_bufqueue_peek
(&s->
queue
[
MAIN
], 0);
73
int
ret
;
74
75
if
(!next_mainpic)
76
return
AVERROR
(EAGAIN);
77
if
((ret =
try_filter_frame
(s, ctx, next_mainpic)) ==
AVERROR
(EAGAIN))
78
return
ret
;
79
ff_bufqueue_get
(&s->
queue
[
MAIN
]);
80
return
ret
;
81
}
82
83
static
int
flush_frames
(
FFDualInputContext
*
s
,
AVFilterContext
*ctx)
84
{
85
int
ret
;
86
87
while
(!(ret =
try_filter_next_frame
(s, ctx)));
88
return
ret ==
AVERROR
(EAGAIN) ? 0 :
ret
;
89
}
90
91
int
ff_dualinput_filter_frame_main
(
FFDualInputContext
*
s
,
92
AVFilterLink
*inlink,
AVFrame
*
in
)
93
{
94
AVFilterContext
*ctx = inlink->
dst
;
95
int
ret
;
96
97
if
((ret =
flush_frames
(s, ctx)) < 0)
98
return
ret
;
99
if
((ret =
try_filter_frame
(s, ctx, in)) < 0) {
100
if
(ret !=
AVERROR
(EAGAIN))
101
return
ret
;
102
ff_bufqueue_add
(ctx, &s->
queue
[
MAIN
], in);
103
}
104
105
if
(!s->
second_frame
)
106
return
0;
107
flush_frames
(s, ctx);
108
109
return
0;
110
}
111
112
int
ff_dualinput_filter_frame_second
(
FFDualInputContext
*
s
,
113
AVFilterLink
*inlink,
AVFrame
*
in
)
114
{
115
AVFilterContext
*ctx = inlink->
dst
;
116
int
ret
;
117
118
if
((ret =
flush_frames
(s, ctx)) < 0)
119
return
ret
;
120
ff_bufqueue_add
(ctx, &s->
queue
[
SECOND
], in);
121
ret =
try_filter_next_frame
(s, ctx);
122
return
ret ==
AVERROR
(EAGAIN) ? 0 :
ret
;
123
}
124
125
int
ff_dualinput_request_frame
(
FFDualInputContext
*
s
,
AVFilterLink
*outlink)
126
{
127
AVFilterContext
*ctx = outlink->
src
;
128
int
input,
ret
;
129
130
if
(!
try_filter_next_frame
(s, ctx))
131
return
0;
132
s->
frame_requested
= 1;
133
while
(s->
frame_requested
) {
134
/* TODO if we had a frame duration, we could guess more accurately */
135
input = !s->
second_eof
&& (s->
queue
[
MAIN
].
available
||
136
s->
queue
[
SECOND
].
available
< 2) ?
137
SECOND
:
MAIN
;
138
ret =
ff_request_frame
(ctx->
inputs
[input]);
139
/* EOF on main is reported immediately */
140
if
(ret ==
AVERROR_EOF
&& input ==
SECOND
) {
141
s->
second_eof
= 1;
142
if
(s->
shortest
)
143
return
ret
;
144
if
((ret =
try_filter_next_frame
(s, ctx)) !=
AVERROR
(EAGAIN))
145
return
ret
;
146
ret = 0;
/* continue requesting frames on main */
147
}
148
if
(ret < 0)
149
return
ret
;
150
}
151
return
0;
152
}
153
154
void
ff_dualinput_uninit
(
FFDualInputContext
*
s
)
155
{
156
av_frame_free
(&s->
second_frame
);
157
ff_bufqueue_discard_all
(&s->
queue
[
MAIN
]);
158
ff_bufqueue_discard_all
(&s->
queue
[
SECOND
]);
159
}
Generated on Wed Jul 10 2013 23:48:09 for FFmpeg by
1.8.2