diff mbox

[FFmpeg-devel] lavc: consider an error during decoder draining as EOF

Message ID 20170215075318.28498-1-nfxjfg@googlemail.com
State Superseded
Headers show

Commit Message

wm4 Feb. 15, 2017, 7:53 a.m. UTC
There is no reason that draining couldn't return an error or two. But
some decoders don't handle this very well, and might always return an
error. This can lead to API users getting into an infinite loop and
burning CPU, because no progress is made and EOF is never returned.

In fact, ffmpeg.c contains a hack against such a case. It is removed
with this patch. This particular error case seems to have been fixed
since the hack was added, though.

This might lose frames if decoding returns errors during draining.
---
 ffmpeg.c           | 6 ------
 libavcodec/utils.c | 6 +++---
 2 files changed, 3 insertions(+), 9 deletions(-)

Comments

Michael Niedermayer Feb. 15, 2017, 10:31 p.m. UTC | #1
On Wed, Feb 15, 2017 at 08:53:18AM +0100, wm4 wrote:
> There is no reason that draining couldn't return an error or two. But
> some decoders don't handle this very well, and might always return an
> error. This can lead to API users getting into an infinite loop and
> burning CPU, because no progress is made and EOF is never returned.
> 
> In fact, ffmpeg.c contains a hack against such a case. It is removed
> with this patch. This particular error case seems to have been fixed
> since the hack was added, though.
> 
> This might lose frames if decoding returns errors during draining.
> ---
>  ffmpeg.c           | 6 ------
>  libavcodec/utils.c | 6 +++---
>  2 files changed, 3 insertions(+), 9 deletions(-)

should be 2 patches, libavcodec one should bump minor version
"new" ffmpeg depends on the change (new version) otherwise it could get
stuck

thx

[...]
diff mbox

Patch

diff --git a/ffmpeg.c b/ffmpeg.c
index 06570c0dd0..bd54e66f08 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2529,12 +2529,6 @@  static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
                    ist->file_index, ist->st->index, av_err2str(ret));
             if (exit_on_error)
                 exit_program(1);
-            // Decoding might not terminate if we're draining the decoder, and
-            // the decoder keeps returning an error.
-            // This should probably be considered a libavcodec issue.
-            // Sample: fate-vsynth1-dnxhd-720p-hr-lb
-            if (!pkt)
-                eof_reached = 1;
             break;
         }
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index f4085bf7a7..0a72dd684d 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -2807,12 +2807,12 @@  static int do_decode(AVCodecContext *avctx, AVPacket *pkt)
     if (ret == AVERROR(EAGAIN))
         ret = pkt->size;
 
-    if (ret < 0)
-        return ret;
-
     if (avctx->internal->draining && !got_frame)
         avctx->internal->draining_done = 1;
 
+    if (ret < 0)
+        return ret;
+
     if (ret >= pkt->size) {
         av_packet_unref(avctx->internal->buffer_pkt);
     } else {