[FFmpeg-devel] [PATCH 2/5] avdevice/alsa_dec: make sure we have enough data in non-blocking mode

Marton Balint cus at passwd.hu
Sun Feb 21 18:46:56 EET 2021


Otherwise we might return 1-2 samples per packet if av_read_frame() call rate is
only sligthly less than the stream sample rate.

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 libavdevice/alsa_dec.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/libavdevice/alsa_dec.c b/libavdevice/alsa_dec.c
index 6d568737b3..8e5c53f56b 100644
--- a/libavdevice/alsa_dec.c
+++ b/libavdevice/alsa_dec.c
@@ -78,6 +78,12 @@ static av_cold int audio_read_header(AVFormatContext *s1)
         return AVERROR(EIO);
     }
 
+    ret = snd_pcm_start(s->h);
+    if (ret < 0) {
+        av_log(s1, AV_LOG_ERROR, "cannot start pcm (%s)\n", snd_strerror(ret));
+        goto fail;
+    }
+
     /* take real parameters */
     st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id    = codec_id;
@@ -104,6 +110,13 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
     int64_t dts;
     snd_pcm_sframes_t delay = 0;
 
+    // Avoid returning 1-2 samples if call rate is slightly less than sample rate
+    if (s1->flags & AVFMT_FLAG_NONBLOCK) {
+        res = snd_pcm_avail(s->h);
+        if (res >= 0 && res < s->period_size)
+            return AVERROR(EAGAIN);
+    }
+
     if (av_new_packet(pkt, s->period_size * s->frame_size) < 0) {
         return AVERROR(EIO);
     }
@@ -121,6 +134,11 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
 
             return AVERROR(EIO);
         }
+        res = snd_pcm_start(s->h);
+        if (res < 0) {
+            av_log(s1, AV_LOG_ERROR, "cannot start pcm after recovery (%s)\n", snd_strerror(res));
+            return AVERROR(EIO);
+        }
         ff_timefilter_reset(s->timefilter);
     }
 
-- 
2.26.2



More information about the ffmpeg-devel mailing list