summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Melanson <mike@multimedia.cx>2002-10-23 02:55:01 +0000
committerMike Melanson <mike@multimedia.cx>2002-10-23 02:55:01 +0000
commit3fd3d7d33515f867316010fe4fbe63bd57d1f7d3 (patch)
treeb0e1958bd806edb68d889a42201a3ebe397d87f4
parent6a57fa96f65018f48bed7d086d34af54e85a1960 (diff)
downloadxine-lib-3fd3d7d33515f867316010fe4fbe63bd57d1f7d3.tar.gz
xine-lib-3fd3d7d33515f867316010fe4fbe63bd57d1f7d3.tar.bz2
bring the RoQ subsystem in line with the latest API revision
CVS patchset: 2949 CVS date: 2002/10/23 02:55:01
-rw-r--r--src/demuxers/demux_roq.c492
-rw-r--r--src/libxineadec/roqaudio.c114
-rw-r--r--src/libxinevdec/roqvideo.c103
3 files changed, 396 insertions, 313 deletions
diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c
index ca32985df..0103d3aab 100644
--- a/src/demuxers/demux_roq.c
+++ b/src/demuxers/demux_roq.c
@@ -21,7 +21,7 @@
* For more information regarding the RoQ file format, visit:
* http://www.csse.monash.edu.au/~timf/
*
- * $Id: demux_roq.c,v 1.20 2002/10/12 17:11:59 jkeil Exp $
+ * $Id: demux_roq.c,v 1.21 2002/10/23 02:55:01 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -52,13 +52,11 @@
#define RoQ_SOUND_MONO 0x1020
#define RoQ_SOUND_STEREO 0x1021
-#define VALID_ENDS "roq"
-
typedef struct {
demux_plugin_t demux_plugin;
- xine_t *xine;
+ xine_stream_t *stream;
config_values_t *config;
@@ -81,8 +79,105 @@ typedef struct {
unsigned int width;
unsigned int height;
unsigned int audio_channels;
+
+ char last_mrl[1024];
} demux_roq_t ;
+typedef struct {
+
+ demux_class_t demux_class;
+
+ /* class-wide, global variables here */
+
+ xine_t *xine;
+ config_values_t *config;
+} demux_roq_class_t;
+
+/* returns 1 if the RoQ file was opened successfully, 0 otherwise */
+static int open_roq_file(demux_roq_t *this) {
+
+ char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
+ int i;
+ unsigned int chunk_type;
+ unsigned int chunk_size;
+
+ this->status = DEMUX_OK;
+
+ this->input->seek(this->input, 0, SEEK_SET);
+ if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
+ RoQ_CHUNK_PREAMBLE_SIZE)
+ return 0;
+
+ this->width = this->height = 0;
+ this->audio_channels = 0; /* assume no audio at first */
+
+ /*
+ * RoQ files enjoy a constant framerate; pts calculation:
+ *
+ * xine pts frame #
+ * -------- = ------- => xine pts = 90000 * frame # / fps
+ * 90000 fps
+ *
+ * therefore, the frame pts increment is 90000 / fps
+ */
+ this->fps = LE_16(&preamble[6]);
+ this->frame_pts_inc = 90000 / this->fps;
+
+ /* iterate through the first 2 seconds worth of chunks searching for
+ * the RoQ_INFO chunk and an audio chunk */
+ i = this->fps * 2;
+ while (i-- > 0) {
+ /* if this read fails, then maybe it's just a really small RoQ file
+ * (even less than 2 seconds) */
+ if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
+ RoQ_CHUNK_PREAMBLE_SIZE)
+ break;
+ chunk_type = LE_16(&preamble[0]);
+ chunk_size = LE_32(&preamble[2]);
+
+ if (chunk_type == RoQ_INFO) {
+ /* fetch the width and height; reuse the preamble bytes */
+ if (this->input->read(this->input, preamble, 8) != 8)
+ break;
+
+ this->width = LE_16(&preamble[0]);
+ this->height = LE_16(&preamble[2]);
+
+ /* if an audio chunk was already found, search is done */
+ if (this->audio_channels)
+ break;
+
+ /* prep the size for a seek */
+ chunk_size -= 8;
+ } else {
+ /* if it was an audio chunk and the info chunk has already been
+ * found (as indicated by width and height) then break */
+ if (chunk_type == RoQ_SOUND_MONO) {
+ this->audio_channels = 1;
+ if (this->width && this->height)
+ break;
+ } else if (chunk_type == RoQ_SOUND_STEREO) {
+ this->audio_channels = 2;
+ if (this->width && this->height)
+ break;
+ }
+ }
+
+ /* skip the rest of the chunk */
+ this->input->seek(this->input, chunk_size, SEEK_CUR);
+ }
+
+ /* after all is said and done, if there is a width and a height,
+ * regard it as being a valid file and reset to the first chunk */
+ if (this->width && this->height) {
+ this->input->seek(this->input, 8, SEEK_SET);
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+
static void *demux_roq_loop (void *this_gen) {
demux_roq_t *this = (demux_roq_t *) this_gen;
@@ -236,7 +331,7 @@ static void *demux_roq_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;
@@ -245,180 +340,65 @@ static void *demux_roq_loop (void *this_gen) {
return NULL;
}
-static int load_roq_and_send_headers(demux_roq_t *this) {
+static void demux_roq_send_headers(demux_plugin_t *this_gen) {
- char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
- int i;
- unsigned int chunk_type;
- unsigned int chunk_size;
+ demux_roq_t *this = (demux_roq_t *) this_gen;
+ buf_element_t *buf;
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->input->seek(this->input, 0, SEEK_SET);
- if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
- RoQ_CHUNK_PREAMBLE_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_CANNOT_HANDLE;
- }
-
- this->width = this->height = 0;
- this->audio_channels = 0; /* assume no audio at first */
-
- /*
- * RoQ files enjoy a constant framerate; pts calculation:
- *
- * xine pts frame #
- * -------- = ------- => xine pts = 90000 * frame # / fps
- * 90000 fps
- *
- * therefore, the frame pts increment is 90000 / fps
- */
- this->fps = LE_16(&preamble[6]);
- this->frame_pts_inc = 90000 / this->fps;
-
- /* iterate through the first 2 seconds worth of chunks searching for
- * the RoQ_INFO chunk and an audio chunk */
- i = this->fps * 2;
- while (i-- > 0) {
- /* if this read fails, then maybe it's just a really small RoQ file
- * (even less than 2 seconds) */
- if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
- RoQ_CHUNK_PREAMBLE_SIZE)
- break;
- chunk_type = LE_16(&preamble[0]);
- chunk_size = LE_32(&preamble[2]);
-
- if (chunk_type == RoQ_INFO) {
- /* fetch the width and height; reuse the preamble bytes */
- if (this->input->read(this->input, preamble, 8) != 8)
- break;
-
- this->width = LE_16(&preamble[0]);
- this->height = LE_16(&preamble[2]);
-
- /* if an audio chunk was already found, search is done */
- if (this->audio_channels)
- break;
-
- /* prep the size for a seek */
- chunk_size -= 8;
- } else {
- /* if it was an audio chunk and the info chunk has already been
- * found (as indicated by width and height) then break */
- if (chunk_type == RoQ_SOUND_MONO) {
- this->audio_channels = 1;
- if (this->width && this->height)
- break;
- } else if (chunk_type == RoQ_SOUND_STEREO) {
- this->audio_channels = 2;
- if (this->width && this->height)
- break;
- }
- }
-
- /* skip the rest of the chunk */
- this->input->seek(this->input, chunk_size, SEEK_CUR);
- }
-
- /* after all is said and done, if there is a width and a height,
- * regard it as being a valid file and reset to the first chunk */
- if (this->width && this->height) {
- this->input->seek(this->input, 8, SEEK_SET);
- } else {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_CANNOT_HANDLE;
- }
-
/* 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;
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] =
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] =
this->audio_channels;
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] =
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] =
RoQ_AUDIO_SAMPLE_RATE;
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = 16;
-
- xine_demux_control_headers_done (this->xine);
-
- pthread_mutex_unlock (&this->mutex);
-
- return DEMUX_CAN_HANDLE;
-}
-
-static int demux_roq_open(demux_plugin_t *this_gen, input_plugin_t *input,
- int stage) {
- demux_roq_t *this = (demux_roq_t *) this_gen;
- char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
-
- 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, 0, SEEK_SET);
- if (input->read(input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
- RoQ_CHUNK_PREAMBLE_SIZE)
- return DEMUX_CANNOT_HANDLE;
-
- /* check for the RoQ magic numbers */
- if ((LE_16(&preamble[0]) == RoQ_MAGIC_NUMBER) &&
- (LE_32(&preamble[2]) == 0xFFFFFFFF))
- return load_roq_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_roq", VALID_ENDS,
- _("valid mrls ending for roq demuxer"),
- NULL, 20, NULL, NULL)));
- while((m = xine_strsep(&valid_ends, ",")) != NULL) {
-
- while(*m == ' ' || *m == '\t') m++;
-
- if(!strcasecmp((suffix + 1), m))
- return load_roq_and_send_headers(this);
- }
- return DEMUX_CANNOT_HANDLE;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = 16;
+
+ /* send start buffers */
+ xine_demux_control_start(this->stream);
+
+ /* send init info to decoders */
+ 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 */
+ /* really be a rebel: No structure at all, just put the video width
+ * and height straight into the buffer, BE_16 format */
+ buf->content[0] = (this->width >> 8) & 0xFF;
+ buf->content[1] = (this->width >> 0) & 0xFF;
+ buf->content[2] = (this->height >> 8) & 0xFF;
+ buf->content[3] = (this->height >> 0) & 0xFF;
+ buf->size = 4;
+ buf->type = BUF_VIDEO_ROQ;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo && this->audio_channels) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_AUDIO_ROQ;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = RoQ_AUDIO_SAMPLE_RATE;
+ buf->decoder_info[2] = 16;
+ buf->decoder_info[3] = this->audio_channels;
+ this->audio_fifo->put (this->audio_fifo, buf);
}
- break;
- default:
- return DEMUX_CANNOT_HANDLE;
- break;
-
- }
+ xine_demux_control_headers_done (this->stream);
- return DEMUX_CANNOT_HANDLE;
+ pthread_mutex_unlock (&this->mutex);
}
static int demux_roq_start (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
demux_roq_t *this = (demux_roq_t *) this_gen;
- buf_element_t *buf;
int err;
pthread_mutex_lock(&this->mutex);
@@ -426,46 +406,8 @@ static int demux_roq_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_roq: RoQ file, video is %dx%d, %d frames/sec\n"),
- this->width, this->height, this->fps);
- if (this->audio_channels)
- xine_log (this->xine, XINE_LOG_MSG,
- _("demux_roq: 16-bit, 22050 Hz %s RoQ DPCM audio\n"),
- (this->audio_channels == 1) ? "monaural" : "stereo");
-
- /* send start buffers */
- xine_demux_control_start(this->xine);
-
/* send new pts */
- xine_demux_control_newpts(this->xine, 0, 0);
-
- /* send init info to decoders */
- 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 */
- /* really be a rebel: No structure at all, just put the video width
- * and height straight into the buffer, BE_16 format */
- buf->content[0] = (this->width >> 8) & 0xFF;
- buf->content[1] = (this->width >> 0) & 0xFF;
- buf->content[2] = (this->height >> 8) & 0xFF;
- buf->content[3] = (this->height >> 0) & 0xFF;
- buf->size = 4;
- buf->type = BUF_VIDEO_ROQ;
- this->video_fifo->put (this->video_fifo, buf);
-
- if (this->audio_fifo && this->audio_channels) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_AUDIO_ROQ;
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[0] = 0;
- buf->decoder_info[1] = RoQ_AUDIO_SAMPLE_RATE;
- buf->decoder_info[2] = 16;
- buf->decoder_info[3] = this->audio_channels;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ xine_demux_control_newpts(this->stream, 0, 0);
this->status = DEMUX_OK;
this->send_end_buffers = 1;
@@ -510,9 +452,9 @@ static void demux_roq_stop (demux_plugin_t *this_gen) {
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_roq_dispose (demux_plugin_t *this) {
@@ -522,11 +464,7 @@ static void demux_roq_dispose (demux_plugin_t *this) {
static int demux_roq_get_status (demux_plugin_t *this_gen) {
demux_roq_t *this = (demux_roq_t *) this_gen;
- return this->status;
-}
-
-static char *demux_roq_get_id(void) {
- return "RoQ";
+ return (this->thread_running?DEMUX_OK:DEMUX_FINISHED);
}
static int demux_roq_get_stream_length (demux_plugin_t *this_gen) {
@@ -534,45 +472,151 @@ static int demux_roq_get_stream_length (demux_plugin_t *this_gen) {
return 0;
}
-static char *demux_roq_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_roq_t *this;
+ input_plugin_t *input = (input_plugin_t *) input_gen;
+ demux_roq_t *this;
+ char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
- this = (demux_roq_t *) xine_xmalloc(sizeof(demux_roq_t));
- this->config = xine->config;
- this->xine = xine;
+ if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) {
+ printf(_("demux_roq.c: input not seekable, can not handle!\n"));
+ return NULL;
+ }
- (void *) this->config->register_string(this->config,
- "mrl.ends_roq", VALID_ENDS,
- _("valid mrls ending for roq demuxer"),
- NULL, 20, NULL, NULL);
+ this = xine_xmalloc (sizeof (demux_roq_t));
+ this->stream = stream;
+ this->input = input;
- this->demux_plugin.open = demux_roq_open;
+ this->demux_plugin.send_headers = demux_roq_send_headers;
this->demux_plugin.start = demux_roq_start;
this->demux_plugin.seek = demux_roq_seek;
this->demux_plugin.stop = demux_roq_stop;
this->demux_plugin.dispose = demux_roq_dispose;
this->demux_plugin.get_status = demux_roq_get_status;
- this->demux_plugin.get_identifier = demux_roq_get_id;
this->demux_plugin.get_stream_length = demux_roq_get_stream_length;
- this->demux_plugin.get_mimetypes = demux_roq_get_mimetypes;
+ this->demux_plugin.demux_class = class_gen;
this->status = DEMUX_FINISHED;
- pthread_mutex_init(&this->mutex, NULL);
+ pthread_mutex_init (&this->mutex, NULL);
+
+ switch (stream->content_detection_method) {
+
+ case METHOD_BY_CONTENT:
+
+ input->seek(input, 0, SEEK_SET);
+ if (input->read(input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
+ RoQ_CHUNK_PREAMBLE_SIZE) {
+ free (this);
+ return NULL;
+ }
+
+ /* check for the RoQ magic numbers */
+ if ((LE_16(&preamble[0]) == RoQ_MAGIC_NUMBER) &&
+ (LE_32(&preamble[2]) == 0xFFFFFFFF)) {
+ free (this);
+ return NULL;
+ }
+
+ if (!open_roq_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, ".roq", 4)) {
+ free (this);
+ return NULL;
+ }
+
+ if (!open_roq_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_roq: RoQ file, video is %dx%d, %d frames/sec\n"),
+ this->width, this->height, this->fps);
+ if (this->audio_channels)
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_roq: 16-bit, 22050 Hz %s RoQ DPCM audio\n"),
+ (this->audio_channels == 1) ? "monaural" : "stereo");
return &this->demux_plugin;
}
+static char *get_description (demux_class_t *this_gen) {
+ return "Id RoQ file demux plugin";
+}
+
+static char *get_identifier (demux_class_t *this_gen) {
+ return "RoQ";
+}
+
+static char *get_extensions (demux_class_t *this_gen) {
+ return "roq";
+}
+
+static char *get_mimetypes (demux_class_t *this_gen) {
+ return NULL;
+}
+
+static void class_dispose (demux_class_t *this_gen) {
+
+ demux_roq_class_t *this = (demux_roq_class_t *) this_gen;
+
+ free (this);
+}
+
+static void *init_plugin (xine_t *xine, void *data) {
+
+ demux_roq_class_t *this;
+
+ this = xine_xmalloc (sizeof (demux_roq_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, "roq", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 14, "roq", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/libxineadec/roqaudio.c b/src/libxineadec/roqaudio.c
index 56c48ed95..85c09b991 100644
--- a/src/libxineadec/roqaudio.c
+++ b/src/libxineadec/roqaudio.c
@@ -21,7 +21,7 @@
* For more information regarding the RoQ file format, visit:
* http://www.csse.monash.edu.au/~timf/
*
- * $Id: roqaudio.c,v 1.8 2002/10/06 03:48:13 komadori Exp $
+ * $Id: roqaudio.c,v 1.9 2002/10/23 02:55:01 tmmm Exp $
*
*/
@@ -47,12 +47,17 @@
else if (x > 32767) x = 32767;
#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
+typedef struct {
+ audio_decoder_class_t decoder_class;
+} roqaudio_class_t;
+
typedef struct roqaudio_decoder_s {
audio_decoder_t audio_decoder;
+ xine_stream_t *stream;
+
int64_t pts;
- ao_instance_t *audio_out;
int output_open;
int output_channels;
@@ -63,26 +68,6 @@ typedef struct roqaudio_decoder_s {
short square_array[256];
} roqaudio_decoder_t;
-static void roqaudio_reset (audio_decoder_t *this_gen) {
-}
-
-static void roqaudio_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
-
- roqaudio_decoder_t *this = (roqaudio_decoder_t *) this_gen;
- int i;
- short square;
-
- this->audio_out = audio_out;
- this->output_open = 0;
-
- /* initialize tables of squares */
- for (i = 0; i < 128; i++) {
- square = i * i;
- this->square_array[i] = square;
- this->square_array[i + 128] = -square;
- }
-}
-
static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
roqaudio_decoder_t *this = (roqaudio_decoder_t *) this_gen;
audio_buffer_t *audio_buffer;
@@ -101,7 +86,7 @@ static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
}
if (!this->output_open) {
- this->output_open = this->audio_out->open(this->audio_out,
+ this->output_open = this->stream->audio_out->open(this->stream->audio_out,
RoQ_AUDIO_BITS_PER_SAMPLE, RoQ_AUDIO_SAMPLE_RATE,
(this->output_channels == 2) ? AO_CAP_MODE_STEREO : AO_CAP_MODE_MONO);
}
@@ -110,9 +95,6 @@ static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
if (!this->output_open)
return;
-//printf ("received audio packet: %d bytes, pts = %lld, flags = %X\n",
-// buf->size, buf->pts, buf->decoder_flags);
-
if( this->size + buf->size > this->bufsize ) {
this->bufsize = this->size + 2 * buf->size;
printf("RoQ: increasing source buffer to %d to avoid overflow.\n",
@@ -124,11 +106,11 @@ static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->size += buf->size;
if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
- audio_buffer = this->audio_out->get_buffer (this->audio_out);
+ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
out = 0;
- // prepare the initial predictors
+ /* prepare the initial predictors */
if (this->output_channels == 1)
predictor[0] = LE_16(&this->buf[6]);
else
@@ -146,7 +128,7 @@ static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
CLAMP_S16(predictor[channel_number]);
audio_buffer->mem[out++] = predictor[channel_number];
- // toggle channel
+ /* toggle channel */
channel_number ^= this->output_channels - 1;
}
@@ -154,45 +136,79 @@ static void roqaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
audio_buffer->num_frames =
(buf->size - 8) / this->output_channels;
-//printf (" audio buffer size = %d, buf size = %d, chan = %d, # of frames sent = %d\n",
-// audio_buffer->mem_size, this->size,
-// this->output_channels, audio_buffer->num_frames);
- this->audio_out->put_buffer (this->audio_out, audio_buffer);
+ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer);
this->size = 0;
}
}
-static void roqaudio_close (audio_decoder_t *this_gen) {
+static void roqaudio_reset (audio_decoder_t *this_gen) {
+}
+
+static void roqaudio_dispose (audio_decoder_t *this_gen) {
+
roqaudio_decoder_t *this = (roqaudio_decoder_t *) this_gen;
if (this->output_open)
- this->audio_out->close (this->audio_out);
+ this->stream->audio_out->close (this->stream->audio_out);
this->output_open = 0;
-}
-
-static char *roqaudio_get_id(void) {
- return "RoQ Audio";
-}
-static void roqaudio_dispose (audio_decoder_t *this_gen) {
free (this_gen);
}
-static void *init_audio_decoder_plugin (xine_t *xine, void *data) {
+static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) {
- roqaudio_decoder_t *this ;
+ roqaudio_decoder_t *this;
+ int i;
+ short square;
- this = (roqaudio_decoder_t *) malloc (sizeof (roqaudio_decoder_t));
+ this = (roqaudio_decoder_t *) xine_xmalloc (sizeof (roqaudio_decoder_t));
- this->audio_decoder.init = roqaudio_init;
this->audio_decoder.decode_data = roqaudio_decode_data;
this->audio_decoder.reset = roqaudio_reset;
- this->audio_decoder.close = roqaudio_close;
- this->audio_decoder.get_identifier = roqaudio_get_id;
this->audio_decoder.dispose = roqaudio_dispose;
+ this->size = 0;
+
+ this->stream = stream;
+
+ this->buf = NULL;
+ this->output_open = 0;
+ this->output_channels = 0;
+
+ /* initialize tables of squares */
+ for (i = 0; i < 128; i++) {
+ square = i * i;
+ this->square_array[i] = square;
+ this->square_array[i + 128] = -square;
+ }
+
+ return &this->audio_decoder;
+}
+
+static char *get_identifier (audio_decoder_class_t *this) {
+ return "RoQ Audio";
+}
+
+static char *get_description (audio_decoder_class_t *this) {
+ return "Id Roq audio decoder plugin";
+}
+
+static void dispose_class (audio_decoder_class_t *this) {
+ free (this);
+}
+
+static void *init_plugin (xine_t *xine, void *data) {
+
+ roqaudio_class_t *this;
+
+ this = (roqaudio_class_t *) xine_xmalloc (sizeof (roqaudio_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 (audio_decoder_t *) this;
+ return this;
}
static uint32_t audio_types[] = {
@@ -206,6 +222,6 @@ static decoder_info_t dec_info_audio = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_AUDIO_DECODER, 9, "roq", XINE_VERSION_CODE, &dec_info_audio, init_audio_decoder_plugin },
+ { PLUGIN_AUDIO_DECODER, 10, "roqaudio", XINE_VERSION_CODE, &dec_info_audio, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/libxinevdec/roqvideo.c b/src/libxinevdec/roqvideo.c
index 21825bd52..c5359451d 100644
--- a/src/libxinevdec/roqvideo.c
+++ b/src/libxinevdec/roqvideo.c
@@ -18,7 +18,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: roqvideo.c,v 1.11 2002/10/05 22:16:08 tmmm Exp $
+ * $Id: roqvideo.c,v 1.12 2002/10/23 02:55:01 tmmm Exp $
*/
/* And this is the header that came with the RoQ video decoder: */
@@ -82,10 +82,17 @@ typedef struct {
int idx[4];
} roq_qcell;
+typedef struct {
+ video_decoder_class_t decoder_class;
+} roqvideo_class_t;
+
typedef struct roq_decoder_s {
video_decoder_t video_decoder;
- vo_instance_t *video_out;
+ roqvideo_class_t *class;
+ xine_stream_t *stream;
+
+
int video_step;
int skipframes;
unsigned char *buf;
@@ -110,13 +117,13 @@ typedef struct roq_decoder_s {
* same for u and v */
int current_planes;
-} roq_decoder_t;
+} roqvideo_decoder_t;
/**************************************************************************
* RoQ video specific decode functions
*************************************************************************/
-static void apply_vector_2x2(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
+static void apply_vector_2x2(roqvideo_decoder_t *ri, int x, int y, roq_cell *cell) {
unsigned char *yptr;
yptr = ri->cur_y + (y * ri->width) + x;
@@ -129,7 +136,7 @@ static void apply_vector_2x2(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
ri->cur_v[(y/2) * (ri->width/2) + x/2] = cell->v;
}
-static void apply_vector_4x4(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
+static void apply_vector_4x4(roqvideo_decoder_t *ri, int x, int y, roq_cell *cell) {
unsigned long row_inc, c_row_inc;
register unsigned char y0, y1, u, v;
unsigned char *yptr, *uptr, *vptr;
@@ -167,7 +174,7 @@ static void apply_vector_4x4(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
*yptr++ = y1;
}
-static void apply_motion_4x4(roq_decoder_t *ri, int x, int y, unsigned char mv,
+static void apply_motion_4x4(roqvideo_decoder_t *ri, int x, int y, unsigned char mv,
char mean_x, char mean_y)
{
int i, mx, my;
@@ -206,7 +213,7 @@ static void apply_motion_4x4(roq_decoder_t *ri, int x, int y, unsigned char mv,
}
}
-static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
+static void apply_motion_8x8(roqvideo_decoder_t *ri, int x, int y,
unsigned char mv, char mean_x, char mean_y) {
int mx, my, i;
@@ -253,7 +260,7 @@ static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
}
}
-static void roq_decode_frame(roq_decoder_t *ri) {
+static void roqvideo_decode_frame(roqvideo_decoder_t *ri) {
unsigned int chunk_id = 0, chunk_arg = 0;
unsigned long chunk_size = 0;
int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1;
@@ -374,24 +381,17 @@ static void roq_decode_frame(roq_decoder_t *ri) {
* xine video plugin functions
*************************************************************************/
-static void roq_init (video_decoder_t *this_gen, vo_instance_t *video_out) {
- roq_decoder_t *this = (roq_decoder_t *) this_gen;
-
- this->video_out = video_out;
- this->buf = NULL;
-}
-
-static void roq_decode_data (video_decoder_t *this_gen,
+static void roqvideo_decode_data (video_decoder_t *this_gen,
buf_element_t *buf) {
- roq_decoder_t *this = (roq_decoder_t *) this_gen;
+ roqvideo_decoder_t *this = (roqvideo_decoder_t *) this_gen;
vo_frame_t *img; /* video out frame */
if (buf->decoder_flags & BUF_FLAG_PREVIEW)
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);
@@ -440,8 +440,8 @@ static void roq_decode_data (video_decoder_t *this_gen,
this->video_step = buf->decoder_info[0];
if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
- img = this->video_out->get_frame (this->video_out, this->width,
- this->height, XINE_VO_ASPECT_SQUARE, XINE_IMGFMT_YV12,
+ img = this->stream->video_out->get_frame (this->stream->video_out,
+ this->width, this->height, XINE_VO_ASPECT_SQUARE, XINE_IMGFMT_YV12,
VO_BOTH_FIELDS);
img->pts = buf->pts;
@@ -464,7 +464,7 @@ static void roq_decode_data (video_decoder_t *this_gen,
this->prev_v = this->v[0];
this->current_planes = 0;
}
- roq_decode_frame(this);
+ roqvideo_decode_frame(this);
xine_fast_memcpy(img->base[0], this->cur_y, this->y_size);
xine_fast_memcpy(img->base[1], this->cur_u, this->c_size);
xine_fast_memcpy(img->base[2], this->cur_v, this->c_size);
@@ -494,17 +494,17 @@ static void roq_decode_data (video_decoder_t *this_gen,
}
}
-static void roq_flush (video_decoder_t *this_gen) {
+static void roqvideo_flush (video_decoder_t *this_gen) {
}
-static void roq_reset (video_decoder_t *this_gen) {
+static void roqvideo_reset (video_decoder_t *this_gen) {
}
-static void roq_close (video_decoder_t *this_gen) {
+static void roqvideo_dispose (video_decoder_t *this_gen) {
- roq_decoder_t *this = (roq_decoder_t *) this_gen;
+ roqvideo_decoder_t *this = (roqvideo_decoder_t *) this_gen;
- this->video_out->close(this->video_out);
+ this->stream->video_out->close(this->stream->video_out);
free(this->y[0]);
free(this->y[1]);
@@ -512,29 +512,52 @@ static void roq_close (video_decoder_t *this_gen) {
free(this->u[1]);
free(this->v[0]);
free(this->v[1]);
+
+ free (this_gen);
+}
+
+static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) {
+
+ roqvideo_decoder_t *this ;
+
+ this = (roqvideo_decoder_t *) xine_xmalloc (sizeof (roqvideo_decoder_t));
+
+ this->video_decoder.decode_data = roqvideo_decode_data;
+ this->video_decoder.flush = roqvideo_flush;
+ this->video_decoder.reset = roqvideo_reset;
+ this->video_decoder.dispose = roqvideo_dispose;
+ this->size = 0;
+
+ this->stream = stream;
+ this->class = (roqvideo_class_t *) class_gen;
+
+ this->buf = NULL;
+
+ return &this->video_decoder;
}
-static char *roq_get_id(void) {
+static char *get_identifier (video_decoder_class_t *this) {
return "RoQ Video";
}
-static void roq_dispose (video_decoder_t *this_gen) {
- free (this_gen);
+static char *get_description (video_decoder_class_t *this) {
+ return "Id RoQ video decoder plugin";
+}
+
+static void dispose_class (video_decoder_class_t *this) {
+ free (this);
}
-static void *init_video_decoder_plugin (xine_t *xine, void *data) {
+static void *init_plugin (xine_t *xine, void *data) {
- roq_decoder_t *this ;
+ roqvideo_class_t *this;
- this = (roq_decoder_t *) malloc (sizeof (roq_decoder_t));
+ this = (roqvideo_class_t *) xine_xmalloc (sizeof (roqvideo_class_t));
- this->video_decoder.init = roq_init;
- this->video_decoder.decode_data = roq_decode_data;
- this->video_decoder.flush = roq_flush;
- this->video_decoder.reset = roq_reset;
- this->video_decoder.close = roq_close;
- this->video_decoder.get_identifier = roq_get_id;
- this->video_decoder.dispose = roq_dispose;
+ 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;
}
@@ -555,6 +578,6 @@ static decoder_info_t dec_info_video = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_DECODER, 10, "roq", XINE_VERSION_CODE, &dec_info_video, init_video_decoder_plugin },
+ { PLUGIN_VIDEO_DECODER, 11, "roq", XINE_VERSION_CODE, &dec_info_video, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};