Module: libav Branch: release/12 Commit: 4276b68651c3cec0c4786e6fb50dceed16593c71
Author: Anton Khirnov <[email protected]> Committer: Luca Barbato <[email protected]> Date: Sat Oct 1 21:07:42 2016 +0200 avconv: only retry decoding on actual decoding errors Errors during decoding are currently considered non-fatal and do not terminate transcoding, so even if parts of the data are corrupted, the rest may be decodable. However, that should apply only to the actual decoding calls, not to the failures elsewhere (e.g. configuring filters). (cherry picked from commit 27085d1b47c3741cc0fac284c916127c4066d049) Signed-off-by: Luca Barbato <[email protected]> Bug-Id: 1089 Thanks to Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University for reporting the issue on the release branch. --- avconv.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/avconv.c b/avconv.c index b2affe9..610ec9e 100644 --- a/avconv.c +++ b/avconv.c @@ -1326,7 +1326,8 @@ int guess_input_channel_layout(InputStream *ist) return 1; } -static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->dec_ctx; @@ -1339,6 +1340,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(avctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1377,7 +1380,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) return err < 0 ? err : ret; } -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; int i, ret = 0, err = 0; @@ -1389,6 +1393,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1429,13 +1435,16 @@ fail: return err < 0 ? err : ret; } -static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVSubtitle subtitle; int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); - if (ret < 0) + if (ret < 0) { + *decode_failed = 1; return ret; + } if (!*got_output) return ret; @@ -1491,16 +1500,19 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e while (ist->decoding_needed && (!pkt || avpkt.size > 0)) { int ret = 0; int got_output = 0; + int decode_failed = 0; if (!repeating) ist->last_dts = ist->next_dts; switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); if (repeating && !got_output) ; else if (pkt && pkt->duration) @@ -1517,16 +1529,21 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e case AVMEDIA_TYPE_SUBTITLE: if (repeating) break; - ret = transcode_subtitles(ist, &avpkt, &got_output); + ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed); break; default: return; } if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", - ist->file_index, ist->st->index); - if (exit_on_error) + if (decode_failed) { + av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", + ist->file_index, ist->st->index); + } else { + av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " + "data for stream #%d:%d\n", ist->file_index, ist->st->index); + } + if (!decode_failed || exit_on_error) exit_program(1); break; } _______________________________________________ libav-commits mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-commits
