summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Melanson <mike@multimedia.cx>2002-10-23 03:21:19 +0000
committerMike Melanson <mike@multimedia.cx>2002-10-23 03:21:19 +0000
commitdb7b8514d28d78565ee6299510eea12dd873214d (patch)
tree60f584a73a539c3db280fcdf0c819047bc4ea5a8
parent3fd3d7d33515f867316010fe4fbe63bd57d1f7d3 (diff)
downloadxine-lib-db7b8514d28d78565ee6299510eea12dd873214d.tar.gz
xine-lib-db7b8514d28d78565ee6299510eea12dd873214d.tar.bz2
bring the FLI subsystem in line with the latest API revision
CVS patchset: 2950 CVS date: 2002/10/23 03:21:19
-rw-r--r--src/demuxers/demux_fli.c372
-rw-r--r--src/libxinevdec/fli.c106
2 files changed, 260 insertions, 218 deletions
diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c
index 53f85d545..68ad37d61 100644
--- a/src/demuxers/demux_fli.c
+++ b/src/demuxers/demux_fli.c
@@ -22,7 +22,7 @@
* avoid while programming a FLI decoder, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: demux_fli.c,v 1.16 2002/10/12 17:11:58 jkeil Exp $
+ * $Id: demux_fli.c,v 1.17 2002/10/23 03:21:19 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -55,7 +55,7 @@ typedef struct {
demux_plugin_t demux_plugin;
- xine_t *xine;
+ xine_stream_t *stream;
config_values_t *config;
@@ -81,8 +81,66 @@ typedef struct {
unsigned int speed;
unsigned int frame_pts_inc;
unsigned int frame_count;
+
+ char last_mrl[1024];
} demux_fli_t;
+typedef struct {
+
+ demux_class_t demux_class;
+
+ /* class-wide, global variables here */
+
+ xine_t *xine;
+ config_values_t *config;
+} demux_fli_class_t;
+
+/* returns 1 if the CIN file was opened successfully, 0 otherwise */
+static int open_fli_file(demux_fli_t *this) {
+
+ /* read the whole header */
+ this->input->seek(this->input, 0, SEEK_SET);
+ if (this->input->read(this->input, this->fli_header, FLI_HEADER_SIZE) !=
+ FLI_HEADER_SIZE)
+ return 0;
+
+ /* validate the file */
+ this->magic_number = LE_16(&this->fli_header[4]);
+ if ((this->magic_number != FLI_FILE_MAGIC_1) &&
+ (this->magic_number != FLI_FILE_MAGIC_2))
+ return 0;
+
+ this->frame_count = LE_16(&this->fli_header[6]);
+ this->width = LE_16(&this->fli_header[8]);
+ this->height = LE_16(&this->fli_header[10]);
+ this->speed = LE_32(&this->fli_header[16]);
+ if (this->magic_number == 0xAF11) {
+ /*
+ * in this case, the speed (n) is number of 1/70s ticks between frames:
+ *
+ * xine pts n * frame #
+ * -------- = ----------- => xine pts = n * (90000/70) * frame #
+ * 90000 70
+ *
+ * therefore, the frame pts increment = n * 1285.7
+ */
+ this->frame_pts_inc = this->speed * 1285.7;
+ } else {
+ /*
+ * in this case, the speed (n) is number of milliseconds between frames:
+ *
+ * xine pts n * frame #
+ * -------- = ----------- => xine pts = n * 90 * frame #
+ * 90000 1000
+ *
+ * therefore, the frame pts increment = n * 90
+ */
+ this->frame_pts_inc = this->speed * 90;
+ }
+
+ return 1;
+}
+
static void *demux_fli_loop (void *this_gen) {
demux_fli_t *this = (demux_fli_t *) this_gen;
@@ -175,7 +233,7 @@ static void *demux_fli_loop (void *this_gen) {
this->status = DEMUX_FINISHED;
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);
}
this->thread_running = 0;
@@ -184,132 +242,45 @@ static void *demux_fli_loop (void *this_gen) {
return NULL;
}
-static int load_fli_and_send_headers(demux_fli_t *this) {
+static void demux_fli_send_headers(demux_plugin_t *this_gen) {
+
+ demux_fli_t *this = (demux_fli_t *) this_gen;
+ buf_element_t *buf;
pthread_mutex_lock(&this->mutex);
- this->video_fifo = this->xine->video_fifo;
+ this->video_fifo = this->stream->video_fifo;
/* video-only format, don't worry about audio_fifo */
this->status = DEMUX_OK;
- /* read the whole header */
- this->input->seek(this->input, 0, SEEK_SET);
- if (this->input->read(this->input, this->fli_header, FLI_HEADER_SIZE) !=
- FLI_HEADER_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock (&this->mutex);
- return DEMUX_CANNOT_HANDLE;
- }
-
- this->magic_number = LE_16(&this->fli_header[4]);
- this->frame_count = LE_16(&this->fli_header[6]);
- this->width = LE_16(&this->fli_header[8]);
- this->height = LE_16(&this->fli_header[10]);
- this->speed = LE_32(&this->fli_header[16]);
- if (this->magic_number == 0xAF11) {
- /*
- * in this case, the speed (n) is number of 1/70s ticks between frames:
- *
- * xine pts n * frame #
- * -------- = ----------- => xine pts = n * (90000/70) * frame #
- * 90000 70
- *
- * therefore, the frame pts increment = n * 1285.7
- */
- this->frame_pts_inc = this->speed * 1285.7;
- } else {
- /*
- * in this case, the speed (n) is number of milliseconds between frames:
- *
- * xine pts n * frame #
- * -------- = ----------- => xine pts = n * 90 * frame #
- * 90000 1000
- *
- * therefore, the frame pts increment = n * 90
- */
- this->frame_pts_inc = this->speed * 90;
- }
-
/* load stream information */
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
-
- xine_demux_control_headers_done (this->xine);
-
- pthread_mutex_unlock (&this->mutex);
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
- return DEMUX_CAN_HANDLE;
-}
-
-static int demux_fli_open(demux_plugin_t *this_gen, input_plugin_t *input,
- int stage) {
-
- demux_fli_t *this = (demux_fli_t *) this_gen;
- char sig[2];
- unsigned int magic_number;
-
- this->input = input;
-
- switch(stage) {
- case STAGE_BY_CONTENT: {
- if ((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) == 0)
- return DEMUX_CANNOT_HANDLE;
-
- input->seek(input, 4, SEEK_SET);
- if (input->read(input, sig, 2) != 2) {
- return DEMUX_CANNOT_HANDLE;
- }
- magic_number = LE_16(&sig[0]);
- if ((magic_number == FLI_FILE_MAGIC_1) ||
- (magic_number == FLI_FILE_MAGIC_2))
- return load_fli_and_send_headers(this);
-
- return DEMUX_CANNOT_HANDLE;
- }
- break;
-
- case STAGE_BY_EXTENSION: {
- char *suffix;
- char *MRL;
- char *m, *valid_ends;
-
- MRL = input->get_mrl (input);
-
- suffix = strrchr(MRL, '.');
-
- if(!suffix)
- return DEMUX_CANNOT_HANDLE;
-
- xine_strdupa(valid_ends, (this->config->register_string(this->config,
- "mrl.ends_fli", VALID_ENDS,
- "valid mrls ending for fli demuxer",
- NULL, 20, NULL, NULL)));
- while((m = xine_strsep(&valid_ends, ",")) != NULL) {
-
- while(*m == ' ' || *m == '\t') m++;
-
- if(!strcasecmp((suffix + 1), m))
- return load_fli_and_send_headers(this);
- }
- return DEMUX_CANNOT_HANDLE;
- }
- break;
+ /* send start buffers */
+ xine_demux_control_start(this->stream);
- default:
- return DEMUX_CANNOT_HANDLE;
- break;
+ /* send init info to FLI decoder */
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = this->frame_pts_inc; /* initial video_step */
+ /* be a rebel and send the FLI header instead of the bih */
+ memcpy(buf->content, this->fli_header, FLI_HEADER_SIZE);
+ buf->size = FLI_HEADER_SIZE;
+ buf->type = BUF_VIDEO_FLI;
+ this->video_fifo->put (this->video_fifo, buf);
- }
+ xine_demux_control_headers_done (this->stream);
- return DEMUX_CANNOT_HANDLE;
+ pthread_mutex_unlock (&this->mutex);
}
static int demux_fli_start (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
demux_fli_t *this = (demux_fli_t *) this_gen;
- buf_element_t *buf;
int err;
pthread_mutex_lock(&this->mutex);
@@ -317,35 +288,8 @@ static int demux_fli_start (demux_plugin_t *this_gen,
/* if thread is not running, initialize demuxer */
if (!this->thread_running) {
- /* print vital stats */
- xine_log (this->xine, XINE_LOG_MSG,
- _("demux_fli: FLI type: %04X, speed: %d/%d\n"),
- this->magic_number, this->speed,
- (this->magic_number == FLI_FILE_MAGIC_1) ? 70 : 1000);
- xine_log (this->xine, XINE_LOG_MSG,
- _("demux_fli: %d frames, %dx%d\n"),
- this->frame_count, this->width, this->height);
- xine_log (this->xine, XINE_LOG_MSG,
- _("demux_fli: running time: %d min, %d sec\n"),
- this->frame_count * this->frame_pts_inc / 90000 / 60,
- this->frame_count * this->frame_pts_inc / 90000 % 60);
-
- /* send start buffers */
- xine_demux_control_start(this->xine);
-
/* send new pts */
- xine_demux_control_newpts(this->xine, 0, 0);
-
- /* send init info to FLI decoder */
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[0] = 0;
- buf->decoder_info[1] = this->frame_pts_inc; /* initial video_step */
- /* be a rebel and send the FLI header instead of the bih */
- memcpy(buf->content, this->fli_header, FLI_HEADER_SIZE);
- buf->size = FLI_HEADER_SIZE;
- buf->type = BUF_VIDEO_FLI;
- this->video_fifo->put (this->video_fifo, buf);
+ xine_demux_control_newpts(this->stream, 0, 0);
this->status = DEMUX_OK;
this->send_end_buffers = 1;
@@ -365,11 +309,10 @@ static int demux_fli_start (demux_plugin_t *this_gen,
static int demux_fli_seek (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
- demux_fli_t *this = (demux_fli_t *) this_gen;
- /* FLI files are not meant to be seekable */
+ /* FLI files are not meant to be seekable; don't even bother */
- return this->status;
+ return 0;
}
static void demux_fli_stop (demux_plugin_t *this_gen) {
@@ -384,15 +327,18 @@ static void demux_fli_stop (demux_plugin_t *this_gen) {
return;
}
+ /* seek to the start of the data in case there's another start command */
+ this->input->seek(this->input, FLI_HEADER_SIZE, SEEK_SET);
+
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- xine_demux_flush_engine(this->xine);
+ xine_demux_flush_engine(this->stream);
- xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
+ xine_demux_control_end(this->stream, BUF_FLAG_END_USER);
}
static void demux_fli_dispose (demux_plugin_t *this) {
@@ -402,11 +348,7 @@ static void demux_fli_dispose (demux_plugin_t *this) {
static int demux_fli_get_status (demux_plugin_t *this_gen) {
demux_fli_t *this = (demux_fli_t *) this_gen;
- return this->status;
-}
-
-static char *demux_fli_get_id(void) {
- return "FLI";
+ return (this->thread_running?DEMUX_OK:DEMUX_FINISHED);
}
static int demux_fli_get_stream_length (demux_plugin_t *this_gen) {
@@ -414,41 +356,141 @@ static int demux_fli_get_stream_length (demux_plugin_t *this_gen) {
return 0;
}
-static char *demux_fli_get_mimetypes(void) {
- return NULL;
-}
+static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
+ input_plugin_t *input_gen) {
-static void *init_demuxer_plugin(xine_t *xine, void *data) {
- demux_fli_t *this;
+ input_plugin_t *input = (input_plugin_t *) input_gen;
+ demux_fli_t *this;
- this = (demux_fli_t *) xine_xmalloc(sizeof(demux_fli_t));
- this->config = xine->config;
- this->xine = xine;
+ if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) {
+ printf(_("demux_fli.c: input not seekable, can not handle!\n"));
+ return NULL;
+ }
- (void *) this->config->register_string(this->config,
- "mrl.ends_fli", VALID_ENDS,
- "valid mrls ending for fli demuxer",
- NULL, 10, NULL, NULL);
+ this = xine_xmalloc (sizeof (demux_fli_t));
+ this->stream = stream;
+ this->input = input;
- this->demux_plugin.open = demux_fli_open;
+ this->demux_plugin.send_headers = demux_fli_send_headers;
this->demux_plugin.start = demux_fli_start;
this->demux_plugin.seek = demux_fli_seek;
this->demux_plugin.stop = demux_fli_stop;
this->demux_plugin.dispose = demux_fli_dispose;
this->demux_plugin.get_status = demux_fli_get_status;
- this->demux_plugin.get_identifier = demux_fli_get_id;
this->demux_plugin.get_stream_length = demux_fli_get_stream_length;
- this->demux_plugin.get_mimetypes = demux_fli_get_mimetypes;
+ this->demux_plugin.demux_class = class_gen;
+
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init (&this->mutex, NULL);
+
+ switch (stream->content_detection_method) {
+
+ case METHOD_BY_CONTENT:
+
+ if (!open_fli_file(this)) {
+ free (this);
+ return NULL;
+ }
+
+ break;
+
+ case METHOD_BY_EXTENSION: {
+ char *ending, *mrl;
+
+ mrl = input->get_mrl (input);
+
+ ending = strrchr(mrl, '.');
+
+ if (!ending) {
+ free (this);
+ return NULL;
+ }
+
+ if (strncasecmp (ending, ".fli", 4) &&
+ strncasecmp (ending, ".flc", 4)) {
+ free (this);
+ return NULL;
+ }
+
+ if (!open_fli_file(this)) {
+ free (this);
+ return NULL;
+ }
+
+ }
+
+ break;
+
+ default:
+ free (this);
+ return NULL;
+ }
+
+ strncpy (this->last_mrl, input->get_mrl (input), 1024);
+
+ /* print vital stats */
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_fli: FLI type: %04X, speed: %d/%d\n"),
+ this->magic_number, this->speed,
+ (this->magic_number == FLI_FILE_MAGIC_1) ? 70 : 1000);
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_fli: %d frames, %dx%d\n"),
+ this->frame_count, this->width, this->height);
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_fli: running time: %d min, %d sec\n"),
+ this->frame_count * this->frame_pts_inc / 90000 / 60,
+ this->frame_count * this->frame_pts_inc / 90000 % 60);
return &this->demux_plugin;
}
+static char *get_description (demux_class_t *this_gen) {
+ return "Autodesk Animator FLI/FLC demux plugin";
+}
+
+static char *get_identifier (demux_class_t *this_gen) {
+ return "FLI/FLC";
+}
+
+static char *get_extensions (demux_class_t *this_gen) {
+ return "fli,flc";
+}
+
+static char *get_mimetypes (demux_class_t *this_gen) {
+ return NULL;
+}
+
+static void class_dispose (demux_class_t *this_gen) {
+
+ demux_fli_class_t *this = (demux_fli_class_t *) this_gen;
+
+ free (this);
+}
+
+static void *init_plugin (xine_t *xine, void *data) {
+
+ demux_fli_class_t *this;
+
+ this = xine_xmalloc (sizeof (demux_fli_class_t));
+ this->config = xine->config;
+ this->xine = xine;
+
+ this->demux_class.open_plugin = open_plugin;
+ 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;
+}
+
/*
* exported plugin catalog entry
*/
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 11, "fli", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 14, "fli", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/libxinevdec/fli.c b/src/libxinevdec/fli.c
index 9cf7a9142..47cb8028d 100644
--- a/src/libxinevdec/fli.c
+++ b/src/libxinevdec/fli.c
@@ -23,7 +23,7 @@
* avoid when implementing a FLI decoder, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: fli.c,v 1.7 2002/10/06 03:48:13 komadori Exp $
+ * $Id: fli.c,v 1.8 2002/10/23 03:21:20 tmmm Exp $
*/
#include <stdio.h>
@@ -55,11 +55,17 @@
* fli specific decode functions
*************************************************************************/
+typedef struct {
+ video_decoder_class_t decoder_class;
+} fli_class_t;
+
typedef struct fli_decoder_s {
video_decoder_t video_decoder; /* parent video decoder structure */
+ fli_class_t *class;
+ xine_stream_t *stream;
+
/* these are traditional variables in a video decoder object */
- vo_instance_t *video_out; /* object that will receive frames */
uint64_t video_step; /* frame duration in pts units */
int decoder_ok; /* current decoder status */
int skipframes;
@@ -401,22 +407,6 @@ void decode_fli_frame(fli_decoder_t *this) {
*************************************************************************/
/*
- * This function is responsible is called to initialize the video decoder
- * for use. Initialization usually involves setting up the fields in your
- * private video decoder object.
- */
-static void fli_init (video_decoder_t *this_gen,
- vo_instance_t *video_out) {
- fli_decoder_t *this = (fli_decoder_t *) this_gen;
-
- /* set our own video_out object to the one that xine gives us */
- this->video_out = video_out;
-
- /* indicate that the decoder is not quite ready yet */
- this->decoder_ok = 0;
-}
-
-/*
* This function receives a buffer of data from the demuxer layer and
* figures out how to handle it based on its header flags.
*/
@@ -431,7 +421,7 @@ static void fli_decode_data (video_decoder_t *this_gen,
return;
if (buf->decoder_flags & BUF_FLAG_HEADER) { /* need to initialize */
- this->video_out->open (this->video_out);
+ this->stream->video_out->open (this->stream->video_out);
if(this->buf)
free(this->buf);
@@ -449,7 +439,7 @@ static void fli_decode_data (video_decoder_t *this_gen,
this->buf = malloc(this->bufsize);
this->size = 0;
- this->video_out->open (this->video_out);
+ this->stream->video_out->open (this->stream->video_out);
this->decoder_ok = 1;
return;
@@ -469,7 +459,7 @@ static void fli_decode_data (video_decoder_t *this_gen,
if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
- img = this->video_out->get_frame (this->video_out,
+ img = this->stream->video_out->get_frame (this->stream->video_out,
this->width, this->height,
XINE_VO_ASPECT_DONT_TOUCH, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS);
@@ -517,11 +507,10 @@ static void fli_reset (video_decoder_t *this_gen) {
}
/*
- * This function is called when xine shuts down the decoder. It should
- * free any memory and release any other resources allocated during the
- * execution of the decoder.
+ * This function frees the video decoder instance allocated to the decoder.
*/
-static void fli_close (video_decoder_t *this_gen) {
+static void fli_dispose (video_decoder_t *this_gen) {
+
fli_decoder_t *this = (fli_decoder_t *) this_gen;
if (this->buf) {
@@ -534,44 +523,55 @@ static void fli_close (video_decoder_t *this_gen) {
if (this->decoder_ok) {
this->decoder_ok = 0;
- this->video_out->close(this->video_out);
+ this->stream->video_out->close(this->stream->video_out);
}
-}
-
-/*
- * This function returns the human-readable ID string to identify
- * this decoder.
- */
-static char *fli_get_id(void) {
- return "FLI Video";
-}
-/*
- * This function frees the video decoder instance allocated to the decoder.
- */
-static void fli_dispose (video_decoder_t *this_gen) {
free (this_gen);
}
-/*
- * This function should be the plugin's only advertised function to the
- * outside world. It allows xine to query the plugin module for the addresses
- * to the necessary functions in the video decoder object.
- */
-static void *init_video_decoder_plugin (xine_t *xine, void *data) {
+static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) {
- fli_decoder_t *this ;
+ fli_decoder_t *this ;
- this = (fli_decoder_t *) malloc (sizeof (fli_decoder_t));
- memset(this, 0, sizeof (fli_decoder_t));
+ this = (fli_decoder_t *) xine_xmalloc (sizeof (fli_decoder_t));
- this->video_decoder.init = fli_init;
this->video_decoder.decode_data = fli_decode_data;
this->video_decoder.flush = fli_flush;
this->video_decoder.reset = fli_reset;
- this->video_decoder.close = fli_close;
- this->video_decoder.get_identifier = fli_get_id;
this->video_decoder.dispose = fli_dispose;
+ this->size = 0;
+
+ this->stream = stream;
+ this->class = (fli_class_t *) class_gen;
+
+ this->decoder_ok = 0;
+ this->buf = NULL;
+
+ return &this->video_decoder;
+}
+
+static char *get_identifier (video_decoder_class_t *this) {
+ return "FLI Video";
+}
+
+static char *get_description (video_decoder_class_t *this) {
+ return "Autodesk Animator FLI/FLC video decoder plugin";
+}
+
+static void dispose_class (video_decoder_class_t *this) {
+ free (this);
+}
+
+static void *init_plugin (xine_t *xine, void *data) {
+
+ fli_class_t *this;
+
+ this = (fli_class_t *) xine_xmalloc (sizeof (fli_class_t));
+
+ this->decoder_class.open_plugin = open_plugin;
+ this->decoder_class.get_identifier = get_identifier;
+ this->decoder_class.get_description = get_description;
+ this->decoder_class.dispose = dispose_class;
return this;
}
@@ -587,12 +587,12 @@ static uint32_t video_types[] = {
static decoder_info_t dec_info_video = {
video_types, /* supported types */
- 1 /* priority */
+ 5 /* priority */
};
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_DECODER, 10, "fli", XINE_VERSION_CODE, &dec_info_video, init_video_decoder_plugin },
+ { PLUGIN_VIDEO_DECODER, 11, "fli", XINE_VERSION_CODE, &dec_info_video, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};