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