Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linuxtv-softmpeg] audio.c patch
Hello Michael,
I finally figured out what the problem with my audio stream playback was.
I try to play an SVCD compliant mpeg stream. The audio has a 44100Hz sample
rate. With this sample rate the frame size is not constant. That caused lots
of problems. I fixed this issue in audio.c.
Unfortunately I do not know how it affects other types of mpeg streams. In
theory it should be fine :-).
So I attach a patch that contains my fix. Please review it in case I made any
mistakes here. The audio decoding now works for this, but the playback is
still jerky.
I will look at the video decoding problem next. I guess it has to do with the
frame resolution not being 768x576.
regards Carsten
Index: audio.c
===================================================================
RCS file: /cvs/linuxtv/libsoftmpeg/src/audio.c,v
retrieving revision 1.21
diff -u -3 -p -b -B -r1.21 audio.c
--- audio.c 21 Feb 2004 16:01:22 -0000 1.21
+++ audio.c 24 Feb 2004 19:18:47 -0000
@@ -442,8 +442,8 @@ int check_and_write_audio_pes(struct aud
}
if (expect < d->current->len) {
AUDIO_PES("broken audio data chunk. too much data - deleting data (have: %d, expect:%d, diff:%d)\n", d->current->len, expect, d->current->len - expect);
- d->current->len = expect;
}
+ d->current->len = expect;
#if 0
AUDIO_PES("as.pts_begin:");
printpts(stderr, d->as.pts_begin);
@@ -483,6 +483,8 @@ int audio_handle_pes_data(struct audio_d
int delay = 0;
int ret = 0;
+ memset (&ac,0,sizeof(struct audio_config));
+
if (!d->current) {
SOFTMPEG_ERROR("no current! no decoding...\n");
return 0;
@@ -519,7 +521,7 @@ int audio_handle_pes_data(struct audio_d
if (d->as.len >= 4) {
if (0 == decode_header(&ac, d->as.buf[0] << 24 | d->as.buf[1] << 16 | d->as.buf[2] << 8 | d->as.buf[3])) {
AUDIO_PES("still in sync at beginning of buffer (%d,%d)\n",d->as.scanning_for_first_frame,d->as.synced_to_frame);
- // AUDIO_DEBUG("sample_rate:%d, bit_rate:%d, channels:%d\n",ac.sample_rate, ac.bit_rate, ac.nb_channels);
+ AUDIO_DEBUG("sample_rate:%d, bit_rate:%d, channels:%d\n",ac.sample_rate, ac.bit_rate, ac.nb_channels);
} else {
AUDIO_PES("ouch lost sync!\n");
d->as.synced_to_frame = 0;
@@ -554,7 +556,7 @@ int audio_handle_pes_data(struct audio_d
}
if (ac.sample_rate != d->config.sample_rate || ac.nb_channels != d->config.nb_channels) {
- AUDIO_PES("audio configuration changed");
+ AUDIO_PES("audio configuration changed\n");
memcpy(&d->config, &ac, sizeof(ac));
audio_reconfigure(d, d->config.sample_rate, d->config.nb_channels);
}
@@ -600,32 +602,37 @@ int audio_handle_pes_data(struct audio_d
delay = ret;
}
}
+ /* next frame could be of different size */
+ if (decode_header(&ac, d->as.buf[0] << 24 | d->as.buf[1] << 16 | d->as.buf[2] << 8 | d->as.buf[3])) {
+ AUDIO_PES("invalid header,lost sync!\n");
+ d->as.synced_to_frame = 0;
+ return delay;
+ }
if (d->as.len >= ac.frame_size) {
int ret;
- int i = 0;
unsigned char *ptr = d->as.buf;
while (d->as.len > ac.frame_size) {
int chunk_len = 0;
- AUDIO_PES("writing %d bytes to avcodec\n", ac.frame_size);
- ret = avcodec_decode_audio(d->codec_ctx, (int16_t *) (d->current->buf + d->current->len), &chunk_len, ptr, ac.frame_size);
- if (ac.frame_size == ret) {
+ AUDIO_PES("writing %d bytes to avcodec\n", d->as.len);
+ ret = avcodec_decode_audio(d->codec_ctx, (int16_t *) (d->current->buf + d->current->len), &chunk_len, ptr, d->as.len);
+ if (ret > 0) {
if (0 != chunk_len) {
d->current->len += chunk_len;
+ ptr += ret;
+ d->as.len -= ret;
} else {
SOFTMPEG_ERROR("mpeg audio frame decoding failed\n");
}
} else {
SOFTMPEG_ERROR("some error while mpeg audio frame decoding\n");
}
- ptr += ac.frame_size;
- d->as.len -= ac.frame_size;
+
AUDIO_PES("current audio buf has %d samples, pes store has %d bytes\n", d->current->len,d->as.len);
- i++;
}
AUDIO_PES("moving %d bytes to front \n", d->as.len);
if (0 != d->as.len) {
- memmove(d->as.buf, d->as.buf + (i*ac.frame_size), d->as.len);
+ memmove(d->as.buf, ptr, d->as.len);
}
}
Home |
Main Index |
Thread Index