Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Video AG Infrastruktur
ffworker
Commits
28b5ce61
Commit
28b5ce61
authored
Nov 26, 2017
by
Julian Rother
Browse files
transcode: Restructured mainloop to fix flushing
parent
8fce34c9
Changes
1
Hide whitespace changes
Inline
Side-by-side
transcode.c
View file @
28b5ce61
...
...
@@ -176,6 +176,54 @@ static void setup_output_stream(char *stream, AVStream *st, AVCodecContext *enc,
avcodec_parameters_from_context
(
st
->
codecpar
,
enc
);
}
static
void
flush_encoder
(
AVFormatContext
*
mux
,
AVFilterContext
*
sink
,
AVCodecContext
*
enc
,
int
idx
)
{
int
err
;
AVPacket
pkt
;
pkt
.
data
=
0
;
pkt
.
size
=
0
;
av_init_packet
(
&
pkt
);
while
(
!
avcodec_receive_packet
(
enc
,
&
pkt
))
{
pkt
.
stream_index
=
idx
;
av_packet_rescale_ts
(
&
pkt
,
sink
->
inputs
[
0
]
->
time_base
,
mux
->
streams
[
idx
]
->
time_base
);
if
(
err
=
av_interleaved_write_frame
(
mux
,
&
pkt
))
job_failed
(
"Could not write frame: %s"
,
av_err2str
(
err
));
}
}
static
void
flush_filtergraph
(
AVFormatContext
*
mux
,
AVFilterContext
**
sinks
,
AVCodecContext
**
encs
)
{
int
i
;
AVFrame
*
frame
;
if
(
!
(
frame
=
av_frame_alloc
()))
exit
(
99
);
for
(
i
=
0
;
i
<
mux
->
nb_streams
;
i
++
)
while
(
av_buffersink_get_frame
(
sinks
[
i
],
frame
)
>=
0
)
{
avcodec_send_frame
(
encs
[
i
],
frame
);
av_frame_unref
(
frame
);
flush_encoder
(
mux
,
sinks
[
i
],
encs
[
i
],
i
);
}
av_frame_free
(
&
frame
);
}
static
void
filtergraph_send
(
AVFilterContext
*
src
,
AVCodecContext
*
dec
,
AVPacket
*
pkt
)
{
int
err
;
AVFrame
*
frame
;
if
(
!
dec
||
!
src
)
return
;
if
(
!
(
frame
=
av_frame_alloc
()))
exit
(
99
);
avcodec_send_packet
(
dec
,
pkt
);
while
(
!
avcodec_receive_frame
(
dec
,
frame
))
if
((
err
=
av_buffersrc_add_frame
(
src
,
frame
))
<
0
)
job_failed
(
"Could not insert frame into filter graph: %s"
,
av_err2str
(
err
));
av_frame_free
(
&
frame
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
err
,
i
,
progress
,
_progress
;
...
...
@@ -186,7 +234,6 @@ int main(int argc, char *argv[])
AVFilterGraph
*
fg
;
AVFilterInOut
*
inpads
,
*
outpads
;
AVPacket
pkt
;
AVFrame
*
frame
;
AVStream
*
stream
;
AVDictionary
*
opts
;
if
(
argc
!=
5
)
...
...
@@ -194,10 +241,9 @@ int main(int argc, char *argv[])
av_register_all
();
avfilter_register_all
();
init_avlogbuf
();
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
=
0
;
pkt
.
size
=
0
;
av_init_packet
(
&
pkt
);
if
(
!
(
frame
=
av_frame_alloc
()))
return
99
;
if
(
!
(
fg
=
avfilter_graph_alloc
()))
return
99
;
...
...
@@ -253,6 +299,7 @@ int main(int argc, char *argv[])
progress
=
0
;
ping_job
(
jobid
,
"running"
,
0
);
while
(
!
av_read_frame
(
demux
,
&
pkt
))
{
i
=
pkt
.
stream_index
;
...
...
@@ -263,42 +310,27 @@ int main(int argc, char *argv[])
jescape
(
get_avlogbuf
()));
progress
=
_progress
;
}
if
(
!
decs
[
i
])
continue
;
avcodec_send_packet
(
decs
[
i
],
&
pkt
);
while
(
!
avcodec_receive_frame
(
decs
[
i
],
frame
))
if
((
err
=
av_buffersrc_add_frame
(
srcs
[
i
],
frame
))
<
0
)
job_failed
(
"Could not insert frame into filter graph: %s"
,
av_err2str
(
err
));
for
(
i
=
0
;
i
<
mux
->
nb_streams
;
i
++
)
while
(
av_buffersink_get_frame
(
sinks
[
i
],
frame
)
>=
0
)
{
avcodec_send_frame
(
encs
[
i
],
frame
);
av_frame_unref
(
frame
);
while
(
!
avcodec_receive_packet
(
encs
[
i
],
&
pkt
))
{
pkt
.
stream_index
=
i
;
av_packet_rescale_ts
(
&
pkt
,
sinks
[
i
]
->
inputs
[
0
]
->
time_base
,
mux
->
streams
[
i
]
->
time_base
);
if
(
err
=
av_interleaved_write_frame
(
mux
,
&
pkt
))
job_failed
(
"Could not write frame: %s"
,
av_err2str
(
err
));
}
}
filtergraph_send
(
srcs
[
i
],
decs
[
i
],
&
pkt
);
flush_filtergraph
(
mux
,
sinks
,
encs
);
}
avformat_close_input
(
&
demux
);
/* Flush */
for
(
i
=
0
;
i
<
demux
->
nb_streams
;
i
++
)
{
if
(
decs
[
i
])
continue
;
filtergraph_send
(
srcs
[
i
],
decs
[
i
],
0
);
!
av_buffersrc_add_frame
(
srcs
[
i
],
0
);
}
flush_filtergraph
(
mux
,
sinks
,
encs
);
for
(
i
=
0
;
i
<
mux
->
nb_streams
;
i
++
)
{
avcodec_send_frame
(
encs
[
i
],
0
);
while
(
!
avcodec_receive_packet
(
encs
[
i
],
&
pkt
))
{
pkt
.
stream_index
=
i
;
av_packet_rescale_ts
(
&
pkt
,
sinks
[
i
]
->
inputs
[
0
]
->
time_base
,
mux
->
streams
[
i
]
->
time_base
);
av_interleaved_write_frame
(
mux
,
&
pkt
);
}
flush_encoder
(
mux
,
sinks
[
i
],
encs
[
i
],
i
);
}
av_interleaved_write_frame
(
mux
,
0
);
avformat_close_input
(
&
demux
);
if
(
err
=
av_write_trailer
(
mux
))
job_failed
(
"Error writing trailer to temporary file"
,
av_err2str
(
err
));
avio_closep
(
&
mux
->
pb
);
...
...
Write
Preview
Supports
Markdown
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