diff options
Diffstat (limited to 'src/dxr3/dxr3_decode_spu.c')
-rw-r--r-- | src/dxr3/dxr3_decode_spu.c | 152 |
1 files changed, 76 insertions, 76 deletions
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c index 82c8f8da0..7682455eb 100644 --- a/src/dxr3/dxr3_decode_spu.c +++ b/src/dxr3/dxr3_decode_spu.c @@ -1,18 +1,18 @@ -/* +/* * Copyright (C) 2000-2004 the xine project - * + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -21,7 +21,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif - + /* dxr3 spu decoder plugin. * Accepts the spu data from xine and sends it directly to the * corresponding dxr3 device. Also handles dvd menu button highlights. @@ -76,7 +76,7 @@ static const decoder_info_t dxr3_spudec_info = { }; const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ + /* type, API, "name", version, special_info, init_function */ { PLUGIN_SPU_DECODER, 16, "dxr3-spudec", XINE_VERSION_CODE, &dxr3_spudec_info, &dxr3_spudec_init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; @@ -114,7 +114,7 @@ struct pci_node_s { typedef struct dxr3_spudec_class_s { spu_decoder_class_t spu_decoder_class; - + int instance; /* we allow only one instance of this plugin */ } dxr3_spudec_class_t; @@ -124,10 +124,10 @@ typedef struct dxr3_spudec_s { xine_stream_t *stream; dxr3_driver_t *dxr3_vo; /* we need to talk to the video out */ xine_event_queue_t *event_queue; - + int devnum; int fd_spu; /* to access the dxr3 spu device */ - + dxr3_spu_stream_state_t spu_stream_state[MAX_SPU_STREAMS]; uint32_t clut[16]; /* the current color lookup table */ int menu; /* are we in a menu? */ @@ -135,7 +135,7 @@ typedef struct dxr3_spudec_s { pci_node_t pci_cur; /* a list of PCI packs, with the list head being current */ pthread_mutex_t pci_lock; uint32_t buttonN; /* currently highlighted button */ - + int anamorphic; /* this is needed to detect anamorphic menus */ } dxr3_spudec_t; @@ -154,7 +154,7 @@ static inline int dxr3_present(xine_stream_t *stream) plugin_node_t *node; video_driver_class_t *vo_class; int present = 0; - + if (stream->video_driver && stream->video_driver->node) { node = (plugin_node_t *)stream->video_driver->node; if (node->plugin_class) { @@ -181,7 +181,7 @@ static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this) static inline void dxr3_spudec_update_nav(dxr3_spudec_t *this) { metronom_clock_t *clock = this->stream->xine->clock; - + if (this->pci_cur.next && this->pci_cur.next->vpts <= clock->get_current_time(clock)) { pci_node_t *node = this->pci_cur.next; xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); @@ -201,17 +201,17 @@ static inline void dxr3_swab_clut(int *clut) static void *dxr3_spudec_init_plugin(xine_t *xine, void* data) { dxr3_spudec_class_t *this; - + this = calloc(1, sizeof(dxr3_spudec_class_t)); if (!this) return NULL; - + this->spu_decoder_class.open_plugin = dxr3_spudec_open_plugin; this->spu_decoder_class.get_identifier = dxr3_spudec_get_identifier; this->spu_decoder_class.get_description = dxr3_spudec_get_description; this->spu_decoder_class.dispose = dxr3_spudec_class_dispose; - + this->instance = 0; - + return &this->spu_decoder_class; } @@ -221,20 +221,20 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi dxr3_spudec_t *this; dxr3_spudec_class_t *class = (dxr3_spudec_class_t *)class_gen; char tmpstr[128]; - + if (class->instance) return NULL; if (!dxr3_present(stream)) return NULL; - + this = calloc(1, sizeof(dxr3_spudec_t)); if (!this) return NULL; - + this->spu_decoder.decode_data = dxr3_spudec_decode_data; this->spu_decoder.reset = dxr3_spudec_reset; this->spu_decoder.discontinuity = dxr3_spudec_discontinuity; this->spu_decoder.dispose = dxr3_spudec_dispose; this->spu_decoder.get_interact_info = dxr3_spudec_interact_info; this->spu_decoder.set_button = dxr3_spudec_set_button; - + this->class = class; this->stream = stream; /* We need to talk to dxr3 video out to coordinate spus and overlays */ @@ -243,7 +243,7 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi this->devnum = stream->xine->config->register_num(stream->xine->config, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); - + pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (this->dxr3_vo->fd_spu) this->fd_spu = this->dxr3_vo->fd_spu; @@ -251,7 +251,7 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi /* open dxr3 spu device */ snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300_sp-%d", this->devnum); if ((this->fd_spu = open(tmpstr, O_WRONLY)) < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_spu: Failed to open spu device %s (%s)\n"), tmpstr, strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); free(this); @@ -263,19 +263,19 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi this->dxr3_vo->fd_spu = this->fd_spu; } pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); - + this->menu = 0; this->button_filter = 1; this->pci_cur.pci.hli.hl_gi.hli_ss = 0; this->pci_cur.next = NULL; this->buttonN = 1; - + this->anamorphic = 0; - + pthread_mutex_init(&this->pci_lock, NULL); - + class->instance = 1; - + return &this->spu_decoder; } @@ -303,11 +303,11 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) dxr3_spu_stream_state_t *state = &this->spu_stream_state[stream_id]; uint32_t spu_channel = this->stream->spu_channel; xine_event_t *event; - + /* handle queued events */ while ((event = xine_event_get(this->event_queue))) { llprintf(LOG_SPU, "event caught: SPU_FD = %i\n",this->fd_spu); - + switch (event->type) { case XINE_EVENT_FRAME_FORMAT_CHANGE: /* we are in anamorphic mode, if the frame is 16:9, but not pan&scan'ed */ @@ -317,17 +317,17 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) llprintf(LOG_BTN, "anamorphic mode %s\n", this->anamorphic ? "on" : "off"); break; } - + xine_event_free(event); } - + /* check, if we need to process the next PCI from the list */ pthread_mutex_lock(&this->pci_lock); dxr3_spudec_update_nav(this); pthread_mutex_unlock(&this->pci_lock); - + if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || - !(buf->decoder_flags & BUF_FLAG_SPECIAL) || + !(buf->decoder_flags & BUF_FLAG_SPECIAL) || buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) return; @@ -337,7 +337,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) dxr3_swab_clut((int *)buf->content); pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_SETPALETTE, buf->content)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set CLUT (%s)\n", strerror(errno)); /* remember clut, when video out places some overlay we may need to restore it */ memcpy(this->clut, buf->content, 16 * sizeof(uint32_t)); @@ -347,20 +347,20 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) } if (buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV) { uint8_t *p = buf->content; - + llprintf(LOG_BTN, "got NAV packet\n"); pthread_mutex_lock(&this->pci_lock); - + /* just watch out for menus */ if (p[3] == 0xbf && p[6] == 0x00) { /* Private stream 2 */ pci_t pci; - + navRead_PCI(&pci, p + 7); llprintf(LOG_BTN, "PCI packet hli_ss is %d\n", pci.hli.hl_gi.hli_ss); - + if (pci.hli.hl_gi.hli_ss == 1) { /* menu ahead */ - + /* NAV packets contain start and end presentation timestamps, which tell the * application, when the highlight information in the NAV is supposed to be valid. * We handle these timestamps only in a very stripped-down way: We keep a list @@ -389,7 +389,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) dxr3_spudec_process_nav(this); } } - + if ((pci.hli.hl_gi.hli_ss == 0) && (this->pci_cur.pci.hli.hl_gi.hli_ss == 1)) { /* this is (or: should be, I hope I got this right) a subpicture plane, that hides all menu buttons */ @@ -413,7 +413,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) pthread_mutex_unlock(&this->pci_lock); return; } - + /* We parse the SPUs command and end sequence here for two reasons: * 1. Look for the display duration entry in the spu packets. * If the spu is a menu button highlight pane, this entry must not exist, @@ -494,7 +494,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) if (state->spu_length < 0) state->spu_length = 0; state->bytes_passed += buf->size; } - + /* filter unwanted streams */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) { llprintf(LOG_SPU, "Dropping SPU channel %d. Preview data\n", stream_id); @@ -512,43 +512,43 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) /* We used to filter for SPU forcing here as well, but this does not work * this way with the DXR3, because we have to evaluate the SPU command sequence * to detect, if a particular SPU is forced or not. See the parsing code above. */ - + pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); - + /* write sync timestamp to the card */ if (buf->pts) { int64_t vpts; uint32_t vpts32; - + vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, buf->pts); llprintf(LOG_PTS, "pts = %" PRId64 " vpts = %" PRIu64 "\n", buf->pts, vpts); vpts32 = vpts; if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_SETPTS, &vpts32)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: spu setpts failed (%s)\n", strerror(errno)); } - + /* has video out tampered with our palette */ if (this->dxr3_vo->clut_cluttered) { if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_SETPALETTE, this->clut)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set CLUT (%s)\n", strerror(errno)); this->dxr3_vo->clut_cluttered = 0; } - + /* write spu data to the card */ llprintf(LOG_SPU, "write: SPU_FD = %i\n",this->fd_spu); written = write(this->fd_spu, buf->content, buf->size); if (written < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: spu device write failed (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); return; } if (written != buf->size) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: Could only write %zd of %d spu bytes.\n", written, buf->size); - + pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } @@ -556,7 +556,7 @@ static void dxr3_spudec_reset(spu_decoder_t *this_gen) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; int i; - + for (i = 0; i < MAX_SPU_STREAMS; i++) this->spu_stream_state[i].spu_length = 0; pthread_mutex_lock(&this->pci_lock); @@ -567,7 +567,7 @@ static void dxr3_spudec_reset(spu_decoder_t *this_gen) static void dxr3_spudec_discontinuity(spu_decoder_t *this_gen) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; - + pthread_mutex_lock(&this->pci_lock); dxr3_spudec_clear_nav_list(this); pthread_mutex_unlock(&this->pci_lock); @@ -582,7 +582,7 @@ static void dxr3_spudec_dispose(spu_decoder_t *this_gen) 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF, 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF }; dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; - + llprintf(LOG_SPU, "close: SPU_FD = %i\n",this->fd_spu); pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); /* clear any remaining spu */ @@ -592,7 +592,7 @@ static void dxr3_spudec_dispose(spu_decoder_t *this_gen) this->fd_spu = 0; this->dxr3_vo->fd_spu = 0; pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); - + dxr3_spudec_clear_nav_list(this); xine_event_dispose_queue(this->event_queue); pthread_mutex_destroy(&this->pci_lock); @@ -603,7 +603,7 @@ static void dxr3_spudec_dispose(spu_decoder_t *this_gen) static int dxr3_spudec_interact_info(spu_decoder_t *this_gen, void *data) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; - + pthread_mutex_lock(&this->pci_lock); dxr3_spudec_update_nav(this); memcpy(data, &this->pci_cur.pci, sizeof(pci_t)); @@ -615,7 +615,7 @@ static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int3 { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; em8300_button_t btn; - + llprintf(LOG_BTN, "setting button\n"); this->buttonN = button; pthread_mutex_lock(&this->pci_lock); @@ -624,7 +624,7 @@ static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int3 (dxr3_spudec_copy_nav_to_btn(this, mode - 1, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, &btn)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } @@ -639,7 +639,7 @@ static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int3 static void dxr3_spudec_process_nav(dxr3_spudec_t *this) { em8300_button_t btn; - + this->menu = 1; this->button_filter = 0; if (this->pci_cur.pci.hli.hl_gi.fosl_btnn > 0) { @@ -655,15 +655,15 @@ static void dxr3_spudec_process_nav(dxr3_spudec_t *this) if ((dxr3_spudec_copy_nav_to_btn(this, 0, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, &btn)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } else { /* current button does not exist -> use another one */ xine_event_t event; - + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("requested button not available\n")); - + if (this->buttonN > this->pci_cur.pci.hli.hl_gi.btn_ns) this->buttonN = this->pci_cur.pci.hli.hl_gi.btn_ns; else @@ -673,11 +673,11 @@ static void dxr3_spudec_process_nav(dxr3_spudec_t *this) event.data = &this->buttonN; event.data_length = sizeof(this->buttonN); xine_event_send(this->stream, &event); - + if ((dxr3_spudec_copy_nav_to_btn(this, 0, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, &btn)) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } else { @@ -689,10 +689,10 @@ static void dxr3_spudec_process_nav(dxr3_spudec_t *this) static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn) { btni_t *button_ptr = NULL; - + if ((this->buttonN <= 0) || (this->buttonN > this->pci_cur.pci.hli.hl_gi.btn_ns)) return -1; - + /* choosing a button from a matching button group */ if (this->anamorphic && !this->dxr3_vo->widescreen_enabled && @@ -700,7 +700,7 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300 this->stream->spu_channel_letterbox != this->stream->spu_channel && this->stream->spu_channel_letterbox >= 0) { unsigned int btns_per_group = 36 / this->pci_cur.pci.hli.hl_gi.btngr_ns; - + /* use a letterbox button group for letterboxed anamorphic menus on tv out */ if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 1 && (this->pci_cur.pci.hli.hl_gi.btngr1_dsp_ty & 2)) button_ptr = &this->pci_cur.pci.hli.btnit[0 * btns_per_group + this->buttonN - 1]; @@ -708,13 +708,13 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300 button_ptr = &this->pci_cur.pci.hli.btnit[1 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 3 && (this->pci_cur.pci.hli.hl_gi.btngr3_dsp_ty & 2)) button_ptr = &this->pci_cur.pci.hli.btnit[2 * btns_per_group + this->buttonN - 1]; - + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "No suitable letterbox button group found.\n"); _x_assert(button_ptr); - + } else { unsigned int btns_per_group = 36 / this->pci_cur.pci.hli.hl_gi.btngr_ns; - + /* otherwise use a normal 4:3 or widescreen button group */ if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 1 && !(this->pci_cur.pci.hli.hl_gi.btngr1_dsp_ty & 6)) button_ptr = &this->pci_cur.pci.hli.btnit[0 * btns_per_group + this->buttonN - 1]; @@ -722,14 +722,14 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300 button_ptr = &this->pci_cur.pci.hli.btnit[1 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 3 && !(this->pci_cur.pci.hli.hl_gi.btngr3_dsp_ty & 6)) button_ptr = &this->pci_cur.pci.hli.btnit[2 * btns_per_group + this->buttonN - 1]; - + } if (!button_ptr) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: No suitable menu button group found, using group 1.\n"); button_ptr = &this->pci_cur.pci.hli.btnit[this->buttonN - 1]; } - + if(button_ptr->btn_coln != 0) { llprintf(LOG_BTN, "normal button clut, mode %d\n", mode); btn->color = (this->pci_cur.pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> 16); @@ -739,7 +739,7 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300 btn->right = button_ptr->x_end; btn->bottom = button_ptr->y_end; return 1; - } + } return -1; } |