[Asterisk-code-review] format pcm: Track actual header size of .au files (asterisk[13])

Sean Bright asteriskteam at digium.com
Fri Apr 14 14:43:20 CDT 2017


Sean Bright has uploaded a new change for review. ( https://gerrit.asterisk.org/5481 )

Change subject: format_pcm: Track actual header size of .au files
......................................................................

format_pcm: Track actual header size of .au files

Sun's Au file format has a minimum data offset 24 bytes, but this
offset is encoded in each .au file. Instead of assuming the minimum,
read the actual value and store it for later use.

ASTERISK-20984 #close
Reported by: Roman S.
Patches:
	asterisk-1.8.20.0-au-clicks-2.diff (license #6474) patch
	uploaded by Roman S.

Change-Id: I524022fb19ff2fd5af2cc2d669d27a780ab2057c
---
M formats/format_pcm.c
1 file changed, 40 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/81/5481/1

diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 481299a..05a7eab 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -233,7 +233,7 @@
 
 /* SUN .au support routines */
 
-#define AU_HEADER_SIZE		24
+#define MIN_AU_HEADER_SIZE	24
 #define AU_HEADER(var)		uint32_t var[6]
 
 #define AU_HDR_MAGIC_OFF	0
@@ -268,7 +268,11 @@
 #endif
 #endif
 
-static int check_header(FILE *f)
+struct au_desc {
+	uint32_t hdr_size;
+};
+
+static int check_header(struct ast_filestream *fs)
 {
 	AU_HEADER(header);
 	uint32_t magic;
@@ -278,7 +282,10 @@
 	uint32_t sample_rate;
 	uint32_t channels;
 
-	if (fread(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
+	struct au_desc *desc = fs->_private;
+	FILE *f = fs->f;
+
+	if (fread(header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
 		ast_log(LOG_WARNING, "Read failed (header)\n");
 		return -1;
 	}
@@ -287,8 +294,8 @@
 		ast_log(LOG_WARNING, "Bad magic: 0x%x\n", magic);
 	}
 	hdr_size = ltohl(header[AU_HDR_HDR_SIZE_OFF]);
-	if (hdr_size < AU_HEADER_SIZE) {
-		hdr_size = AU_HEADER_SIZE;
+	if (hdr_size < MIN_AU_HEADER_SIZE) {
+		hdr_size = MIN_AU_HEADER_SIZE;
 	}
 /*	data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */
 	encoding = ltohl(header[AU_HDR_ENCODING_OFF]);
@@ -313,20 +320,26 @@
 		ast_log(LOG_WARNING, "Failed to skip to data: %u\n", hdr_size);
 		return -1;
 	}
+
+	/* We'll need this later */
+	desc->hdr_size = hdr_size;
+
 	return data_size;
 }
 
-static int update_header(FILE *f)
+static int update_header(struct ast_filestream *fs)
 {
 	off_t cur, end;
 	uint32_t datalen;
 	int bytes;
+	struct au_desc *desc = fs->_private;
+	FILE *f = fs->f;
 
 	cur = ftell(f);
 	fseek(f, 0, SEEK_END);
 	end = ftell(f);
 	/* data starts 24 bytes in */
-	bytes = end - AU_HEADER_SIZE;
+	bytes = end - desc->hdr_size;
 	datalen = htoll(bytes);
 
 	if (cur < 0) {
@@ -348,12 +361,15 @@
 	return 0;
 }
 
-static int write_header(FILE *f)
+static int write_header(struct ast_filestream *fs)
 {
+	struct au_desc *desc = fs->_private;
+	FILE *f = fs->f;
+
 	AU_HEADER(header);
 
 	header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC);
-	header[AU_HDR_HDR_SIZE_OFF] = htoll(AU_HEADER_SIZE);
+	header[AU_HDR_HDR_SIZE_OFF] = htoll(desc->hdr_size);
 	header[AU_HDR_DATA_SIZE_OFF] = 0;
 	header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW);
 	header[AU_HDR_SAMPLE_RATE_OFF] = htoll(DEFAULT_SAMPLE_RATE);
@@ -361,7 +377,7 @@
 
 	/* Write an au header, ignoring sizes which will be filled in later */
 	fseek(f, 0, SEEK_SET);
-	if (fwrite(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
+	if (fwrite(header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
@@ -370,14 +386,18 @@
 
 static int au_open(struct ast_filestream *s)
 {
-	if (check_header(s->f) < 0)
+	if (check_header(s) < 0)
 		return -1;
 	return 0;
 }
 
 static int au_rewrite(struct ast_filestream *s, const char *comment)
 {
-	if (write_header(s->f))
+	struct au_desc *desc = s->_private;
+
+	desc->hdr_size = MIN_AU_HEADER_SIZE;
+
+	if (write_header(s))
 		return -1;
 	return 0;
 }
@@ -385,8 +405,11 @@
 /* XXX check this, probably incorrect */
 static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
 {
-	off_t min = AU_HEADER_SIZE, max, cur;
+	off_t min, max, cur;
 	long offset = 0, bytes;
+	struct au_desc *desc = fs->_private;
+
+	min = desc->hdr_size;
 
 	if (ast_format_cmp(fs->fmt->format, ast_format_g722) == AST_FORMAT_CMP_EQUAL)
 		bytes = sample_offset / 2;
@@ -442,13 +465,14 @@
 	if (ftruncate(fd, cur)) {
 		return -1;
 	}
-	return update_header(fs->f);
+	return update_header(fs);
 }
 
 static off_t au_tell(struct ast_filestream *fs)
 {
+	struct au_desc *desc = fs->_private;
 	off_t offset = ftello(fs->f);
-	return offset - AU_HEADER_SIZE;
+	return offset - desc->hdr_size;
 }
 
 static struct ast_format_def alaw_f = {
@@ -500,6 +524,7 @@
 	.tell = au_tell,
 	.read = pcm_read,
 	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,	/* this many shorts */
+	.desc_size = sizeof(struct au_desc),
 };
 
 static int unload_module(void)

-- 
To view, visit https://gerrit.asterisk.org/5481
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I524022fb19ff2fd5af2cc2d669d27a780ab2057c
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Sean Bright <sean.bright at gmail.com>



More information about the asterisk-code-review mailing list