diff options
| author | Siarhei Siamashka <siarhei.siamashka@nokia.com> | 2009-01-16 17:23:54 +0200 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2009-01-18 16:14:46 +0100 | 
| commit | e010fc175e9bedbd5d099f7e32068ad8a051cbec (patch) | |
| tree | 19b1ca11a8acbfa37704712f1fbbec9f99cacccd /sbc/sbcenc.c | |
| parent | d48c175f70eaf37d6aaecf05f6a22833dc53798c (diff) | |
Performance optimizations for sbcenc utility
Read and write buffers sizes increased, memmove overhead eliminated.
Nonportable cast from 'unsigned char *' to 'struct au_header *' is
now also resolved as part of the changes.
Diffstat (limited to 'sbc/sbcenc.c')
| -rw-r--r-- | sbc/sbcenc.c | 122 | 
1 files changed, 50 insertions, 72 deletions
| diff --git a/sbc/sbcenc.c b/sbc/sbcenc.c index 9cbfb871..388be2a4 100644 --- a/sbc/sbcenc.c +++ b/sbc/sbcenc.c @@ -40,45 +40,15 @@  static int verbose = 0; -static ssize_t __read(int fd, void *buf, size_t count) -{ -	ssize_t len, pos = 0; - -	while (count > 0) { -		len = read(fd, buf + pos, count); -		if (len <= 0) -			return pos > len ? pos : len; - -		count -= len; -		pos   += len; -	} - -	return pos; -} - -static ssize_t __write(int fd, const void *buf, size_t count) -{ -	ssize_t len, pos = 0; - -	while (count > 0) { -		len = write(fd, buf + pos, count); -		if (len <= 0) -			return len; - -		count -= len; -		pos   += len; -	} - -	return pos; -} +#define BUF_SIZE 32768 +static unsigned char input[BUF_SIZE], output[BUF_SIZE + BUF_SIZE / 4];  static void encode(char *filename, int subbands, int bitpool, int joint,  					int dualchannel, int snr, int blocks)  { -	struct au_header *au_hdr; -	unsigned char input[2048], output[2048]; +	struct au_header au_hdr;  	sbc_t sbc; -	int fd, len, size, count, encoded, srate; +	int fd, len, size, count, encoded, srate, codesize, nframes;  	if (strcmp(filename, "-")) {  		fd = open(filename, O_RDONLY); @@ -90,8 +60,8 @@ static void encode(char *filename, int subbands, int bitpool, int joint,  	} else  		fd = fileno(stdin); -	len = __read(fd, input, sizeof(input)); -	if (len < sizeof(*au_hdr)) { +	len = read(fd, &au_hdr, sizeof(au_hdr)); +	if (len < sizeof(au_hdr)) {  		if (fd > fileno(stderr))  			fprintf(stderr, "Can't read header from file %s: %s\n",  						filename, strerror(errno)); @@ -100,19 +70,17 @@ static void encode(char *filename, int subbands, int bitpool, int joint,  		goto done;  	} -	au_hdr = (struct au_header *) input; - -	if (au_hdr->magic != AU_MAGIC || -			BE_INT(au_hdr->hdr_size) > 128 || -			BE_INT(au_hdr->hdr_size) < 24 || -			BE_INT(au_hdr->encoding) != AU_FMT_LIN16) { +	if (au_hdr.magic != AU_MAGIC || +			BE_INT(au_hdr.hdr_size) > 128 || +			BE_INT(au_hdr.hdr_size) < 24 || +			BE_INT(au_hdr.encoding) != AU_FMT_LIN16) {  		fprintf(stderr, "Not in Sun/NeXT audio S16_BE format\n");  		goto done;  	}  	sbc_init(&sbc, 0L); -	switch (BE_INT(au_hdr->sample_rate)) { +	switch (BE_INT(au_hdr.sample_rate)) {  	case 16000:  		sbc.frequency = SBC_FREQ_16000;  		break; @@ -127,11 +95,11 @@ static void encode(char *filename, int subbands, int bitpool, int joint,  		break;  	} -	srate = BE_INT(au_hdr->sample_rate); +	srate = BE_INT(au_hdr.sample_rate);  	sbc.subbands = subbands == 4 ? SBC_SB_4 : SBC_SB_8; -	if (BE_INT(au_hdr->channels) == 1) { +	if (BE_INT(au_hdr.channels) == 1) {  		sbc.mode = SBC_MODE_MONO;  		if (joint || dualchannel) {  			fprintf(stderr, "Audio is mono but joint or " @@ -151,9 +119,9 @@ static void encode(char *filename, int subbands, int bitpool, int joint,  	}  	sbc.endian = SBC_BE; -	count = BE_INT(au_hdr->data_size); -	size = len - BE_INT(au_hdr->hdr_size); -	memmove(input, input + BE_INT(au_hdr->hdr_size), size); +	count = BE_INT(au_hdr.data_size); +	size = len - BE_INT(au_hdr.hdr_size); +	memmove(input, input + BE_INT(au_hdr.hdr_size), size);  	sbc.bitpool = bitpool;  	sbc.allocation = snr ? SBC_AM_SNR : SBC_AM_LOUDNESS; @@ -172,37 +140,47 @@ static void encode(char *filename, int subbands, int bitpool, int joint,  						"STEREO" : "JOINTSTEREO");  	} +	codesize = sbc_get_codesize(&sbc); +	nframes = sizeof(input) / codesize;  	while (1) { -		if (size < sizeof(input)) { -			len = __read(fd, input + size, sizeof(input) - size); -			if (len == 0 && size == 0) -				break; - -			if (len < 0) { -				perror("Can't read audio data"); +		unsigned char *inp, *outp; +		/* read data for up to 'nframes' frames of input data */ +		size = read(fd, input, codesize * nframes); +		if (size < 0) { +			/* Something really bad happened */ +			perror("Can't read audio data"); +			break; +		} +		if (size < codesize) { +			/* Not enough data for encoding even a single frame */ +			break; +		} +		/* encode all the data from the input buffer in a loop */ +		inp = input; +		outp = output; +		while (size >= codesize) { +			len = sbc_encode(&sbc, inp, codesize, +				outp, sizeof(output) - (outp - output), +				&encoded); +			if (len != codesize || encoded <= 0) { +				fprintf(stderr, +					"sbc_encode fail, len=%d, encoded=%d\n", +					len, encoded);  				break;  			} - -			size += len; +			size -= len; +			inp += len; +			outp += encoded;  		} - -		len = sbc_encode(&sbc, input, size, -					output, sizeof(output), &encoded); -		if (len <= 0) -			break; -		if (len < size) -			memmove(input, input + len, size - len); - -		size -= len; - -		len = __write(fileno(stdout), output, encoded); -		if (len == 0) -			break; - -		if (len < 0 || len != encoded) { +		len = write(fileno(stdout), output, outp - output); +		if (len != outp - output) {  			perror("Can't write SBC output");  			break;  		} +		if (size >= codesize) { +			/* sbc_encode failure has been detected earlier */ +			break; +		}  	}  	sbc_finish(&sbc); | 
