[FFmpeg-devel] avformat/utils.c: allows av_read_frame to return after a timeout period.

Submitted by Gonzalo Garramuño on Nov. 28, 2019, 11:58 p.m.

Details

Message ID 20191128235854.2692-1-ggarra13@gmail.com
State New
Headers show

Commit Message

Gonzalo Garramuño Nov. 28, 2019, 11:58 p.m.
From: Gonzalo Garramuño <ggarra13@gmail.com>

Moved the check inside if (pktl) as per Michael Niedermayer's suggestion.
This patch is based on one from bsenftner at earthlink.net.
---
 libavformat/utils.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Michael Niedermayer Nov. 29, 2019, 6:35 p.m.
On Thu, Nov 28, 2019 at 08:58:54PM -0300, ggarra13@gmail.com wrote:
> From: Gonzalo Garramuño <ggarra13@gmail.com>
> 
> Moved the check inside if (pktl) as per Michael Niedermayer's suggestion.
> This patch is based on one from bsenftner at earthlink.net.
> ---
>  libavformat/utils.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 8196442dd1..1f5754d7d3 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -1795,6 +1795,11 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
>          AVPacketList *pktl = s->internal->packet_buffer;
>  
>          if (pktl) {
> +            if (ff_check_interrupt(&s->interrupt_callback)) {
> +                av_log(s, AV_LOG_DEBUG, "interrupted\n");
> +                return AVERROR_EXIT;
> +            }
> +
>              AVPacket *next_pkt = &pktl->pkt;
>  
>              if (next_pkt->dts != AV_NOPTS_VALUE) {

I would put it at the end of the "if (pktl) {" body
because if a packet gets processed and returned no interrupt check is needed

also, do we have a testcase where this loop hangs ?
if not please provide a testcase

Thanks

[...]
Gonzalo Garramuño Nov. 29, 2019, 11:50 p.m.
On 29/11/19 15:35, Michael Niedermayer wrote:

> also, do we have a testcase where this loop hangs ?
> if not please provide a testcase
I don't have an easy testcase, but it can be seen with any rtmp stream.  
A full test case can be reproduced like this:

Compile and create a nginx server like it is specified here:

  https://github.com/arut/nginx-rtmp-module/wiki/Getting-started-with-nginx-rtmp

Start the nginx server:
/usr/local/nginx/sbin/nginx

Start ffmpeg streaming:
ffmpeg -re -i long.mov -c copy -f flv rtmp://localhost/myapp/mystream

In another window, play the stream:
ffplay rtmp://localhost/myapp/mystream

Now, abort the ffmpeg process by CTRL-C.  ffplay will eventually hang 
and not allow it to close it when clicking on the close window button.  
With the patch, ffplay will eventually become responsive once again 
after the timeout period.

Patch hide | download patch | download mbox

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 8196442dd1..1f5754d7d3 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1795,6 +1795,11 @@  int av_read_frame(AVFormatContext *s, AVPacket *pkt)
         AVPacketList *pktl = s->internal->packet_buffer;
 
         if (pktl) {
+            if (ff_check_interrupt(&s->interrupt_callback)) {
+                av_log(s, AV_LOG_DEBUG, "interrupted\n");
+                return AVERROR_EXIT;
+            }
+
             AVPacket *next_pkt = &pktl->pkt;
 
             if (next_pkt->dts != AV_NOPTS_VALUE) {