[FFmpeg-devel] [PATCH] What is missing for working AVFMT_FLAG_NONBLOCK?

Michael Niedermayer michaelni
Tue Mar 3 15:32:35 CET 2009


On Tue, Mar 03, 2009 at 03:21:41PM +0100, Michael Niedermayer wrote:
> On Tue, Mar 03, 2009 at 02:01:48PM +0100, Luca Abeni wrote:
> > Hi Michael,
> > Michael Niedermayer wrote:
> >> On Tue, Mar 03, 2009 at 03:06:21AM +0100, Michael Niedermayer wrote:
> >>> Hi
> >>>
> >>> AVFMT_FLAG_NONBLOCK is not enabled in ffmpeg/ffplay.c
> >>> what is missing for it?
> >>> capturing from several devices is likely going to work better if they
> >>> dont block. And yes i know it all should be using select() but that is
> >>> harder. And simple polling with non blocking demuxers should already
> >>> work pretty well.
> >
> > I guess you want to set AVFMT_FLAG_NONBLOCK on input files, right?
> > It seems to me that your patch sets it on the output... The attached
> > fix-ffmpeg-nonblock.diff sets the flag for the inputs too (I hope ;-).
> 
> yes :)
> 
> 
> >
> > I tried it, and it already uncovered a small bug in the alsa input
> > device (see attached fix-alsa-nonblock.diff.
> 
> ok (if iam supposed to review it ...)
> 
> 
> >
> > I tested capturing some audio with the two attached patches (without them,
> > nothing changes...) and it seems to me that this is working (easy,,, I
> > only have a single input ;-). I see a near-100% CPU load, so I guess a
> > usleep() somewhere (or something similar) is really needed.
> 
> sched_yield() should be added IMHO, usleep() just feels like the wrong thing

new patch below, will apply tomorrow unless objections comments for improvment
regtests passed of course

Index: ffmpeg.c
===================================================================
--- ffmpeg.c	(revision 17740)
+++ ffmpeg.c	(working copy)
@@ -31,6 +31,7 @@
 #include <signal.h>
 #include <limits.h>
 #include <unistd.h>
+#include <sched.h>
 #include "libavformat/avformat.h"
 #include "libavdevice/avdevice.h"
 #include "libswscale/swscale.h"
@@ -1559,6 +1560,8 @@
     AVInputFile *file_table;
     int key;
     int want_sdp = 1;
+    uint8_t no_packet[MAX_FILES]={0};
+    int no_packet_count=0;
 
     file_table= av_mallocz(nb_input_files * sizeof(AVInputFile));
     if (!file_table)
@@ -2067,6 +2070,8 @@
             ost = ost_table[i];
             os = output_files[ost->file_index];
             ist = ist_table[ost->source_index];
+            if(no_packet[ist->file_index])
+                continue;
             if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO)
                 opts = ost->sync_opts * av_q2d(ost->st->codec->time_base);
             else
@@ -2089,6 +2094,12 @@
         }
         /* if none, if is finished */
         if (file_index < 0) {
+            if(no_packet_count){
+                no_packet_count=0;
+                memset(no_packet, 0, sizeof(no_packet));
+                sched_yield();
+                continue;
+            }
             break;
         }
 
@@ -2103,8 +2114,11 @@
         /* read a frame from it and output it in the fifo */
         is = input_files[file_index];
         ret= av_read_frame(is, &pkt);
-        if(ret == AVERROR(EAGAIN) && strcmp(is->iformat->name, "ffm"))
+        if(ret == AVERROR(EAGAIN) && strcmp(is->iformat->name, "ffm")){
+            no_packet[file_index]=1;
+            no_packet_count++;
             continue;
+        }
         if (ret < 0) {
             file_table[file_index].eof_reached = 1;
             if (opt_shortest)
@@ -2113,6 +2127,9 @@
                 continue;
         }
 
+        no_packet_count=0;
+        memset(no_packet, 0, sizeof(no_packet));
+
         if (do_pkt_dump) {
             av_pkt_dump_log(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump);
         }
@@ -2822,6 +2839,7 @@
     ic->video_codec_id   = find_codec_or_die(video_codec_name   , CODEC_TYPE_VIDEO   , 0);
     ic->audio_codec_id   = find_codec_or_die(audio_codec_name   , CODEC_TYPE_AUDIO   , 0);
     ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 0);
+    ic->flags |= AVFMT_FLAG_NONBLOCK;
 
     /* open the input file with generic libav function */
     err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
@@ -3412,6 +3430,7 @@
     oc->preload= (int)(mux_preload*AV_TIME_BASE);
     oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
     oc->loop_output = loop_output;
+    oc->flags |= AVFMT_FLAG_NONBLOCK;
 
     set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
 
[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If a bugfix only changes things apparently unrelated to the bug with no
further explanation, that is a good sign that the bugfix is wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090303/10799381/attachment.pgp>



More information about the ffmpeg-devel mailing list