From c9f0d22f0ac19dcee7d1991020c75c8a3691b1b7 Mon Sep 17 00:00:00 2001
From: Warren Dukes <warren.dukes@gmail.com>
Date: Fri, 7 May 2004 19:11:43 +0000
Subject: [PATCH] rewrite outputBuffer'ing abstraction a bit to be more
 effecient and easier to interface.  Also, use outputBuffer abstraction for
 ogg

git-svn-id: https://svn.musicpd.org/mpd/trunk@941 09075e82-0dd4-0310-85a5-a0d7c8717e4f
---
 src/mp3_decode.c   | 19 ++++++-------
 src/ogg_decode.c   | 34 ++++++-----------------
 src/outputBuffer.c | 68 +++++++++++++++++++++++++++++-----------------
 src/outputBuffer.h |  7 +++--
 4 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/src/mp3_decode.c b/src/mp3_decode.c
index 973f96541..d3a6a592e 100644
--- a/src/mp3_decode.c
+++ b/src/mp3_decode.c
@@ -468,21 +468,15 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
 
 			if(data->outputPtr==data->outputBufferEnd) {
                                 ret = sendDataToOutputBuffer(cb,dc,
-                                                0,data->outputBuffer,
+                                                data->outputBuffer,
                                                 MP3_DATA_OUTPUT_BUFFER_SIZE,
                                                 data->elapsedTime,
                                                 data->bitRate/1000);
                                 if(ret == OUTPUT_BUFFER_DC_STOP) {
                                         return DECODE_BREAK;
                                 }
-                                if(ret >= 0) {
-                                        memmove(data->outputBuffer,
-                                                data->outputBuffer+ret,
-                                                MP3_DATA_OUTPUT_BUFFER_SIZE-
-                                                ret);
-                                        data->outputPtr-=ret;
-                                }
-                                else data->outputPtr = data->outputBuffer;
+
+                                data->outputPtr = data->outputBuffer;
 
                                 if(ret == OUTPUT_BUFFER_DC_SEEK) break;
 			}
@@ -545,9 +539,12 @@ int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
 	while(mp3Read(&data,cb,dc)!=DECODE_BREAK);
 	/* send last little bit if not dc->stop */
 	if(data.outputPtr!=data.outputBuffer && data.flush)  {
-        	sendDataToOutputBuffer(cb,dc,1,data.outputBuffer,
+        	if(sendDataToOutputBuffer(cb,dc,data.outputBuffer,
                                 data.outputPtr-data.outputBuffer,
-                                data.elapsedTime,data.bitRate/1000);
+                                data.elapsedTime,data.bitRate/1000) == 0)
+		{
+			flushOutputBuffer(cb);
+		}
 	}
 
 	mp3DecodeDataFinalize(&data);
diff --git a/src/ogg_decode.c b/src/ogg_decode.c
index 5aad02f78..709fbac23 100644
--- a/src/ogg_decode.c
+++ b/src/ogg_decode.c
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "pcm_utils.h"
 #include "inputStream.h"
+#include "outputBuffer.h"
 
 #include <stdio.h>
 #include <unistd.h>
@@ -132,41 +133,24 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
 				ov_time_seek_page(&vf,dc->seekWhere);
 				dc->seek = 0;
 			}
-			ret = ov_read(&vf,chunk+chunkpos,
-					CHUNK_SIZE-chunkpos,
+			ret = ov_read(&vf, chunk, CHUNK_SIZE,
 					OGG_DECODE_USE_BIGENDIAN,
-					2,1,
-					&current_section);
+					2, 1, &current_section);
 			if(ret<=0) eof = 1;
-			else chunkpos+=ret;
-			if(chunkpos>=CHUNK_SIZE || eof) {
-				while(cb->begin==cb->end && cb->wrap &&
-						!dc->stop && !dc->seek)
-				{
-					my_usleep(10000);
-				}
-				if(dc->stop) break;
-				else if(dc->seek) continue;
-        
-				memcpy(cb->chunks+cb->end*CHUNK_SIZE,
-						chunk,chunkpos);
-				cb->chunkSize[cb->end] = chunkpos;
-				chunkpos = 0;
-				cb->times[cb->end] = ov_time_tell(&vf);
+			else {
 				if((test = ov_bitrate_instant(&vf))>0) {
 					bitRate = test/1000;
 				}
-				cb->bitRate[cb->end] = bitRate;
-				cb->end++;
-				if(cb->end>=buffered_chunks) {
-					cb->end = 0;
-					cb->wrap = 1;
-				}
+				sendDataToOutputBuffer(cb,dc,chunk,ret,
+					ov_time_tell(&vf),bitRate);
+				if(dc->stop) break;
 			}
 		}
 
 		ov_clear(&vf);
 
+		flushOutputBuffer(cb);
+
 		if(dc->seek) dc->seek = 0;
 
 		if(dc->stop) {
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index 191ea7556..1861fe45a 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -24,39 +24,57 @@
 
 #include <string.h>
 
-long sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, 
-                int flushAllData, char * data, long datalen, float time, 
-		mpd_uint16 bitRate)
-{
-        long dataSent = 0;
-        long dataToSend;
-
-        while(datalen >= CHUNK_SIZE || (flushAllData && datalen)) {
-                dataToSend = datalen > CHUNK_SIZE ? CHUNK_SIZE : datalen;
-
-	        while(cb->begin==cb->end && cb->wrap && !dc->stop && !dc->seek) 
-		        my_usleep(10000);
-	        if(dc->stop) return OUTPUT_BUFFER_DC_STOP;
-	        /* just for now, so it doesn't hang */
-	        if(dc->seek) return OUTPUT_BUFFER_DC_SEEK;
-	        /* be sure to remove this! */
-
-	        memcpy(cb->chunks+cb->end*CHUNK_SIZE,data,dataToSend);
-	        cb->chunkSize[cb->end] = dataToSend;
-	        cb->bitRate[cb->end] = bitRate;
-	        cb->times[cb->end] = time;
+static mpd_sint16 currentChunk = -1;
 
+void flushOutputBuffer(OutputBuffer * cb) {
+	if(currentChunk == cb->end) {
 	        cb->end++;
 	        if(cb->end>=buffered_chunks) {
-		        cb->end = 0;
-		        cb->wrap = 1;
+		       	cb->end = 0;
+		       	cb->wrap = 1;
 	        }
+		currentChunk = -1;
+	}
+}
+
+int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, 
+                char * data, long datalen, float time, mpd_uint16 bitRate)
+{
+        mpd_uint16 dataToSend;
+	mpd_uint16 chunkLeft;
+
+        while(datalen) {
+		if(currentChunk != cb->end) {
+	        	while(cb->begin==cb->end && cb->wrap && !dc->stop && 
+					!dc->seek)
+			{
+		        	my_usleep(10000);
+			}
+	        	if(dc->stop) return OUTPUT_BUFFER_DC_STOP;
+	        	if(dc->seek) return OUTPUT_BUFFER_DC_SEEK;
+
+			currentChunk = cb->end;
+			cb->chunkSize[currentChunk] = 0;
+		}
+
+		chunkLeft = CHUNK_SIZE-cb->chunkSize[currentChunk];
+                dataToSend = datalen > chunkLeft ? chunkLeft : datalen;
+
+	        memcpy(cb->chunks+currentChunk*CHUNK_SIZE+
+			cb->chunkSize[currentChunk],
+			data, dataToSend);
+	        cb->chunkSize[currentChunk]+= dataToSend;
+	        cb->bitRate[currentChunk] = bitRate;
+	        cb->times[currentChunk] = time;
 
                 datalen-= dataToSend;
-                dataSent+= dataToSend;
                 data+= dataToSend;
+
+		if(cb->chunkSize[currentChunk] == CHUNK_SIZE) {
+			flushOutputBuffer(cb);
+		}
         }
 
-	return dataSent;
+	return 0;
 }
 /* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/outputBuffer.h b/src/outputBuffer.h
index 1a5335df2..00ff6b5bd 100644
--- a/src/outputBuffer.h
+++ b/src/outputBuffer.h
@@ -37,9 +37,10 @@ typedef struct _OutputBuffer {
 	float totalTime;
 } OutputBuffer;
 
-long sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, 
-               int flushAllData, char * data, long datalen, float time, 
-               mpd_uint16 bitRate);
+void flushOutputBuffer(OutputBuffer * cb);
+
+int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, 
+               char * data, long datalen, float time, mpd_uint16 bitRate);
 
 #endif
 /* vim:set shiftwidth=4 tabstop=8 expandtab: */