[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, ×tamp);
> + 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