Commit 28b5ce61 authored by Julian Rother's avatar Julian Rother

transcode: Restructured mainloop to fix flushing

parent 8fce34c9
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment