summaryrefslogtreecommitdiff
path: root/src/dxr3/dxr3_decode_spu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dxr3/dxr3_decode_spu.c')
-rw-r--r--src/dxr3/dxr3_decode_spu.c152
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;
}