summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibaut Mattern <tmattern@users.sourceforge.net>2004-06-05 14:11:24 +0000
committerThibaut Mattern <tmattern@users.sourceforge.net>2004-06-05 14:11:24 +0000
commitf18c75175a3ae2f63682fc2c782d4a8a578b5309 (patch)
treed825e592b9764b4a9d4a16dafb173f855b367026
parent444f5b8ee7754e72224f49e6cd023bd2925a90cb (diff)
downloadxine-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.c57
-rw-r--r--src/libw32dll/w32codec.c49
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);