diff options
author | Liong Sauw Ming <ming@teluu.com> | 2011-01-19 10:23:58 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2011-01-19 10:23:58 +0000 |
commit | 3975c5d02c5214a6ebb8828c9a94b366a807e1bd (patch) | |
tree | 6d504270e2a48f3d7b13ee26be479b8bef00ed6f /pjmedia | |
parent | a22edb7e705e27853307a483f60e16cf2a07ff9d (diff) |
Fixes #597: Error reading WAV files when there are extra chunks after DATA chunk.
Wav player will now just play data chunks in wav files and ignore others.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3405 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r-- | pjmedia/src/pjmedia/wav_player.c | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/pjmedia/src/pjmedia/wav_player.c b/pjmedia/src/pjmedia/wav_player.c index e0279b28..95da4f55 100644 --- a/pjmedia/src/pjmedia/wav_player.c +++ b/pjmedia/src/pjmedia/wav_player.c @@ -67,6 +67,8 @@ struct file_reader_port pj_off_t fsize; unsigned start_data; + unsigned data_len; + unsigned data_left; pj_off_t fpos; pj_oshandle_t fd; @@ -105,7 +107,9 @@ static struct file_reader_port *create_file_port(pj_pool_t *pool) */ static pj_status_t fill_buffer(struct file_reader_port *fport) { - pj_ssize_t size_left = fport->bufsize; + pj_size_t data_left = fport->data_left; + pj_ssize_t bufsize = (fport->bufsize > data_left) ? data_left : fport->bufsize; + pj_ssize_t size_left = bufsize; unsigned size_to_read; pj_ssize_t size; pj_status_t status; @@ -117,7 +121,8 @@ static pj_status_t fill_buffer(struct file_reader_port *fport) /* Calculate how many bytes to read in this run. */ size = size_to_read = size_left; status = pj_file_read(fport->fd, - &fport->buf[fport->bufsize-size_left], + //&fport->buf[fport->bufsize-size_left], + &fport->buf[bufsize-size_left], &size); if (status != PJ_SUCCESS) return status; @@ -127,23 +132,37 @@ static pj_status_t fill_buffer(struct file_reader_port *fport) } size_left -= size; + fport->data_left -= size; fport->fpos += size; /* If size is less than size_to_read, it indicates that we've * encountered EOF. Rewind the file. */ - if (size < (pj_ssize_t)size_to_read) { - fport->eof = PJ_TRUE; - fport->eofpos = fport->buf + fport->bufsize - size_left; - - if (fport->options & PJMEDIA_FILE_NO_LOOP) { - /* Zero remaining buffer */ - pj_bzero(fport->eofpos, size_left); - } + if (size < (pj_ssize_t)size_to_read || fport->data_left <= 0) { + fport->eof = PJ_TRUE; + //fport->eofpos = fport->buf + fport->bufsize - size_left; + fport->eofpos = fport->buf + bufsize - size_left; + + if (fport->options & PJMEDIA_FILE_NO_LOOP) { + /* Zero remaining buffer */ + if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) { + pj_bzero(fport->eofpos, size_left + + (fport->bufsize - data_left)); + } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) { + int val = pjmedia_linear2ulaw(0); + pj_memset(fport->eofpos, val, size_left + + (fport->bufsize - data_left)); + } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW) { + int val = pjmedia_linear2alaw(0); + pj_memset(fport->eofpos, val, size_left + + (fport->bufsize - data_left)); + } + } /* Rewind file */ fport->fpos = fport->start_data; pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET); + fport->data_left = fport->data_len; } } @@ -312,12 +331,16 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool, /* Current file position now points to start of data */ status = pj_file_getpos(fport->fd, &pos); fport->start_data = (unsigned)pos; + fport->data_len = wave_hdr.data_hdr.len; + fport->data_left = wave_hdr.data_hdr.len; - /* Validate length. */ + /* Validate length. This is unnecessary since we only play data chunks. */ + /* if (wave_hdr.data_hdr.len != fport->fsize - fport->start_data) { pj_file_close(fport->fd); return PJMEDIA_EWAVEUNSUPP; } + */ if (wave_hdr.data_hdr.len < ptime * wave_hdr.fmt_hdr.sample_rate * wave_hdr.fmt_hdr.nchan / 1000) { @@ -591,7 +614,19 @@ static pj_status_t file_get_frame(pjmedia_port *this_port, /* End Of Buffer and EOF and NO LOOP */ if (fport->eof && (fport->options & PJMEDIA_FILE_NO_LOOP)) { fport->readpos += endread; - pj_bzero((char*)frame->buf + endread, frame_size - endread); + + if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) { + pj_bzero((char*)frame->buf + endread, frame_size - endread); + } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) { + int val = pjmedia_linear2ulaw(0); + pj_memset((char*)frame->buf + endread, val, + frame_size - endread); + } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW) { + int val = pjmedia_linear2alaw(0); + pj_memset((char*)frame->buf + endread, val, + frame_size - endread); + } + return PJ_SUCCESS; } |