diff options
author | Mike Melanson <mike@multimedia.cx> | 2002-10-23 02:55:01 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2002-10-23 02:55:01 +0000 |
commit | 3fd3d7d33515f867316010fe4fbe63bd57d1f7d3 (patch) | |
tree | b0e1958bd806edb68d889a42201a3ebe397d87f4 | |
parent | 6a57fa96f65018f48bed7d086d34af54e85a1960 (diff) | |
download | xine-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.c | 492 | ||||
-rw-r--r-- | src/libxineadec/roqaudio.c | 114 | ||||
-rw-r--r-- | src/libxinevdec/roqvideo.c | 103 |
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 } }; |