[FFmpeg-devel] [PATCH] ALSA for libavdevice

Michael Niedermayer michaelni
Wed Dec 17 04:44:22 CET 2008


On Tue, Dec 16, 2008 at 09:22:43PM +0100, Nicolas George wrote:
> Le sextidi 26 frimaire, an CCXVII, Michael Niedermayer a ?crit?:
> > choose which you prefer, if it causes problems in reality (which i admit is
> > unlikely) it can be changed later
> 
> Ok. I agree, the actual choice does probably not matter much; I left
> microseconds because I think this is marginally the simplest.
> 
> Here is the latest version of the patch. I fixed the rounding error you
> reported; I made the playback fail if the sample rate is not available; and
> I removed an useless error check.
[...]
> +int ff_alsa_xrun_recover(AVFormatContext *s1, int err)
> +{
> +    AlsaData *s = s1->priv_data;
> +    snd_pcm_t *handle = s->h;
> +
> +    av_log(s1, AV_LOG_WARNING, "ALSA buffer xrun.\n");
> +    if (err == -EPIPE) {
> +        err = snd_pcm_prepare(handle);
> +        if (err < 0) {

> +            av_log(s1, AV_LOG_ERROR, "cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err));
> +
> +            return AVERROR_IO;
> +        }
> +    } else if (err == -ESTRPIPE) {
> +        av_log(NULL, AV_LOG_ERROR, "-ESTRPIPE... Unsupported!\n");
                  ^^^^
this should be s1


[...]
> +static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
> +{
> +    AlsaData *s = s1->priv_data;
> +    AVStream *st = s1->streams[0];
> +    int res;
> +    snd_htimestamp_t timestamp;
> +    snd_pcm_uframes_t ts_delay;
> +
> +    if (av_new_packet(pkt, s->period_size) < 0) {
> +        return AVERROR(EIO);
> +    }
> +
> +    while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / s->frame_size)) < 0) {
> +        if (res == -EAGAIN) {

> +            pkt->size = 0;

unneeded?


> +            av_free_packet(pkt);
> +
> +            return AVERROR(EAGAIN);
> +        }
> +        if (ff_alsa_xrun_recover(s1, res) < 0) {
> +            av_log(s1, AV_LOG_ERROR, "Alsa read error: %s\n",
> +                   snd_strerror(res));
> +            av_free_packet(pkt);
> +
> +            return AVERROR(EIO);
> +        }
> +    }
> +
> +    snd_pcm_htimestamp(s->h, &ts_delay, &timestamp);
> +    ts_delay += res;
> +    pkt->pts = (int64_t)timestamp.tv_sec * 1000000 +
> +        (timestamp.tv_nsec + 500) / 1000;

> +    pkt->pts -= (int64_t)(ts_delay * 1000000 + st->codec->sample_rate / 2) /
> +        st->codec->sample_rate;

if the cast is supposed to prevent an overflow of ts_delay * 1000000 then its
at the wrong spot. Otherwise i dont see why the cast is there at all

besides this the rounding is still not correct, following is correct
pkt->pts = timestamp.tv_sec * 1000000LL
          + ( timestamp.tv_nsec * st->codec->sample_rate
             -ts_delay * 1000000000LL + st->codec->sample_rate*500LL) / (st->codec->sample_rate * 1000LL)

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

No snowflake in an avalanche ever feels responsible. -- Voltaire
-------------- 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/20081217/858da118/attachment.pgp>



More information about the ffmpeg-devel mailing list