diff options
Diffstat (limited to 'src/demuxers/demux_avi.c')
-rw-r--r-- | src/demuxers/demux_avi.c | 292 |
1 files changed, 146 insertions, 146 deletions
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index b4ccec6ae..a277ebb2f 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.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: demux_avi.c,v 1.113 2002/10/12 17:14:41 jkeil Exp $ + * $Id: demux_avi.c,v 1.114 2002/10/14 15:47:13 guenter Exp $ * * demultiplexer for avi streams * @@ -71,8 +71,6 @@ #define MAX_AUDIO_STREAMS 8 -#define VALID_ENDS "avi" - /* The following variable indicates the kind of error */ typedef struct @@ -168,9 +166,7 @@ typedef struct typedef struct demux_avi_s { demux_plugin_t demux_plugin; - xine_t *xine; - - config_values_t *config; + xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; @@ -198,6 +194,16 @@ typedef struct demux_avi_s { idx_grow_t idx_grow; } demux_avi_t ; +typedef struct { + + demux_class_t demux_class; + + /* class-wide, global variables here */ + + xine_t *xine; + config_values_t *config; +} demux_avi_class_t; + #define AVI_ERR_SIZELIM 1 /* The write of the data would exceed the maximum size of the AVI file. This is more a warning than an error @@ -393,16 +399,16 @@ static void demux_avi_stop (demux_plugin_t *this_gen); * notify the user. Returns -1 if EOF was reached, the non-negative * return value of stopper otherwise. */ static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *), - void *stopdata) -{ + void *stopdata) { + unsigned long n; - long i; - long retval = -1; - long num_read = 0; - off_t ioff = 8; - char data[256]; - int did_osd = 0; - off_t savepos = this->input->seek(this->input, 0, SEEK_CUR); + long i; + long retval = -1; + long num_read = 0; + off_t ioff = 8; + char data[256]; + off_t savepos = this->input->seek(this->input, 0, SEEK_CUR); + this->input->seek(this->input, this->idx_grow.nexttagoffset, SEEK_SET); while ((retval = stopper(this, stopdata)) < 0) { @@ -410,22 +416,24 @@ static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *), num_read += 1; if (num_read % 1000 == 0) { - /* Update the user using the OSD */ - off_t file_len = this->input->get_length (this->input); - char str[60]; - - sprintf(str, "Building index (%3lld%%)", - 100 * this->idx_grow.nexttagoffset / file_len); - - this->xine->osd_renderer->filled_rect (this->xine->osd, - 0, 0, 299, 99, 0); - this->xine->osd_renderer->render_text (this->xine->osd, - 5, 30, str, OSD_TEXT1); - this->xine->osd_renderer->show (this->xine->osd, 0); - did_osd = 1; + /* send event to frontend about index generation progress */ + + xine_event_t event; + xine_idx_progress_data_t idx; + off_t file_len; + + file_len = this->input->get_length (this->input); + + idx.percent = 100 * this->idx_grow.nexttagoffset / file_len; + + event.type = XINE_EVENT_BUILDING_INDEX; + event.data = &idx; + event.data_length = sizeof (xine_idx_progress_data_t); + + xine_event_send (this->stream, &event); } - if( this->input->read(this->input, data,8) != 8 ) + if (this->input->read(this->input, data,8) != 8) break; n = str2ulong(data+4); @@ -466,12 +474,7 @@ static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *), } - /* Clear the OSD */ - if (did_osd) { - this->xine->osd_renderer->hide (this->xine->osd, 0); - } - - this->input->seek(this->input, savepos, SEEK_SET); + this->input->seek (this->input, savepos, SEEK_SET); if (retval < 0) retval = -1; return retval; @@ -649,7 +652,8 @@ static avi_t *AVI_init(demux_avi_t *this) { ERR_EXIT(AVI_ERR_NO_MEM); if (this->input->read(this->input, (char *)AVI->idx, n) != n ) { - xine_log (this->xine, XINE_LOG_MSG, _("demux_avi: avi index is broken\n")); + xine_log (this->stream->xine, XINE_LOG_MSG, + _("demux_avi: avi index is broken\n")); free (AVI->idx); /* Index is broken, reconstruct */ AVI->idx = NULL; AVI->n_idx = AVI->max_idx = 0; @@ -1162,13 +1166,13 @@ static void *demux_avi_loop (void *this_gen) { } while( this->status == DEMUX_OK ); if (this->send_end_buffers) { - xine_demux_control_end(this->xine, BUF_FLAG_END_STREAM); + xine_demux_control_end (this->stream, BUF_FLAG_END_STREAM); } printf ("demux_avi: demux loop finished.\n"); this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); + pthread_mutex_unlock (&this->mutex); pthread_exit(NULL); @@ -1180,27 +1184,27 @@ static void demux_avi_stop (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; void *p; - pthread_mutex_lock( &this->mutex ); + pthread_mutex_lock (&this->mutex); if (!this->thread_running) { printf ("demux_avi: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); + pthread_mutex_unlock (&this->mutex); return; } this->send_end_buffers = 0; this->status = DEMUX_FINISHED; - pthread_mutex_unlock( &this->mutex ); + pthread_mutex_unlock (&this->mutex); pthread_join (this->thread, &p); - xine_demux_flush_engine(this->xine); + xine_demux_flush_engine (this->stream); /* AVI_close (this->avi); this->avi = NULL; */ - xine_demux_control_end(this->xine, BUF_FLAG_END_USER); + xine_demux_control_end (this->stream, BUF_FLAG_END_USER); } static void demux_avi_dispose (demux_plugin_t *this_gen) { @@ -1218,19 +1222,20 @@ static int demux_avi_get_status (demux_plugin_t *this_gen) { return (this->thread_running?DEMUX_OK:DEMUX_FINISHED); } -static int demux_avi_send_headers (demux_avi_t *this) { +static void demux_avi_send_headers (demux_plugin_t *this_gen) { + demux_avi_t *this = (demux_avi_t *) this_gen; int i; pthread_mutex_lock (&this->mutex); - this->video_fifo = this->xine->video_fifo; - this->audio_fifo = this->xine->audio_fifo; + this->video_fifo = this->stream->video_fifo; + this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; - this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->avi->width; - this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->avi->height; + this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->avi->width; + this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->avi->height; for (i=0; i < this->avi->n_audio; i++) printf ("demux_avi: audio format[%d] = 0x%x\n", @@ -1243,7 +1248,6 @@ static int demux_avi_send_headers (demux_avi_t *this) { if( !this->avi->audio[i]->audio_type ) { printf ("demux_avi: unknown audio type 0x%x\n", this->avi->audio[i]->wavex->wFormatTag); - xine_report_codec( this->xine, XINE_CODEC_AUDIO, this->avi->audio[i]->wavex->wFormatTag, 0, 0); this->no_audio = 1; this->avi->audio[i]->audio_type = BUF_CONTROL_NOP; } else @@ -1252,11 +1256,12 @@ static int demux_avi_send_headers (demux_avi_t *this) { (int)this->avi->audio[i]->wavex->wFormatTag); } - xine_demux_control_headers_done (this->xine); + this->stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO] = 1; + this->stream->stream_info[XINE_STREAM_INFO_HAS_AUDIO] = !this->no_audio; - pthread_mutex_unlock (&this->mutex); + xine_demux_control_headers_done (this->stream); - return DEMUX_CAN_HANDLE; + pthread_mutex_unlock (&this->mutex); } static int demux_avi_start (demux_plugin_t *this_gen, @@ -1380,15 +1385,13 @@ static int demux_avi_start (demux_plugin_t *this_gen, * send start buffers */ if( !this->thread_running && (this->status == DEMUX_OK) ) { - xine_demux_control_start(this->xine); + xine_demux_control_start (this->stream); } else { - xine_demux_flush_engine(this->xine); + xine_demux_flush_engine (this->stream); } if( this->status == DEMUX_OK ) - { - xine_demux_control_newpts(this->xine, video_pts, BUF_FLAG_SEEK); - } + xine_demux_control_newpts (this->stream, video_pts, BUF_FLAG_SEEK); if( !this->thread_running && (this->status == DEMUX_OK) ) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); @@ -1407,8 +1410,6 @@ static int demux_avi_start (demux_plugin_t *this_gen, (char*)&this->avi->bih.biCompression); buf->free_buffer (buf); - xine_report_codec( this->xine, XINE_CODEC_VIDEO, this->avi->bih.biCompression, 0, 0); - this->status = DEMUX_FINISHED; } else { buf->type = this->avi->video_type; @@ -1496,143 +1497,142 @@ static int demux_avi_seek (demux_plugin_t *this_gen, return demux_avi_start (this_gen, start_pos, start_time); } -static int demux_avi_open(demux_plugin_t *this_gen, - input_plugin_t *input, int stage) { +static int demux_avi_get_stream_length (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; - if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) { - printf("demux_avi.c: not seekable, can't handle!\n"); - return DEMUX_CANNOT_HANDLE; + + if (this->avi) { + return get_video_pts(this, this->avi->video_idx.video_frames) / 90000 ; } - switch(stage) { + return 0; +} - case STAGE_BY_CONTENT: { - if (input->get_blocksize(input)) - return DEMUX_CANNOT_HANDLE; +static void* open_plugin (void *class_gen, xine_stream_t *stream, + const void *input_gen) { + + input_plugin_t *input = (input_plugin_t *) input_gen; + demux_avi_t *this; - if (!(input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) - return DEMUX_CANNOT_HANDLE; + if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) { + printf("demux_avi.c: not seekable, can't handle!\n"); + return NULL; + } - input->seek(input, 0, SEEK_SET); + this = xine_xmalloc (sizeof (demux_avi_t)); + this->stream = stream; + this->input = input; - this->input = input; + this->demux_plugin.send_headers = demux_avi_send_headers; + this->demux_plugin.start = demux_avi_start; + this->demux_plugin.seek = demux_avi_seek; + this->demux_plugin.stop = demux_avi_stop; + this->demux_plugin.dispose = demux_avi_dispose; + this->demux_plugin.get_status = demux_avi_get_status; + this->demux_plugin.get_stream_length = demux_avi_get_stream_length; - if (this->avi) - AVI_close (this->avi); + this->status = DEMUX_FINISHED; + pthread_mutex_init (&this->mutex, NULL); - this->avi = AVI_init (this); + switch (stream->content_detection_method) { + + case XINE_DEMUX_CONTENT_STRATEGY: - if (this->avi) { + if (input->get_capabilities(input) & INPUT_CAP_BLOCK) { + printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n", + this->AVI_errno); + free (this); + return NULL; + } - printf ("demux_avi: %ld frames\n", this->avi->video_idx.video_frames); + input->seek(input, 0, SEEK_SET); - strncpy(this->last_mrl, input->get_mrl (input), 1024); + this->avi = AVI_init (this); - return demux_avi_send_headers (this); + if (!this->avi) { + free (this); + return NULL; } - /* printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n", this->AVI_errno); */ - - return DEMUX_CANNOT_HANDLE; - } break; - case STAGE_BY_EXTENSION: { + case XINE_DEMUX_EXTENSION_STRATEGY: { char *ending, *mrl; - char *m, *valid_ends; mrl = input->get_mrl (input); ending = strrchr(mrl, '.'); - if(ending) { - xine_strdupa(valid_ends, - this->config->register_string(this->config, - "mrl.ends_avi", VALID_ENDS, - _("valid mrls ending for avi demuxer"), - NULL, 20, NULL, NULL)); - while((m = xine_strsep(&valid_ends, ",")) != NULL) { - - while(*m == ' ' || *m == '\t') m++; - - if(!strcasecmp((ending + 1), m)) { - - this->input = input; + if (!ending) { + free (this); + return NULL; + } - if (this->avi) - AVI_close (this->avi); + if (strncasecmp (ending, ".AVI", 4)) { + free (this); + return NULL; + } - this->avi = AVI_init (this); + this->avi = AVI_init (this); - if (this->avi) { - strncpy(this->last_mrl, input->get_mrl (input), 1024); - return demux_avi_send_headers (this); - } else { - printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n", - this->AVI_errno); - return DEMUX_CANNOT_HANDLE; - } - } - } + if (!this->avi) { + printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n", + this->AVI_errno); + free (this); + return NULL; } - return DEMUX_CANNOT_HANDLE; } break; default: - return DEMUX_CANNOT_HANDLE; - break; + free (this); + return NULL; } - return DEMUX_CANNOT_HANDLE; + strncpy (this->last_mrl, input->get_mrl (input), 1024); + + printf ("demux_avi: %ld frames\n", this->avi->video_idx.video_frames); + + return this; +} + +static char *get_description (demux_class_t *this_gen) { + return "AVI/RIFF demux plugin"; } -static char *demux_avi_get_id(void) { +static char *get_identifier (demux_class_t *this_gen) { return "AVI"; } -static char *demux_avi_get_mimetypes(void) { +static char *get_extensions (demux_class_t *this_gen) { + return "avi"; +} + +static char *get_mimetypes (demux_class_t *this_gen) { return "video/msvideo: avi: AVI animation;" "video/x-msvideo: avi: AVI animation;"; } -static int demux_avi_get_stream_length (demux_plugin_t *this_gen) { - - demux_avi_t *this = (demux_avi_t *) this_gen; +static void class_dispose (demux_class_t *this_gen) { - if (this->avi) { - return get_video_pts(this, this->avi->video_idx.video_frames) / 90000 ; - } + demux_avi_class_t *this = (demux_avi_class_t *) this_gen; - return 0; + free (this); } -static void *init_demuxer_plugin(xine_t *xine, void *data) { +static void *init_plugin (xine_t *xine, void *data) { - demux_avi_t *this; + demux_avi_class_t *this; - this = xine_xmalloc (sizeof (demux_avi_t)); + this = xine_xmalloc (sizeof (demux_avi_class_t)); this->config = xine->config; this->xine = xine; - (void*) this->config->register_string(this->config, - "mrl.ends_avi", VALID_ENDS, - _("valid mrls ending for avi demuxer"), - NULL, 20, NULL, NULL); - - this->demux_plugin.open = demux_avi_open; - this->demux_plugin.start = demux_avi_start; - this->demux_plugin.seek = demux_avi_seek; - this->demux_plugin.stop = demux_avi_stop; - this->demux_plugin.dispose = demux_avi_dispose; - this->demux_plugin.get_status = demux_avi_get_status; - this->demux_plugin.get_identifier = demux_avi_get_id; - this->demux_plugin.get_stream_length = demux_avi_get_stream_length; - this->demux_plugin.get_mimetypes = demux_avi_get_mimetypes; - - this->status = DEMUX_FINISHED; - pthread_mutex_init( &this->mutex, NULL ); + this->demux_class.get_description = get_description; + this->demux_class.get_identifier = get_identifier; + this->demux_class.get_mimetypes = get_mimetypes; + this->demux_class.get_extensions = get_extensions; + this->demux_class.dispose = class_dispose; return this; } @@ -1643,6 +1643,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 11, "avi", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } + { PLUGIN_DEMUX, 12, "avi", XINE_VERSION_CODE, NULL, init_plugin, open_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL, NULL } }; |