--- alsa-plugins-1.0.14rc2/a52/pcm_a52.c 2007-01-15 14:38:28.000000000 +0100 +++ alsa-plugins-1.0.14rc2.orig/a52/pcm_a52.c 2007-02-01 14:10:12.000000000 +0100 @@ -55,6 +55,7 @@ out_bytes = avcodec_encode_audio(rec->avctx, rec->outbuf + 8, rec->outbuf_size - 8, rec->inbuf); + rec->outbuf[0] = 0xf8; /* sync words */ rec->outbuf[1] = 0x72; rec->outbuf[2] = 0x4e; @@ -68,7 +69,7 @@ swab(rec->outbuf, rec->outbuf, out_bytes + 8); memset(rec->outbuf + 8 + out_bytes, 0, rec->outbuf_size - 8 - out_bytes); - rec->remain = rec->outbuf_size / 4; + rec->remain += rec->outbuf_size / 4; rec->filled = 0; } @@ -76,18 +77,38 @@ static int write_out_pending(snd_pcm_ioplug_t *io, struct a52_ctx *rec) { int err, ofs = 0; + snd_pcm_status_t *pcm_stat; + int wait_result; if (! rec->remain) return 0; + snd_pcm_status_alloca(&pcm_stat); while (rec->remain) { + if ( (snd_pcm_state(rec->slave) == SND_PCM_STATE_RUNNING) ) { + snd_pcm_status(rec->slave, pcm_stat); + int avail = snd_pcm_status_get_avail(pcm_stat); + while ( avail < rec->remain) { + //wait_result = snd_pcm_wait(rec->slave, 10000); + usleep(100); +// if (wait_result < 0) return 0; + snd_pcm_status(rec->slave, pcm_stat); + avail = snd_pcm_status_get_avail(pcm_stat); + } + } err = snd_pcm_writei(rec->slave, rec->outbuf + ofs, rec->remain); if (err < 0) { - if (err == -EPIPE) + printf("Write error\n"); + if (err == -EPIPE) { + printf("epipe\n"); io->state = SND_PCM_STATE_XRUN; + } + return err; - } else if (! err) + } else if (! err) { + io->state = SND_PCM_STATE_RUNNING; break; + } if (err < rec->remain) ofs += (rec->remain - err) * 4; rec->remain -= err; @@ -104,7 +125,7 @@ { struct a52_ctx *rec = io->private_data; int err; - +printf("draining\n"); if (rec->filled) { if ((err = write_out_pending(io, rec)) < 0) return err; @@ -154,8 +175,9 @@ unsigned int src_step; int err; - if ((err = write_out_pending(io, rec)) < 0) + if ((err = write_out_pending(io, rec)) < 0) { return err; + } if (size > len) size = len; @@ -189,7 +211,8 @@ } } rec->filled += size; - if (rec->filled == rec->avctx->frame_size) { + float val = rec->filled/(1.0*rec->avctx->frame_size); + if (val == (int)val) { convert_data(rec); write_out_pending(io, rec); } @@ -211,8 +234,10 @@ do { err = fill_data(io, areas, offset, size, interleaved); - if (err < 0) + if (err < 0) { + printf("fill data error\n"); break; + } offset += (unsigned int)err; size -= (unsigned int)err; result += err; @@ -421,6 +446,8 @@ { struct a52_ctx *rec = io->private_data; + avcodec_init(); + a52_free(rec); rec->avctx = avcodec_alloc_context(); @@ -446,6 +473,7 @@ rec->remain = 0; rec->filled = 0; + return snd_pcm_prepare(rec->slave); } @@ -545,6 +573,7 @@ snd_pcm_hw_params_get_buffer_size_max(rec->hw_params, &buffer_max); period_bytes = A52_FRAME_SIZE * 2 * rec->channels; max_periods = buffer_max / A52_FRAME_SIZE; +printf("periods: %d\n", max_periods); if ((err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, period_bytes, period_bytes)) < 0 ||