mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 21:40:34 +00:00
ffmpeg: Flush output BSFs when encode reaches EOF
Before this, output bitstream filters would never see EOF and
therefore would not be able to flush any delayed packets.
(cherry picked from commit f64d1100a5
)
This commit is contained in:
parent
4976a3411f
commit
bc4e33ce0f
41
ffmpeg.c
41
ffmpeg.c
@ -814,7 +814,19 @@ static void close_output_stream(OutputStream *ost)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
|
/*
|
||||||
|
* Send a single packet to the output, applying any bitstream filters
|
||||||
|
* associated with the output stream. This may result in any number
|
||||||
|
* of packets actually being written, depending on what bitstream
|
||||||
|
* filters are applied. The supplied packet is consumed and will be
|
||||||
|
* blank (as if newly-allocated) when this function returns.
|
||||||
|
*
|
||||||
|
* If eof is set, instead indicate EOF to all bitstream filters and
|
||||||
|
* therefore flush any delayed packets to the output. A blank packet
|
||||||
|
* must be supplied in this case.
|
||||||
|
*/
|
||||||
|
static void output_packet(OutputFile *of, AVPacket *pkt,
|
||||||
|
OutputStream *ost, int eof)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -822,10 +834,11 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
|
|||||||
if (ost->nb_bitstream_filters) {
|
if (ost->nb_bitstream_filters) {
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt);
|
ret = av_bsf_send_packet(ost->bsf_ctx[0], eof ? NULL : pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
eof = 0;
|
||||||
idx = 1;
|
idx = 1;
|
||||||
while (idx) {
|
while (idx) {
|
||||||
/* get a packet from the previous filter up the chain */
|
/* get a packet from the previous filter up the chain */
|
||||||
@ -834,19 +847,24 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
idx--;
|
idx--;
|
||||||
continue;
|
continue;
|
||||||
|
} else if (ret == AVERROR_EOF) {
|
||||||
|
eof = 1;
|
||||||
} else if (ret < 0)
|
} else if (ret < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
/* send it to the next filter down the chain or to the muxer */
|
/* send it to the next filter down the chain or to the muxer */
|
||||||
if (idx < ost->nb_bitstream_filters) {
|
if (idx < ost->nb_bitstream_filters) {
|
||||||
ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt);
|
ret = av_bsf_send_packet(ost->bsf_ctx[idx], eof ? NULL : pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
idx++;
|
idx++;
|
||||||
} else
|
eof = 0;
|
||||||
|
} else if (eof)
|
||||||
|
goto finish;
|
||||||
|
else
|
||||||
write_packet(of, pkt, ost, 0);
|
write_packet(of, pkt, ost, 0);
|
||||||
}
|
}
|
||||||
} else
|
} else if (!eof)
|
||||||
write_packet(of, pkt, ost, 0);
|
write_packet(of, pkt, ost, 0);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
@ -922,7 +940,7 @@ static void do_audio_out(OutputFile *of, OutputStream *ost,
|
|||||||
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
|
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
output_packet(of, &pkt, ost);
|
output_packet(of, &pkt, ost, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1010,7 +1028,7 @@ static void do_subtitle_out(OutputFile *of,
|
|||||||
pkt.pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
|
pkt.pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
|
||||||
}
|
}
|
||||||
pkt.dts = pkt.pts;
|
pkt.dts = pkt.pts;
|
||||||
output_packet(of, &pkt, ost);
|
output_packet(of, &pkt, ost, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,7 +1214,7 @@ static void do_video_out(OutputFile *of,
|
|||||||
pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->mux_timebase);
|
pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->mux_timebase);
|
||||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||||
|
|
||||||
output_packet(of, &pkt, ost);
|
output_packet(of, &pkt, ost, 0);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@ -1299,7 +1317,7 @@ static void do_video_out(OutputFile *of,
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame_size = pkt.size;
|
frame_size = pkt.size;
|
||||||
output_packet(of, &pkt, ost);
|
output_packet(of, &pkt, ost, 0);
|
||||||
|
|
||||||
/* if two pass, output log */
|
/* if two pass, output log */
|
||||||
if (ost->logfile && enc->stats_out) {
|
if (ost->logfile && enc->stats_out) {
|
||||||
@ -1930,6 +1948,7 @@ static void flush_encoders(void)
|
|||||||
fprintf(ost->logfile, "%s", enc->stats_out);
|
fprintf(ost->logfile, "%s", enc->stats_out);
|
||||||
}
|
}
|
||||||
if (ret == AVERROR_EOF) {
|
if (ret == AVERROR_EOF) {
|
||||||
|
output_packet(of, &pkt, ost, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ost->finished & MUXER_FINISHED) {
|
if (ost->finished & MUXER_FINISHED) {
|
||||||
@ -1938,7 +1957,7 @@ static void flush_encoders(void)
|
|||||||
}
|
}
|
||||||
av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
|
av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
|
||||||
pkt_size = pkt.size;
|
pkt_size = pkt.size;
|
||||||
output_packet(of, &pkt, ost);
|
output_packet(of, &pkt, ost, 0);
|
||||||
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
|
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
|
||||||
do_video_stats(ost, pkt_size);
|
do_video_stats(ost, pkt_size);
|
||||||
}
|
}
|
||||||
@ -2077,7 +2096,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
output_packet(of, &opkt, ost);
|
output_packet(of, &opkt, ost, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int guess_input_channel_layout(InputStream *ist)
|
int guess_input_channel_layout(InputStream *ist)
|
||||||
|
Loading…
Reference in New Issue
Block a user