do input buffering in while sleeping loop of sending stuff to output buffer
git-svn-id: https://svn.musicpd.org/mpd/trunk@1125 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
		
							
								
								
									
										13
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								TODO
									
									
									
									
									
								
							| @@ -1,21 +1,16 @@ | |||||||
| 1) play streams | 1) play streams | ||||||
| 	a) make seekings non-blocking: | 	a) deal with pausing better | ||||||
| 		1) player: first check that seekWhere isn't already buffered |  | ||||||
| 	b) bufferInput in outputBuffer waiting! |  | ||||||
| 		1) implement some sort of callback mechanism for this |  | ||||||
| 			for abstraction sake |  | ||||||
| 	c) deal with pausing better |  | ||||||
| 		1) seekable, on resuming pause, check if we need to reconnect, | 		1) seekable, on resuming pause, check if we need to reconnect, | ||||||
| 			jumping to offset | 			jumping to offset | ||||||
| 		2) if seekable, at some point after init, mark this! | 		2) if seekable, at some point after init, mark this! | ||||||
| 		3) if not seekable, reset buffer, and elapsedTime when | 		3) if not seekable, reset buffer, and elapsedTime when | ||||||
| 			unpaused | 			unpaused | ||||||
| 	d) put some sort of error reporting for streaming/inputStream! | 	b) put some sort of error reporting for streaming/inputStream! | ||||||
| 	e) fetch metadata and store in DecoderControl and pass to  | 	c) fetch metadata and store in DecoderControl and pass to  | ||||||
| 		PlayerControl | 		PlayerControl | ||||||
| 		1) eventually deal with icy-metadata | 		1) eventually deal with icy-metadata | ||||||
| 		2) parse metadata on the fly in decoders | 		2) parse metadata on the fly in decoders | ||||||
| 	f) command for dealing with the changing metadata, currentsonginfo | 	d) command for dealing with the changing metadata, currentsonginfo | ||||||
| 		or something | 		or something | ||||||
|  |  | ||||||
| 2) how to deal with streams and the db | 2) how to deal with streams and the db | ||||||
|   | |||||||
| @@ -362,8 +362,8 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) { | |||||||
| 			 | 			 | ||||||
| 		sampleBufferLen = sampleCount*2; | 		sampleBufferLen = sampleCount*2; | ||||||
|  |  | ||||||
| 		sendDataToOutputBuffer(cb,dc,sampleBuffer,sampleBufferLen, | 		sendDataToOutputBuffer(cb, NULL, dc, sampleBuffer, | ||||||
| 				time,bitRate); |                                 sampleBufferLen, time, bitRate); | ||||||
| 		if(dc->seek) dc->seek = 0; | 		if(dc->seek) dc->seek = 0; | ||||||
| 		else if(dc->stop) { | 		else if(dc->stop) { | ||||||
| 			eof = 1; | 			eof = 1; | ||||||
|   | |||||||
| @@ -109,7 +109,11 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) { | |||||||
| 			if(ret<=0) eof = 1; | 			if(ret<=0) eof = 1; | ||||||
| 			else { | 			else { | ||||||
| 				current += ret; | 				current += ret; | ||||||
| 				sendDataToOutputBuffer(cb,dc,chunk,ret*fs, | 				sendDataToOutputBuffer(cb,  | ||||||
|  |                                         NULL, | ||||||
|  |                                         dc, | ||||||
|  |                                         chunk, | ||||||
|  |                                         ret*fs, | ||||||
| 					(float)current / | 					(float)current / | ||||||
| 					(float)dc->audioFormat.sampleRate, | 					(float)dc->audioFormat.sampleRate, | ||||||
| 					bitRate); | 					bitRate); | ||||||
|   | |||||||
| @@ -376,8 +376,8 @@ int flacSendChunk(FlacData * data) { | |||||||
|         doReplayGain(data->chunk,data->chunk_length,&(data->dc->audioFormat), |         doReplayGain(data->chunk,data->chunk_length,&(data->dc->audioFormat), | ||||||
|                         data->replayGainScale); |                         data->replayGainScale); | ||||||
|  |  | ||||||
| 	switch(sendDataToOutputBuffer(data->cb,data->dc,data->chunk, | 	switch(sendDataToOutputBuffer(data->cb, NULL, data->dc, data->chunk, | ||||||
| 			data->chunk_length,data->time,data->bitRate))  | 			data->chunk_length, data->time, data->bitRate))  | ||||||
| 	{ | 	{ | ||||||
| 	case OUTPUT_BUFFER_DC_STOP: | 	case OUTPUT_BUFFER_DC_STOP: | ||||||
| 		return -1; | 		return -1; | ||||||
|   | |||||||
| @@ -53,6 +53,9 @@ int openInputStream(InputStream * inStream, char * url); | |||||||
| int seekInputStream(InputStream * inStream, long offset, int whence); | int seekInputStream(InputStream * inStream, long offset, int whence); | ||||||
| int closeInputStream(InputStream * inStream); | int closeInputStream(InputStream * inStream); | ||||||
| int inputStreamAtEOF(InputStream * inStream); | int inputStreamAtEOF(InputStream * inStream); | ||||||
|  |  | ||||||
|  | /* return value: -1 is error, 1 inidicates stuff was buffered, 0 means nothing | ||||||
|  |    was buffered */ | ||||||
| int bufferInputStream(InputStream * inStream); | int bufferInputStream(InputStream * inStream); | ||||||
|  |  | ||||||
| size_t readFromInputStream(InputStream * inStream, void * ptr, size_t size, | size_t readFromInputStream(InputStream * inStream, void * ptr, size_t size, | ||||||
|   | |||||||
| @@ -542,20 +542,20 @@ int inputStream_httpBuffer(InputStream * inStream) { | |||||||
|                 readed = read(data->sock, data->buffer+data->buflen,  |                 readed = read(data->sock, data->buffer+data->buflen,  | ||||||
|                                 (size_t)(HTTP_BUFFER_SIZE-1-data->buflen)); |                                 (size_t)(HTTP_BUFFER_SIZE-1-data->buflen)); | ||||||
|  |  | ||||||
|                 if(readed < 0 && (errno == EAGAIN || errno == EINTR)); |                 if(readed < 0 && (errno == EAGAIN || errno == EINTR)) { | ||||||
|  |                         readed = 0; | ||||||
|  |                 } | ||||||
|                 else if(readed <= 0) { |                 else if(readed <= 0) { | ||||||
|                         close(data->sock); |                         close(data->sock); | ||||||
|                         data->connState = HTTP_CONN_STATE_CLOSED; |                         data->connState = HTTP_CONN_STATE_CLOSED; | ||||||
|  |                         readed = 0; | ||||||
|                 } |                 } | ||||||
|                 else { | 		/*fwrite(data->buffer+data->buflen,1,readed,stdout);*/ | ||||||
| 			/*fwrite(data->buffer+data->buflen,1,readed,stdout);*/ | 		data->buflen += readed; | ||||||
| 			data->buflen += readed; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 	if(data->buflen > HTTP_PREBUFFER_SIZE) data->prebuffer = 0; | 	if(data->buflen > HTTP_PREBUFFER_SIZE) data->prebuffer = 0; | ||||||
|  |  | ||||||
|         return 0; |         return (readed ? 1 : 0); | ||||||
| } | } | ||||||
| /* vim:set shiftwidth=8 tabstop=8 expandtab: */ | /* vim:set shiftwidth=8 tabstop=8 expandtab: */ | ||||||
|   | |||||||
| @@ -494,7 +494,9 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) { | |||||||
|  |  | ||||||
| 			if(data->outputPtr==data->outputBufferEnd) { | 			if(data->outputPtr==data->outputBufferEnd) { | ||||||
|                                 long ret; |                                 long ret; | ||||||
|                                 ret = sendDataToOutputBuffer(cb,dc, |                                 ret = sendDataToOutputBuffer(cb, | ||||||
|  |                                                 data->inStream, | ||||||
|  |                                                 dc, | ||||||
|                                                 data->outputBuffer, |                                                 data->outputBuffer, | ||||||
|                                                 MP3_DATA_OUTPUT_BUFFER_SIZE, |                                                 MP3_DATA_OUTPUT_BUFFER_SIZE, | ||||||
|                                                 data->elapsedTime, |                                                 data->elapsedTime, | ||||||
| @@ -584,7 +586,7 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) { | |||||||
| 	while(mp3Read(&data,cb,dc)!=DECODE_BREAK); | 	while(mp3Read(&data,cb,dc)!=DECODE_BREAK); | ||||||
| 	/* send last little bit if not dc->stop */ | 	/* send last little bit if not dc->stop */ | ||||||
| 	if(data.outputPtr!=data.outputBuffer && data.flush)  { | 	if(data.outputPtr!=data.outputBuffer && data.flush)  { | ||||||
|         	if(sendDataToOutputBuffer(cb,dc,data.outputBuffer, |         	if(sendDataToOutputBuffer(cb,NULL,dc,data.outputBuffer, | ||||||
|                                 data.outputPtr-data.outputBuffer, |                                 data.outputPtr-data.outputBuffer, | ||||||
|                                 data.elapsedTime,data.bitRate/1000) == 0) |                                 data.elapsedTime,data.bitRate/1000) == 0) | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -279,8 +279,8 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) { | |||||||
|  |  | ||||||
| 		sampleBuffer+=offset*channels*2; | 		sampleBuffer+=offset*channels*2; | ||||||
|  |  | ||||||
| 		sendDataToOutputBuffer(cb,dc,sampleBuffer, | 		sendDataToOutputBuffer(cb, NULL, dc, sampleBuffer, | ||||||
| 				sampleBufferLen,time,bitRate); | 				sampleBufferLen, time, bitRate); | ||||||
| 		if(dc->stop) { | 		if(dc->stop) { | ||||||
| 			eof = 1; | 			eof = 1; | ||||||
| 			break; | 			break; | ||||||
|   | |||||||
| @@ -241,16 +241,16 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) | |||||||
| 				} | 				} | ||||||
|                                 doReplayGain(chunk,ret,&(dc->audioFormat), |                                 doReplayGain(chunk,ret,&(dc->audioFormat), | ||||||
|                                                 replayGainScale); |                                                 replayGainScale); | ||||||
| 				sendDataToOutputBuffer(cb,dc,chunk,chunkpos, | 				sendDataToOutputBuffer(cb, inStream, dc, chunk, | ||||||
| 					ov_time_tell(&vf),bitRate); | 					chunkpos, ov_time_tell(&vf), bitRate); | ||||||
| 				if(dc->stop) break; | 				if(dc->stop) break; | ||||||
| 				chunkpos = 0; | 				chunkpos = 0; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(!dc->stop && chunkpos > 0) { | 		if(!dc->stop && chunkpos > 0) { | ||||||
| 			sendDataToOutputBuffer(cb,dc,chunk,chunkpos, | 			sendDataToOutputBuffer(cb, NULL, dc, chunk, chunkpos, | ||||||
| 					ov_time_tell(&vf),bitRate); | 					ov_time_tell(&vf), bitRate); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ov_clear(&vf); | 		ov_clear(&vf); | ||||||
|   | |||||||
| @@ -43,8 +43,9 @@ void flushOutputBuffer(OutputBuffer * cb) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc,  | int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,   | ||||||
|                 char * dataIn, long dataInLen, float time, mpd_uint16 bitRate) |                 DecoderControl * dc, char * dataIn, long dataInLen, float time, | ||||||
|  |                 mpd_uint16 bitRate) | ||||||
| { | { | ||||||
|         mpd_uint16 dataToSend; |         mpd_uint16 dataToSend; | ||||||
| 	mpd_uint16 chunkLeft; | 	mpd_uint16 chunkLeft; | ||||||
| @@ -75,7 +76,11 @@ int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, | |||||||
| 		if(currentChunk != cb->end) { | 		if(currentChunk != cb->end) { | ||||||
| 	        	while(cb->begin==cb->end && cb->wrap && !dc->stop) | 	        	while(cb->begin==cb->end && cb->wrap && !dc->stop) | ||||||
| 			{ | 			{ | ||||||
| 		        	my_usleep(10000); |                                 if(!inStream ||  | ||||||
|  |                                         bufferInputStream(inStream) <= 0) | ||||||
|  |                                 { | ||||||
|  | 		        	        my_usleep(10000); | ||||||
|  |                                 } | ||||||
| 			} | 			} | ||||||
| 	        	if(dc->stop) return OUTPUT_BUFFER_DC_STOP; | 	        	if(dc->stop) return OUTPUT_BUFFER_DC_STOP; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
| #include "mpd_types.h" | #include "mpd_types.h" | ||||||
| #include "decode.h" | #include "decode.h" | ||||||
| #include "audio.h" | #include "audio.h" | ||||||
|  | #include "inputStream.h" | ||||||
|  |  | ||||||
| #define OUTPUT_BUFFER_DC_STOP   -1 | #define OUTPUT_BUFFER_DC_STOP   -1 | ||||||
| #define OUTPUT_BUFFER_DC_SEEK   -2 | #define OUTPUT_BUFFER_DC_SEEK   -2 | ||||||
| @@ -42,8 +43,11 @@ void clearOutputBuffer(OutputBuffer * cb); | |||||||
|  |  | ||||||
| void flushOutputBuffer(OutputBuffer * cb); | void flushOutputBuffer(OutputBuffer * cb); | ||||||
|  |  | ||||||
| int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc,  | /* we send inStream where for buffering the inputStream while waiting to | ||||||
|                char * data, long datalen, float time, mpd_uint16 bitRate); |    send the next chunk */ | ||||||
|  | int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream, | ||||||
|  |                 DecoderControl * dc, char * data, long datalen, float time, | ||||||
|  |                 mpd_uint16 bitRate); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
| /* vim:set shiftwidth=4 tabstop=8 expandtab: */ | /* vim:set shiftwidth=4 tabstop=8 expandtab: */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Warren Dukes
					Warren Dukes