diff options
author | Thibaut Mattern <tmattern@users.sourceforge.net> | 2004-06-05 14:11:24 +0000 |
---|---|---|
committer | Thibaut Mattern <tmattern@users.sourceforge.net> | 2004-06-05 14:11:24 +0000 |
commit | f18c75175a3ae2f63682fc2c782d4a8a578b5309 (patch) | |
tree | d825e592b9764b4a9d4a16dafb173f855b367026 | |
parent | 444f5b8ee7754e72224f49e6cd023bd2925a90cb (diff) | |
download | xine-lib-f18c75175a3ae2f63682fc2c782d4a8a578b5309.tar.gz xine-lib-f18c75175a3ae2f63682fc2c782d4a8a578b5309.tar.bz2 |
Support big decoder init data chunk (> 8192 bytes).
All demuxers and decoders have to be modified the same way...
Fix playback of this stream (with win32 dll):
http://naboo.homelinux.org/~daniel/media/p_length.avi
CVS patchset: 6640
CVS date: 2004/06/05 14:11:24
-rw-r--r-- | src/demuxers/demux_avi.c | 57 | ||||
-rw-r--r-- | src/libw32dll/w32codec.c | 49 |
2 files changed, 60 insertions, 46 deletions
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index eadb042e1..600eb8cb8 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_avi.c,v 1.203 2004/05/29 22:31:49 tmmm Exp $ + * $Id: demux_avi.c,v 1.204 2004/06/05 14:11:24 tmattern Exp $ * * demultiplexer for avi streams * @@ -993,12 +993,14 @@ static avi_t *AVI_init(demux_avi_t *this) { } } else if(lasttag == 2) { + xine_waveformatex *wavex; + + wavex = (xine_waveformatex *)malloc(n); + memcpy((void *)wavex, hdrl_data+i, n); + _x_waveformatex_le2me( wavex ); - AVI->audio[AVI->n_audio-1]->wavex=(xine_waveformatex *)malloc(n); - AVI->audio[AVI->n_audio-1]->wavex_len=n; - - memcpy((void *)AVI->audio[AVI->n_audio-1]->wavex, hdrl_data+i, n); - _x_waveformatex_le2me( AVI->audio[AVI->n_audio-1]->wavex ); + AVI->audio[AVI->n_audio-1]->wavex = wavex; + AVI->audio[AVI->n_audio-1]->wavex_len = n; lprintf("audio stream format\n"); auds_strf_seen = 1; } @@ -1924,7 +1926,7 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { if (this->avi->bih->biSize > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_avi: private decoder data length (%d) is greater than fifo buffer length (%d)\n", + "demux_avi: private video decoder data length (%d) is greater than fifo buffer length (%d)\n", this->avi->bih->biSize, buf->max_size); buf->free_buffer(buf); this->status = DEMUX_FINISHED; @@ -1980,26 +1982,31 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { if (this->audio_fifo) { for (i=0; i<this->avi->n_audio; i++) { avi_audio_t *a = this->avi->audio[i]; + uint32_t todo = a->wavex_len; + uint32_t done = 0; - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - if (a->wavex_len > buf->max_size) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_avi: private decoder data length (%d) is greater than fifo buffer length (%d)\n", - a->wavex_len, buf->max_size); - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - return; + while (todo) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + if (todo > buf->max_size) { + buf->size = buf->max_size; + } else { + buf->size = todo; + } + todo -= buf->size; + + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER; + if (todo == 0) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + + memcpy (buf->content, a->wavex + done, buf->size); + buf->type = a->audio_type | i; + buf->decoder_info[0] = 0; /* first package, containing wavex */ + buf->decoder_info[1] = a->wavex->nSamplesPerSec; /* Audio Rate */ + buf->decoder_info[2] = a->wavex->wBitsPerSample; /* Audio bits */ + buf->decoder_info[3] = a->wavex->nChannels; /* Audio channels */ + this->audio_fifo->put (this->audio_fifo, buf); + done += buf->size; } - - buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; - memcpy (buf->content, a->wavex, a->wavex_len); - buf->size = a->wavex_len; - buf->type = a->audio_type | i; - buf->decoder_info[0] = 0; /* first package, containing wavex */ - buf->decoder_info[1] = a->wavex->nSamplesPerSec; /* Audio Rate */ - buf->decoder_info[2] = a->wavex->wBitsPerSample; /* Audio bits */ - buf->decoder_info[3] = a->wavex->nChannels; /* Audio channels */ - this->audio_fifo->put (this->audio_fifo, buf); } if(this->avi->n_audio == 1) diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c index 9dfecaeea..d84d45df0 100644 --- a/src/libw32dll/w32codec.c +++ b/src/libw32dll/w32codec.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: w32codec.c,v 1.141 2004/05/04 21:49:00 jstembridge Exp $ + * $Id: w32codec.c,v 1.142 2004/06/05 14:11:24 tmattern Exp $ * * routines for using w32 codecs * DirectShow support by Miguel Freitas (Nov/2001) @@ -1152,18 +1152,18 @@ static void w32a_discontinuity (audio_decoder_t *this_gen) { this->pts = this->lastpts = this->sumpts = this->sumsize = 0; } -static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { +static int w32a_init_audio (w32a_decoder_t *this, + uint8_t *buf, int bufsize, int buftype) { HRESULT ret; - static WAVEFORMATEX wf; - static WAVEFORMATEX *in_fmt; + WAVEFORMATEX wf; + WAVEFORMATEX *in_fmt; unsigned long in_size; unsigned long out_size; audio_buffer_t *audio_buffer; int audio_buffer_mem_size; - in_fmt = (WAVEFORMATEX *) malloc (buf->size); - memcpy (in_fmt, buf->content, buf->size); + in_fmt = (WAVEFORMATEX *)buf; in_size=in_fmt->nBlockAlign; this->srcstream = 0; @@ -1179,7 +1179,6 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { if (!this->output_open) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: (ACM_Decoder) Cannot open audio output device\n"); - free(in_fmt); return 0; } @@ -1198,7 +1197,7 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { wf.cbSize = 0; this->ldt_fs = Setup_LDT_Keeper(); - win32_codec_name = get_auds_codec_name (this, buf->type); + win32_codec_name = get_auds_codec_name (this, buftype); if( this->driver_type == DRIVER_STD ) { @@ -1216,7 +1215,6 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: (ACM_Decoder) acmStreamOpen error %d\n"), (int) ret); this->srcstream = 0; - free(in_fmt); return 0; } @@ -1236,7 +1234,6 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { if( this->ds_dec == NULL ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: Error initializing DirectShow Audio\n")); this->srcstream = 0; - free(in_fmt); return 0; } @@ -1255,7 +1252,6 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { if( this->dmo_dec == NULL ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: Error initializing DMO Audio\n")); this->srcstream = 0; - free(in_fmt); return 0; } @@ -1294,8 +1290,6 @@ static int w32a_init_audio (w32a_decoder_t *this, buf_element_t *buf ) { this->size = 0; this->pts = this->lastpts = this->sumpts = this->sumsize = 0; - free(in_fmt); - return 1; } @@ -1466,16 +1460,29 @@ static void w32a_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (buf->decoder_flags & BUF_FLAG_STDHEADER) { lprintf ("got audio header\n"); - - pthread_mutex_lock(&win32_codec_mutex); - this->decoder_ok = w32a_init_audio (this, buf); - if( !this->decoder_ok ) { - xine_log (this->stream->xine, XINE_LOG_MSG, - _("w32codec: decoder failed to start. Is '%s' installed?\n"), win32_codec_name ); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + /* accumulate init data */ + if( this->size + buf->size > this->max_audio_src_size ) { + this->max_audio_src_size = this->size + 2 * buf->size; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "w32codec: increasing source buffer to %d to avoid overflow.\n", + this->max_audio_src_size); + this->buf = realloc( this->buf, this->max_audio_src_size ); + } + memcpy(this->buf + this->size, buf->content, buf->size); + this->size += buf->size; + + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + pthread_mutex_lock(&win32_codec_mutex); + this->decoder_ok = w32a_init_audio (this, this->buf, this->size, buf->type); + + if( !this->decoder_ok ) { + xine_log (this->stream->xine, XINE_LOG_MSG, + _("w32codec: decoder failed to start. Is '%s' installed?\n"), win32_codec_name ); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); + } + pthread_mutex_unlock(&win32_codec_mutex); } - pthread_mutex_unlock(&win32_codec_mutex); } else if (this->decoder_ok) { lprintf ("decoding %d data bytes...\n", buf->size); |