Message ID | 20210221164659.19180-2-cus@passwd.hu |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,1/5] avdevice/alsa_dec: do not set codecpar frame_size | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
Marton Balint (12021-02-21): > 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@passwd.hu> > --- > libavdevice/alsa_dec.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) Looping snd_pcm_readi() seems like a more robust solution to this issue. Regards,
On Sun, 28 Feb 2021, Nicolas George wrote: > Marton Balint (12021-02-21): >> 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@passwd.hu> >> --- >> libavdevice/alsa_dec.c | 18 ++++++++++++++++++ >> 1 file changed, 18 insertions(+) > > Looping snd_pcm_readi() seems like a more robust solution to this issue. Robust how? For non-blocking mode that would mean you have to keep the read data in the context if you read less than period size. Doable, but I wanted to avoid it. Regards, Marton
Marton Balint (12021-02-28): > Robust how? For non-blocking mode that would mean you have to keep the read > data in the context if you read less than period size. Doable, but I wanted > to avoid it. That is exactly what I am suggesting. It does not rely on less tested functions like snd_pcm_avail() (I have observed bugs with this kind of functions and some of the infrastructure plugins), and it does not require starting the PCM manually at seemingly random places in the code. Regards,
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); }
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@passwd.hu> --- libavdevice/alsa_dec.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)