mirror of https://git.ffmpeg.org/ffmpeg.git
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).
This commit is contained in:
parent
f6772e9bf8
commit
27085d1b47
37
avconv.c
37
avconv.c
|
@ -1326,7 +1326,8 @@ int guess_input_channel_layout(InputStream *ist)
|
||||||
return 1;
|
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;
|
AVFrame *decoded_frame, *f;
|
||||||
AVCodecContext *avctx = ist->dec_ctx;
|
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;
|
decoded_frame = ist->decoded_frame;
|
||||||
|
|
||||||
ret = decode(avctx, decoded_frame, got_output, pkt);
|
ret = decode(avctx, decoded_frame, got_output, pkt);
|
||||||
|
if (ret < 0)
|
||||||
|
*decode_failed = 1;
|
||||||
if (!*got_output || ret < 0)
|
if (!*got_output || ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1377,7 +1380,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||||
return err < 0 ? err : ret;
|
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;
|
AVFrame *decoded_frame, *f;
|
||||||
int i, ret = 0, err = 0;
|
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;
|
decoded_frame = ist->decoded_frame;
|
||||||
|
|
||||||
ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt);
|
ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt);
|
||||||
|
if (ret < 0)
|
||||||
|
*decode_failed = 1;
|
||||||
if (!*got_output || ret < 0)
|
if (!*got_output || ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1429,13 +1435,16 @@ fail:
|
||||||
return err < 0 ? err : ret;
|
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;
|
AVSubtitle subtitle;
|
||||||
int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
|
int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
|
||||||
&subtitle, got_output, pkt);
|
&subtitle, got_output, pkt);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
*decode_failed = 1;
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
if (!*got_output)
|
if (!*got_output)
|
||||||
return ret;
|
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)) {
|
while (ist->decoding_needed && (!pkt || avpkt.size > 0)) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int got_output = 0;
|
int got_output = 0;
|
||||||
|
int decode_failed = 0;
|
||||||
|
|
||||||
if (!repeating)
|
if (!repeating)
|
||||||
ist->last_dts = ist->next_dts;
|
ist->last_dts = ist->next_dts;
|
||||||
|
|
||||||
switch (ist->dec_ctx->codec_type) {
|
switch (ist->dec_ctx->codec_type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
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;
|
break;
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
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)
|
if (repeating && !got_output)
|
||||||
;
|
;
|
||||||
else if (pkt && pkt->duration)
|
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:
|
case AVMEDIA_TYPE_SUBTITLE:
|
||||||
if (repeating)
|
if (repeating)
|
||||||
break;
|
break;
|
||||||
ret = transcode_subtitles(ist, &avpkt, &got_output);
|
ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
|
if (decode_failed) {
|
||||||
ist->file_index, ist->st->index);
|
av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
|
||||||
if (exit_on_error)
|
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);
|
exit_program(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue