summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2002-10-26 14:35:04 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2002-10-26 14:35:04 +0000
commite6926fa3475e1c528aeba7a73daabfa6d70d84e5 (patch)
tree829802b044ed971210cfef79a5932ab4ad963fc1
parent28702c7e332217caec870f664ad5423ca2547fac (diff)
downloadxine-lib-e6926fa3475e1c528aeba7a73daabfa6d70d84e5.tar.gz
xine-lib-e6926fa3475e1c528aeba7a73daabfa6d70d84e5.tar.bz2
- dxr3 adapted to new API (compiles, but untested)
- use vo_scale helper for video_out_dxr3 (overlay display is now pixel aspect corrected) - some additional dxr3 fixes, especially overlay (menus & overlay, forgotten brightness/constrast/saturation setting ...) CVS patchset: 3010 CVS date: 2002/10/26 14:35:04
-rw-r--r--src/Makefile.am1
-rw-r--r--src/dxr3/dxr3.h6
-rw-r--r--src/dxr3/dxr3_decode_spu.c328
-rw-r--r--src/dxr3/dxr3_decode_video.c351
-rw-r--r--src/dxr3/dxr3_mpeg_encoders.c16
-rw-r--r--src/dxr3/dxr3_scr.c13
-rw-r--r--src/dxr3/dxr3_scr.h4
-rw-r--r--src/dxr3/video_out_dxr3.c362
-rw-r--r--src/dxr3/video_out_dxr3.h96
9 files changed, 640 insertions, 537 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f34afe541..83e44da2c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ SUBDIRS = \
xine-engine \
audio_out \
video_out \
+ dxr3 \
input \
demuxers \
libffmpeg \
diff --git a/src/dxr3/dxr3.h b/src/dxr3/dxr3.h
index 0a2396d8b..2790a1809 100644
--- a/src/dxr3/dxr3.h
+++ b/src/dxr3/dxr3.h
@@ -17,7 +17,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: dxr3.h,v 1.4 2002/09/05 20:44:39 mroi Exp $
+ * $Id: dxr3.h,v 1.5 2002/10/26 14:35:04 mroi Exp $
*/
#ifndef HAVE_DXR3_H
@@ -36,5 +36,9 @@
/* image format used by dxr3_decoder to tag undecoded mpeg data */
#define XINE_IMGFMT_DXR3 (('3'<<24)|('R'<<16)|('X'<<8)|'D')
+/* name of the dxr3 video out plugin
+ * (used by decoders to check for dxr3 presence) */
+#define DXR3_VO_ID "dxr3"
+
#endif
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c
index dfb4cbf3d..8c3540ac9 100644
--- a/src/dxr3/dxr3_decode_spu.c
+++ b/src/dxr3/dxr3_decode_spu.c
@@ -17,7 +17,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: dxr3_decode_spu.c,v 1.20 2002/09/27 13:07:43 mroi Exp $
+ * $Id: dxr3_decode_spu.c,v 1.21 2002/10/26 14:35:04 mroi Exp $
*/
/* dxr3 spu decoder plugin.
@@ -52,7 +52,7 @@
#define MAX_SPU_STREAMS 32
-/* plugin initialization function */
+/* plugin class initialization function */
static void *dxr3_spudec_init_plugin(xine_t *xine, void *);
@@ -71,14 +71,18 @@ plugin_info_t xine_plugin_info[] = {
};
-/* functions required by xine api */
-static char *dxr3_spudec_get_id(void);
-static void dxr3_spudec_init(spu_decoder_t *this_gen, vo_instance_t *vo_out);
+/* plugin class functions */
+static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xine_stream_t *stream);
+static char *dxr3_spudec_get_identifier(spu_decoder_class_t *class_gen);
+static char *dxr3_spudec_get_description(spu_decoder_class_t *class_gen);
+static void dxr3_spudec_class_dispose(spu_decoder_class_t *class_gen);
+
+/* plugin instance functions */
static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf);
-static int dxr3_spudec_get_nav_pci(spu_decoder_t *this_gen, pci_t *pci);
static void dxr3_spudec_reset(spu_decoder_t *this_gen);
-static void dxr3_spudec_close(spu_decoder_t *this_gen);
static void dxr3_spudec_dispose(spu_decoder_t *this_gen);
+static int dxr3_spudec_get_nav_pci(spu_decoder_t *this_gen, pci_t *pci);
+static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int32_t mode);
/* plugin structures */
typedef struct dxr3_spu_stream_state_s {
@@ -91,13 +95,22 @@ typedef struct dxr3_spu_stream_state_s {
int bytes_passed; /* used to parse the spu */
} dxr3_spu_stream_state_t;
+typedef struct dxr3_spudec_class_s {
+ spu_decoder_class_t spu_decoder_class;
+
+ int instance; /* we allow only one instance of this plugin */
+
+ char devname[128];
+ char devnum[3];
+} dxr3_spudec_class_t;
+
typedef struct dxr3_spudec_s {
spu_decoder_t spu_decoder;
- xine_t *xine;
+ dxr3_spudec_class_t *class;
+ xine_stream_t *stream;
dxr3_driver_t *dxr3_vo; /* we need to talk to the video out */
+ xine_event_queue_t *event_queue;
- char devname[128];
- char devnum[3];
int fd_spu; /* to access the dxr3 spu device */
dxr3_spu_stream_state_t spu_stream_state[MAX_SPU_STREAMS];
@@ -113,21 +126,19 @@ typedef struct dxr3_spudec_s {
} dxr3_spudec_t;
/* helper functions */
-static int dxr3_present(xine_t *xine);
-static void dxr3_spudec_event_listener(void *this_gen, xine_event_t *event_gen);
+static int dxr3_present(xine_stream_t *stream);
+static void dxr3_spudec_handle_event(dxr3_spudec_t *this);
static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn);
static void dxr3_swab_clut(int* clut);
static void *dxr3_spudec_init_plugin(xine_t *xine, void* data)
{
- dxr3_spudec_t *this;
+ dxr3_spudec_class_t *this;
const char *confstr;
int dashpos;
- if (!dxr3_present(xine)) return NULL;
-
- this = (dxr3_spudec_t *)malloc(sizeof(dxr3_spudec_t));
+ this = (dxr3_spudec_class_t *)malloc(sizeof(dxr3_spudec_class_t));
if (!this) return NULL;
confstr = xine->config->register_string(xine->config,
@@ -145,56 +156,54 @@ static void *dxr3_spudec_init_plugin(xine_t *xine, void* data)
this->devnum[0] = '\0';
}
- this->spu_decoder.get_identifier = dxr3_spudec_get_id;
- this->spu_decoder.init = dxr3_spudec_init;
- this->spu_decoder.decode_data = dxr3_spudec_decode_data;
- this->spu_decoder.get_nav_pci = dxr3_spudec_get_nav_pci;
- this->spu_decoder.reset = dxr3_spudec_reset;
- this->spu_decoder.close = dxr3_spudec_close;
- this->spu_decoder.dispose = dxr3_spudec_dispose;
+ 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->xine = xine;
- /* We need to talk to dxr3 video out to coordinate spus and overlays */
- this->dxr3_vo = (dxr3_driver_t *)xine->video_driver;
-
- this->fd_spu = 0;
- this->menu = 0;
- this->button_filter = 1;
- this->pci.hli.hl_gi.hli_ss = 0;
- this->buttonN = 1;
-
- this->aspect = XINE_VO_ASPECT_4_3;
+ this->instance = 0;
- pthread_mutex_init(&this->pci_lock, NULL);
-
- xine_register_event_listener(xine, dxr3_spudec_event_listener, this);
-
- return &this->spu_decoder;
+ return &this->spu_decoder_class;
}
-static char *dxr3_spudec_get_id(void)
-{
- return "dxr3-spudec";
-}
-static void dxr3_spudec_init(spu_decoder_t *this_gen, vo_instance_t *vo_out)
+static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xine_stream_t *stream)
{
- dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
+ dxr3_spudec_t *this;
+ dxr3_spudec_class_t *class = (dxr3_spudec_class_t *)class_gen;
char tmpstr[128];
int i;
- pthread_mutex_lock(&this->dxr3_vo->spu_device_lock);
+ if (class->instance) return NULL;
+ if (!dxr3_present(stream)) return NULL;
+
+ this = (dxr3_spudec_t *)malloc(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.dispose = dxr3_spudec_dispose;
+ this->spu_decoder.get_nav_pci = dxr3_spudec_get_nav_pci;
+ 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 */
+ this->dxr3_vo = (dxr3_driver_t *)stream->video_driver;
+ this->event_queue = xine_event_new_queue(stream);
+
+ pthread_mutex_lock(&this->dxr3_vo->spu_device_lock);
if (this->dxr3_vo->fd_spu)
this->fd_spu = this->dxr3_vo->fd_spu;
else {
/* open dxr3 spu device */
- snprintf(tmpstr, sizeof(tmpstr), "%s_sp%s", this->devname, this->devnum);
+ snprintf(tmpstr, sizeof(tmpstr), "%s_sp%s", class->devname, class->devnum);
if ((this->fd_spu = open(tmpstr, O_WRONLY)) < 0) {
printf("dxr3_decode_spu: Failed to open spu device %s (%s)\n",
tmpstr, strerror(errno));
pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
- return;
+ free(this);
+ return NULL;
}
#if LOG_SPU
printf ("dxr3_decode_spu: init: SPU_FD = %i\n",this->fd_spu);
@@ -203,22 +212,52 @@ static void dxr3_spudec_init(spu_decoder_t *this_gen, vo_instance_t *vo_out)
* access to the same spu device */
this->dxr3_vo->fd_spu = this->fd_spu;
}
-
pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
- for (i=0; i < MAX_SPU_STREAMS; i++) {
+ for (i = 0; i < MAX_SPU_STREAMS; i++) {
this->spu_stream_state[i].stream_filter = 1;
this->spu_stream_state[i].spu_length = 0;
}
+
+ this->menu = 0;
+ this->button_filter = 1;
+ this->pci.hli.hl_gi.hli_ss = 0;
+ this->buttonN = 1;
+
+ this->aspect = XINE_VO_ASPECT_4_3;
+
+ pthread_mutex_init(&this->pci_lock, NULL);
+
+ class->instance = 1;
+
+ return &this->spu_decoder;
+}
+
+static char *dxr3_spudec_get_identifier(spu_decoder_class_t *class_gen)
+{
+ return "dxr3-spudec";
+}
+
+static char *dxr3_spudec_get_description(spu_decoder_class_t *class_gen)
+{
+ return "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 decoder card";
}
+static void dxr3_spudec_class_dispose(spu_decoder_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+
static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
{
dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
ssize_t written;
uint32_t stream_id = buf->type & 0x1f;
dxr3_spu_stream_state_t *state = &this->spu_stream_state[stream_id];
- uint32_t spu_channel = this->xine->spu_channel;
+ uint32_t spu_channel = this->stream->spu_channel;
+
+ dxr3_spudec_handle_event(this);
if (buf->type == BUF_SPU_CLUT) {
#if LOG_SPU
@@ -270,12 +309,14 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
if ( this->pci.hli.hl_gi.fosl_btnn > 0) {
/* a button is forced here, inform nav plugin */
spu_button_t spu_button;
- xine_spu_event_t spu_event;
- this->buttonN = this->pci.hli.hl_gi.fosl_btnn ;
- spu_event.event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
- spu_event.data = &spu_button;
- spu_button.buttonN = this->buttonN;
- xine_send_event(this->xine, &spu_event.event);
+ xine_event_t event;
+ this->buttonN = this->pci.hli.hl_gi.fosl_btnn ;
+ event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
+ event.stream = this->stream;
+ event.data = &spu_button;
+ event.data_length = sizeof(spu_button);
+ spu_button.buttonN = 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);
@@ -361,12 +402,10 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
#endif
return;
}
- if (this->aspect == XINE_VO_ASPECT_ANAMORPHIC &&
- this->xine->spu_channel_user == -1 && this->xine->spu_channel_letterbox >= 0 &&
- this->xine->video_driver->get_property(this->xine->video_driver, VO_PROP_VO_TYPE) ==
- VO_TYPE_DXR3_LETTERBOXED) {
- /* Use the letterbox version of the subpicture for tv out. */
- spu_channel = this->xine->spu_channel_letterbox;
+ if (this->aspect == XINE_VO_ASPECT_ANAMORPHIC && !this->dxr3_vo->widescreen_enabled &&
+ this->stream->spu_channel_user == -1 && this->stream->spu_channel_letterbox >= 0) {
+ /* Use the letterbox version of the subpicture for letterboxed display. */
+ spu_channel = this->stream->spu_channel_letterbox;
}
if ((spu_channel & 0x1f) != stream_id) {
#if LOG_SPU
@@ -388,10 +427,9 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
int64_t vpts;
uint32_t vpts32;
- vpts = this->xine->metronom->got_spu_packet(
- this->xine->metronom, buf->pts);
+ vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, buf->pts);
/* estimate with current time, when metronom doesn't know */
- if (!vpts) vpts = this->xine->metronom->get_current_time(this->xine->metronom);
+ if (!vpts) vpts = this->stream->metronom->get_current_time(this->stream->metronom);
#if LOG_PTS
printf("dxr3_decode_spu: pts = %lld vpts = %lld\n", buf->pts, vpts);
#endif
@@ -425,16 +463,6 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
}
-static int dxr3_spudec_get_nav_pci(spu_decoder_t *this_gen, pci_t *pci)
-{
- dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
-
- pthread_mutex_lock(&this->pci_lock);
- memcpy(pci, &this->pci, sizeof(pci_t) );
- pthread_mutex_unlock(&this->pci_lock);
- return 1;
-}
-
static void dxr3_spudec_reset(spu_decoder_t *this_gen)
{
dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
@@ -444,9 +472,10 @@ static void dxr3_spudec_reset(spu_decoder_t *this_gen)
this->spu_stream_state[i].spu_length = 0;
}
-static void dxr3_spudec_close(spu_decoder_t *this_gen)
+static void dxr3_spudec_dispose(spu_decoder_t *this_gen)
{
dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
+
#if LOG_SPU
printf("dxr3_decode_spu: close: SPU_FD = %i\n",this->fd_spu);
#endif
@@ -455,95 +484,90 @@ static void dxr3_spudec_close(spu_decoder_t *this_gen)
this->fd_spu = 0;
this->dxr3_vo->fd_spu = 0;
pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
-}
-
-static void dxr3_spudec_dispose(spu_decoder_t *this_gen)
-{
- dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
- xine_remove_event_listener(this->xine, dxr3_spudec_event_listener);
+ xine_event_dispose_queue(this->event_queue);
pthread_mutex_destroy(&this->pci_lock);
+ this->class->instance = 0;
free (this);
}
-
-static int dxr3_present(xine_t *xine)
+static int dxr3_spudec_get_nav_pci(spu_decoder_t *this_gen, pci_t *pci)
{
- int info;
+ dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
- if (xine && xine->video_driver) {
- info = xine->video_driver->get_property(xine->video_driver, VO_PROP_VO_TYPE);
-#ifdef LOG_SPU
- printf("dxr3_decode_spu: dxr3 presence test: info = %d\n", info);
-#endif
- if ((info != VO_TYPE_DXR3_LETTERBOXED) && (info != VO_TYPE_DXR3_WIDE))
- return 0;
- }
+ pthread_mutex_lock(&this->pci_lock);
+ memcpy(pci, &this->pci, sizeof(pci_t) );
+ pthread_mutex_unlock(&this->pci_lock);
return 1;
}
-static void dxr3_spudec_event_listener(void *this_gen, xine_event_t *event_gen)
+static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int32_t mode)
{
dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
- xine_spu_event_t *event = (xine_spu_event_t *)event_gen;
+ em8300_button_t btn;
-#if LOG_SPU
- printf("dxr3_decode_spu: event caught: SPU_FD = %i\n",this->fd_spu);
-#endif
-
- switch (event->event.type) {
- case XINE_EVENT_SPU_BUTTON:
- {
- spu_button_t *but = event->data;
- em8300_button_t btn;
#if LOG_BTN
- printf("dxr3_decode_spu: got SPU_BUTTON\n");
+ printf("dxr3_decode_spu: setting button\n");
#endif
- pthread_mutex_lock(&this->pci_lock);
- this->buttonN = but->buttonN;
- if ((but->show > 0) && !this->button_filter &&
- (dxr3_spudec_copy_nav_to_btn(this, but->show - 1, &btn) > 0)) {
- pthread_mutex_lock(&this->dxr3_vo->spu_device_lock);
- if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, &btn))
- printf("dxr3_decode_spu: failed to set spu button (%s)\n",
- strerror(errno));
- pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
- }
- pthread_mutex_unlock(&this->pci_lock);
- if (but->show == 2) this->button_filter = 1;
+ this->buttonN = button;
+ pthread_mutex_lock(&this->pci_lock);
+ if (mode > 0 && !this->button_filter &&
+ (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))
+ printf("dxr3_decode_spu: failed to set spu button (%s)\n",
+ strerror(errno));
+ pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
+ }
+ pthread_mutex_unlock(&this->pci_lock);
+ if (mode == 2) this->button_filter = 1;
#if LOG_BTN
- printf("dxr3_decode_spu: buttonN = %u\n",but->buttonN);
+ printf("dxr3_decode_spu: buttonN = %u\n", this->buttonN);
#endif
+}
+
+
+static 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) {
+ vo_class = (video_driver_class_t *)node->plugin_class;
+ if (vo_class->get_identifier)
+ present = (strcmp(vo_class->get_identifier(vo_class), DXR3_VO_ID) == 0);
}
- break;
-
- case XINE_EVENT_SPU_CLUT:
- {
- spudec_clut_table_t *clut = event->data;
-#if LOG_SPU
- printf("dxr3_decode_spu: got SPU_CLUT\n");
+ }
+#ifdef LOG_SPU
+ printf("dxr3_decode_video: dxr3 %s\n", present ? "present" : "not present");
#endif
-#ifdef WORDS_BIGENDIAN
- dxr3_swab_clut(clut->clut);
+ return present;
+}
+
+static void dxr3_spudec_handle_event(dxr3_spudec_t *this)
+{
+ xine_event_t *event;
+
+ if (!(event = xine_event_get(this->event_queue))) return;
+
+#if LOG_SPU
+ printf("dxr3_decode_spu: event caught: SPU_FD = %i\n",this->fd_spu);
#endif
- pthread_mutex_lock(&this->dxr3_vo->spu_device_lock);
- if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_SETPALETTE, clut->clut))
- printf("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, clut->clut, 16 * sizeof(uint32_t));
- this->dxr3_vo->clut_cluttered = 0;
- pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock);
- }
- break;
- case XINE_EVENT_FRAME_CHANGE:
- this->height = ((xine_frame_change_event_t *)event)->height;
- this->aspect = ((xine_frame_change_event_t *)event)->aspect;
+
+ switch (event->type) {
+ case XINE_EVENT_FRAME_FORMAT_CHANGE:
+ this->height = ((xine_format_change_data_t *)event->data)->height;
+ this->aspect = ((xine_format_change_data_t *)event->data)->aspect;
#if LOG_BTN
printf("dxr3_decode_spu: aspect changed to %d\n", this->aspect);
#endif
break;
}
+
+ xine_event_free(event);
}
static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn)
@@ -552,16 +576,18 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300
if ((this->buttonN <= 0) || (this->buttonN > this->pci.hli.hl_gi.btn_ns)) {
spu_button_t spu_button;
- xine_spu_event_t spu_event;
+ xine_event_t event;
printf("dxr3_decode_spu: Unable to select button number %i as it doesn't exist. Forcing button 1\n",
this->buttonN);
- this->buttonN = 1;
+ this->buttonN = 1;
/* inform nav plugin that we have chosen another button */
- spu_event.event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
- spu_event.data = &spu_button;
- spu_button.buttonN = this->buttonN;
- xine_send_event(this->xine, &spu_event.event);
+ event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
+ event.stream = this->stream;
+ event.data = &spu_button;
+ event.data_length = sizeof(spu_button);
+ spu_button.buttonN = this->buttonN;
+ xine_event_send(this->stream, &event);
}
button_ptr = &this->pci.hli.btnit[this->buttonN - 1];
@@ -577,10 +603,10 @@ 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;
if (this->aspect == XINE_VO_ASPECT_ANAMORPHIC &&
- this->xine->video_driver->get_property(this->xine->video_driver, VO_PROP_VO_TYPE) ==
- VO_TYPE_DXR3_LETTERBOXED && this->xine->spu_channel_user == -1 &&
- this->xine->spu_channel_letterbox != this->xine->spu_channel &&
- this->xine->spu_channel_letterbox >= 0) {
+ !this->dxr3_vo->widescreen_enabled &&
+ this->stream->spu_channel_user == -1 &&
+ this->stream->spu_channel_letterbox != this->stream->spu_channel &&
+ this->stream->spu_channel_letterbox >= 0) {
/* modify button areas for letterboxed anamorphic menus on tv out */
int top_black_bar = this->height / 8;
btn->top = btn->top * 3 / 4 + top_black_bar;
diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c
index b6a037f75..f1c69dc3d 100644
--- a/src/dxr3/dxr3_decode_video.c
+++ b/src/dxr3/dxr3_decode_video.c
@@ -17,7 +17,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: dxr3_decode_video.c,v 1.16 2002/09/18 15:43:34 mroi Exp $
+ * $Id: dxr3_decode_video.c,v 1.17 2002/10/26 14:35:04 mroi Exp $
*/
/* dxr3 video decoder plugin.
@@ -38,6 +38,7 @@
#include "xine_internal.h"
#include "buffer.h"
#include "dxr3_scr.h"
+#include "video_out_dxr3.h"
#include "dxr3.h"
#define LOG_VID 1
@@ -57,7 +58,7 @@
#define HEADER_OFFSET 0
-/* plugin initialization function */
+/* plugin class initialization function */
static void *dxr3_init_plugin(xine_t *xine, void *);
@@ -76,55 +77,65 @@ plugin_info_t xine_plugin_info[] = {
};
-/* functions required by xine api */
-static char *dxr3_get_id(void);
-static void dxr3_init(video_decoder_t *this_gen, vo_instance_t *video_out);
-static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf);
-static void dxr3_flush(video_decoder_t *this_gen);
-static void dxr3_reset(video_decoder_t *this_gen);
-static void dxr3_close(video_decoder_t *this_gen);
-static void dxr3_dispose(video_decoder_t *this_gen);
+/* plugin class functions */
+static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream);
+static char *dxr3_get_identifier(video_decoder_class_t *class_gen);
+static char *dxr3_get_description(video_decoder_class_t *class_gen);
+static void dxr3_class_dispose(video_decoder_class_t *class_gen);
-/* plugin structure */
-typedef struct dxr3_decoder_s {
- video_decoder_t video_decoder;
- vo_instance_t *video_out;
- dxr3_scr_t *scr;
- xine_t *xine;
-
- char devname[128];
- char devnum[3];
- int fd_control;
- int fd_video; /* to access the dxr3 devices */
-
- int have_header_info;
- int width;
- int height;
- int aspect;
- int frame_rate_code;
- int repeat_first_field; /* mpeg stream header data */
-
- int force_aspect; /* when input plugin has better info, we are forced
- * to use a certain aspect */
- int last_width;
- int last_height;
- int last_aspect; /* used to detect changes for event sending */
-
- int sync_every_frame;
- int sync_retry;
- int enhanced_mode;
- int resync_window;
- int skip_count; /* syncing parameters */
-
- int correct_durations;
- int64_t last_vpts;
- int force_duration_window;
- int avg_duration; /* logic to correct broken frame rates */
+/* plugin instance functions */
+static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf);
+static void dxr3_reset(video_decoder_t *this_gen);
+static void dxr3_flush(video_decoder_t *this_gen);
+static void dxr3_dispose(video_decoder_t *this_gen);
+
+/* plugin structures */
+typedef struct dxr3_decoder_class_s {
+ video_decoder_class_t video_decoder_class;
+
+ int instance; /* we allow only one instance of this plugin */
+ char devname[128];
+ char devnum[3];
+} dxr3_decoder_class_t;
+
+typedef struct dxr3_decoder_s {
+ video_decoder_t video_decoder;
+ dxr3_decoder_class_t *class;
+ xine_stream_t *stream;
+ dxr3_scr_t *scr;
+ dxr3_driver_t *dxr3_vo; /* we need to talk to the dxr3 video out */
+
+ int fd_control;
+ int fd_video; /* to access the dxr3 devices */
+
+ int have_header_info;
+ int width;
+ int height;
+ int aspect;
+ int frame_rate_code;
+ int repeat_first_field; /* mpeg stream header data */
+
+ int force_aspect; /* when input plugin has better info, we are forced
+ * to use a certain aspect */
+ int last_width;
+ int last_height;
+ int last_aspect; /* used to detect changes for event sending */
+
+ int sync_every_frame;
+ int sync_retry;
+ int enhanced_mode;
+ int resync_window;
+ int skip_count; /* syncing parameters */
+
+ int correct_durations;
+ int64_t last_vpts;
+ int force_duration_window;
+ int avg_duration; /* logic to correct broken frame rates */
} dxr3_decoder_t;
/* helper functions */
-static int dxr3_present(xine_t *xine);
+static int dxr3_present(xine_stream_t *stream);
static int dxr3_mvcommand(int fd_control, int command);
static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t *buffer);
static int get_duration(dxr3_decoder_t *this);
@@ -137,15 +148,12 @@ static void dxr3_update_correct_durations(void *this_gen, xine_cfg_entry_t
static void *dxr3_init_plugin(xine_t *xine, void *data)
{
- dxr3_decoder_t *this;
+ dxr3_decoder_class_t *this;
config_values_t *cfg;
const char *confstr;
int dashpos;
- int64_t cur_offset;
-
- if (!dxr3_present(xine)) return NULL;
- this = (dxr3_decoder_t *)malloc(sizeof (dxr3_decoder_t));
+ this = (dxr3_decoder_class_t *)malloc(sizeof (dxr3_decoder_class_t));
if (!this) return NULL;
cfg = xine->config;
@@ -163,49 +171,44 @@ static void *dxr3_init_plugin(xine_t *xine, void *data)
this->devnum[0] = '\0';
}
- this->video_decoder.get_identifier = dxr3_get_id;
- this->video_decoder.init = dxr3_init;
- this->video_decoder.decode_data = dxr3_decode_data;
- this->video_decoder.flush = dxr3_flush;
- this->video_decoder.reset = dxr3_reset;
- this->video_decoder.close = dxr3_close;
- this->video_decoder.dispose = dxr3_dispose;
+ this->video_decoder_class.open_plugin = dxr3_open_plugin;
+ this->video_decoder_class.get_identifier = dxr3_get_identifier;
+ this->video_decoder_class.get_description = dxr3_get_description;
+ this->video_decoder_class.dispose = dxr3_class_dispose;
- this->scr = NULL;
- this->xine = xine;
+ this->instance = 0;
- this->sync_every_frame = cfg->register_bool(cfg,
- "dxr3.sync_every_frame", 0, _("Try to sync video every frame"),
- _("This is relevant for progressive video only (most PAL films)."), 20,
- dxr3_update_sync_mode, this);
- this->enhanced_mode = cfg->register_bool(cfg,
- "dxr3.alt_play_mode", 1, _("Use alternate Play mode"),
- _("Enabling this option will utilise a smoother play mode."), 10,
- dxr3_update_enhanced_mode, this);
- this->correct_durations = cfg->register_bool(cfg,
- "dxr3.correct_durations", 0, _("Correct frame durations in broken streams"),
- _("Enable this for streams with wrong frame durations."), 10,
- dxr3_update_correct_durations, this);
-
- /* set a/v offset to compensate dxr3 internal delay */
- cur_offset = this->xine->metronom->get_option(this->xine->metronom, METRONOM_AV_OFFSET);
- this->xine->metronom->set_option(this->xine->metronom, METRONOM_AV_OFFSET, cur_offset - 21600);
-
- return &this->video_decoder;
+ return &this->video_decoder_class;
}
-static char *dxr3_get_id(void)
+static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream)
{
- return "dxr3-mpeg2";
-}
-
-static void dxr3_init(video_decoder_t *this_gen, vo_instance_t *video_out)
-{
- dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen;
+ dxr3_decoder_t *this;
+ dxr3_decoder_class_t *class = (dxr3_decoder_class_t *)class_gen;
+ config_values_t *cfg;
char tmpstr[128];
+ int64_t cur_offset;
+
+ if (class->instance) return NULL;
+ if (!dxr3_present(stream)) return NULL;
- snprintf(tmpstr, sizeof(tmpstr), "%s%s", this->devname, this->devnum);
+ this = (dxr3_decoder_t *)malloc(sizeof (dxr3_decoder_t));
+ if (!this) return NULL;
+
+ cfg = stream->xine->config;
+
+ this->video_decoder.decode_data = dxr3_decode_data;
+ this->video_decoder.reset = dxr3_reset;
+ this->video_decoder.flush = dxr3_flush;
+ this->video_decoder.dispose = dxr3_dispose;
+
+ this->class = class;
+ this->stream = stream;
+ this->scr = NULL;
+ this->dxr3_vo = (dxr3_driver_t *)stream->video_driver;
+
+ snprintf(tmpstr, sizeof(tmpstr), "%s%s", class->devname, class->devnum);
#if LOG_VID
printf("dxr3_decode_video: Entering video init, devname=%s.\n",tmpstr);
#endif
@@ -216,12 +219,10 @@ static void dxr3_init(video_decoder_t *this_gen, vo_instance_t *video_out)
if ((this->fd_control = open(tmpstr, O_WRONLY)) < 0) {
printf("dxr3_decode_video: Failed to open control device %s (%s)\n",
tmpstr, strerror(errno));
- return;
+ free(this);
+ return NULL;
}
- video_out->open(video_out);
- this->video_out = video_out;
-
this->have_header_info = 0;
this->repeat_first_field = 0;
@@ -236,11 +237,51 @@ static void dxr3_init(video_decoder_t *this_gen, vo_instance_t *video_out)
this->skip_count = 0;
this->force_duration_window = -FORCE_DURATION_WINDOW_SIZE;
- this->last_vpts =
- this->xine->metronom->get_current_time(this->xine->metronom);
+ this->last_vpts = this->stream->metronom->get_current_time(this->stream->metronom);
this->avg_duration = 0;
+
+ this->sync_every_frame = cfg->register_bool(cfg,
+ "dxr3.sync_every_frame", 0, _("Try to sync video every frame"),
+ _("This is relevant for progressive video only (most PAL films)."), 20,
+ dxr3_update_sync_mode, this);
+ this->enhanced_mode = cfg->register_bool(cfg,
+ "dxr3.alt_play_mode", 1, _("Use alternate Play mode"),
+ _("Enabling this option will utilise a smoother play mode."), 10,
+ dxr3_update_enhanced_mode, this);
+ this->correct_durations = cfg->register_bool(cfg,
+ "dxr3.correct_durations", 0, _("Correct frame durations in broken streams"),
+ _("Enable this for streams with wrong frame durations."), 10,
+ dxr3_update_correct_durations, this);
+
+ if (!this->dxr3_vo->overlay_enabled) {
+ /* set a/v offset to compensate dxr3 internal delay */
+ cur_offset = this->stream->metronom->get_option(this->stream->metronom, METRONOM_AV_OFFSET);
+ this->stream->metronom->set_option(this->stream->metronom, METRONOM_AV_OFFSET, cur_offset - 21600);
+ }
+
+ stream->video_out->open(stream->video_out);
+
+ class->instance = 1;
+
+ return &this->video_decoder;
+}
+
+static char *dxr3_get_identifier(video_decoder_class_t *class_gen)
+{
+ return "dxr3-mpeg2";
}
+static char *dxr3_get_description(video_decoder_class_t *class_gen)
+{
+ return "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 decoder card.";
+}
+
+static void dxr3_class_dispose(video_decoder_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+
static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
{
dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen;
@@ -262,12 +303,16 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
this->aspect = this->force_aspect = XINE_VO_ASPECT_PAN_SCAN;
/* when aspect changed, we have to send an event for dxr3 spu decoder */
if (!this->last_aspect || this->last_aspect != this->aspect) {
- xine_frame_change_event_t event;
- event.event.type = XINE_EVENT_FRAME_CHANGE;
- event.width = this->last_width;
- event.height = this->last_height;
- event.aspect = this->aspect;
- xine_send_event(this->xine, &event.event);
+ xine_event_t event;
+ xine_format_change_data_t data;
+ event.type = XINE_EVENT_FRAME_FORMAT_CHANGE;
+ event.stream = this->stream;
+ event.data = &data;
+ event.data_length = sizeof(data);
+ data.width = this->last_width;
+ data.height = this->last_height;
+ data.aspect = this->aspect;
+ xine_event_send(this->stream, &event);
this->last_aspect = this->aspect;
}
}
@@ -318,7 +363,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
continue;
/* pretend like we have decoded a frame */
- img = this->video_out->get_frame (this->video_out,
+ img = this->stream->video_out->get_frame(this->stream->video_out,
this->width, this->height, this->aspect,
XINE_IMGFMT_DXR3, VO_BOTH_FIELDS);
img->pts = buf->pts;
@@ -364,7 +409,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
/* we have had enough skipping messages now, let's react */
int64_t vpts_adjust = skip * (int64_t)img->duration / 2;
if (vpts_adjust > 90000) vpts_adjust = 90000;
- this->xine->metronom->set_option(this->xine->metronom,
+ this->stream->metronom->set_option(this->stream->metronom,
METRONOM_ADJ_VPTS_OFFSET, vpts_adjust);
this->skip_count = 0;
this->resync_window = 0;
@@ -408,7 +453,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
*/
if (this->fd_video < 0) {
char tmpstr[128];
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum);
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->class->devname, this->class->devnum);
if ((this->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK)) < 0) {
printf("dxr3_decode_video: Failed to open video device %s (%s)\n",
tmpstr, strerror(errno));
@@ -426,14 +471,13 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
if (!this->scr) {
int64_t time;
- time = this->xine->metronom->get_current_time(
- this->xine->metronom);
+ time = this->stream->metronom->get_current_time(this->stream->metronom);
- this->scr = dxr3_scr_init(this->xine);
+ this->scr = dxr3_scr_init(this->stream);
this->scr->scr_plugin.start(&this->scr->scr_plugin, time);
- this->xine->metronom->register_scr(
- this->xine->metronom, &this->scr->scr_plugin);
- if (this->xine->metronom->scr_master == &this->scr->scr_plugin)
+ this->stream->metronom->register_scr(
+ this->stream->metronom, &this->scr->scr_plugin);
+ if (this->stream->metronom->scr_master == &this->scr->scr_plugin)
#if LOG_VID
printf("dxr3_decode_video: dxr3_scr plugin is master\n");
#endif
@@ -447,8 +491,8 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
if (vpts) {
int64_t delay;
- delay = vpts - this->xine->metronom->get_current_time(
- this->xine->metronom);
+ delay = vpts - this->stream->metronom->get_current_time(
+ this->stream->metronom);
#if LOG_PTS
printf("dxr3_decode_video: SETPTS got %lld\n", vpts);
#endif
@@ -493,6 +537,10 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
written, buf->size);
}
+static void dxr3_reset(video_decoder_t *this_gen)
+{
+}
+
static void dxr3_flush(video_decoder_t *this_gen)
{
dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen;
@@ -500,14 +548,10 @@ static void dxr3_flush(video_decoder_t *this_gen)
if (this->fd_video >= 0) fsync(this->fd_video);
}
-static void dxr3_reset(video_decoder_t *this_gen)
-{
-}
-
-static void dxr3_close(video_decoder_t *this_gen)
+static void dxr3_dispose(video_decoder_t *this_gen)
{
dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen;
- metronom_t *metronom = this->xine->metronom;
+ metronom_t *metronom = this->stream->metronom;
if (this->scr) {
metronom->unregister_scr(metronom, &this->scr->scr_plugin);
@@ -518,30 +562,33 @@ static void dxr3_close(video_decoder_t *this_gen)
if (this->fd_video >= 0) close(this->fd_video);
this->fd_video = -1;
- this->video_out->close(this->video_out);
+ this->stream->video_out->close(this->stream->video_out);
this->have_header_info = 0;
-}
-
-static void dxr3_dispose(video_decoder_t *this_gen)
-{
- free(this_gen);
+ this->class->instance = 0;
+
+ free(this);
}
-static int dxr3_present(xine_t *xine)
+static int dxr3_present(xine_stream_t *stream)
{
- int info;
-
- if (xine && xine->video_driver) {
- info = xine->video_driver->get_property(xine->video_driver, VO_PROP_VO_TYPE);
+ 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) {
+ vo_class = (video_driver_class_t *)node->plugin_class;
+ if (vo_class->get_identifier)
+ present = (strcmp(vo_class->get_identifier(vo_class), DXR3_VO_ID) == 0);
+ }
+ }
#ifdef LOG_VID
- printf("dxr3_decode_video: dxr3 presence test: info = %d\n", info);
+ printf("dxr3_decode_video: dxr3 %s\n", present ? "present" : "not present");
#endif
- if ((info != VO_TYPE_DXR3_LETTERBOXED) && (info != VO_TYPE_DXR3_WIDE))
- return 0;
- }
- return 1;
+ return present;
}
static int dxr3_mvcommand(int fd_control, int command)
@@ -575,32 +622,36 @@ static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t * buffer)
(this->last_width != this->width) ||
(this->last_height != this->height) ||
(this->last_aspect != this->aspect)) {
- xine_frame_change_event_t event;
- event.event.type = XINE_EVENT_FRAME_CHANGE;
- event.width = this->width;
- event.height = this->height;
- event.aspect = this->aspect;
- xine_send_event(this->xine, &event.event);
+ xine_event_t event;
+ xine_format_change_data_t data;
+ event.type = XINE_EVENT_FRAME_FORMAT_CHANGE;
+ event.stream = this->stream;
+ event.data = &data;
+ event.data_length = sizeof(data);
+ data.width = this->width;
+ data.height = this->height;
+ data.aspect = this->aspect;
+ xine_event_send(this->stream, &event);
this->last_width = this->width;
this->last_height = this->height;
this->last_aspect = this->aspect;
/* update stream metadata */
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
switch (this->aspect) {
case XINE_VO_ASPECT_SQUARE:
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000;
break;
case XINE_VO_ASPECT_4_3:
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 4.0 / 3.0;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 4.0 / 3.0;
break;
case XINE_VO_ASPECT_PAN_SCAN:
case XINE_VO_ASPECT_ANAMORPHIC:
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 16.0 / 9.0;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 16.0 / 9.0;
break;
case XINE_VO_ASPECT_DVB:
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 2.11;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_RATIO] = 10000 * 2.11;
break;
}
}
@@ -643,7 +694,7 @@ static int get_duration(dxr3_decoder_t *this)
}
/* update stream metadata */
- this->xine->stream_info[XINE_STREAM_INFO_FRAME_DURATION] = duration;
+ this->stream->stream_info[XINE_STREAM_INFO_FRAME_DURATION] = duration;
if (this->correct_durations) {
/* we set an initial average frame duration here */
@@ -656,13 +707,13 @@ static int get_duration(dxr3_decoder_t *this)
*/
if (this->avg_duration && this->avg_duration < 3300 && duration == 3600) {
if (this->force_duration_window > 0) {
- // we are already in a force_duration window, so we force duration
+ /* we are already in a force_duration window, so we force duration */
this->force_duration_window = FORCE_DURATION_WINDOW_SIZE;
return 3000;
}
if (this->force_duration_window <= 0 && (this->force_duration_window += 10) > 0) {
- // we just entered a force_duration window, so we start the correction
- metronom_t *metronom = this->xine->metronom;
+ /* we just entered a force_duration window, so we start the correction */
+ metronom_t *metronom = this->stream->metronom;
int64_t cur_offset;
printf("dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n");
/* those weird streams need an offset, too */
@@ -674,11 +725,11 @@ static int get_duration(dxr3_decoder_t *this)
}
if (this->force_duration_window == -FORCE_DURATION_WINDOW_SIZE)
- // we are far from a force_duration window
+ /* we are far from a force_duration window */
return duration;
if (--this->force_duration_window == 0) {
- // we have just left a force_duration window
- metronom_t *metronom = this->xine->metronom;
+ /* we have just left a force_duration window */
+ metronom_t *metronom = this->stream->metronom;
int64_t cur_offset;
cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET);
metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset + 28800);
diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c
index e661753b1..00a1dc2dc 100644
--- a/src/dxr3/dxr3_mpeg_encoders.c
+++ b/src/dxr3/dxr3_mpeg_encoders.c
@@ -17,7 +17,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: dxr3_mpeg_encoders.c,v 1.9 2002/09/05 12:52:24 mroi Exp $
+ * $Id: dxr3_mpeg_encoders.c,v 1.10 2002/10/26 14:35:04 mroi Exp $
*/
/* mpeg encoders for the dxr3 video out plugin.
@@ -177,7 +177,7 @@ static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
return 0;
}
- this->rte_bitrate = drv->xine->config->register_range(drv->xine->config,
+ this->rte_bitrate = drv->class->xine->config->register_range(drv->class->xine->config,
"dxr3.rte_bitrate", 10000, 1000, 20000,
_("Dxr3enc: rte mpeg output bitrate (kbit/s)"),
_("The bitrate the mpeg encoder library librte should use for dxr3's encoding mode"), 10,
@@ -295,7 +295,7 @@ static void mp1e_callback(rte_context *context, void *data, ssize_t size, void *
ssize_t written;
if (drv->fd_video == CLOSED_FOR_ENCODER) {
- snprintf(tmpstr, sizeof(tmpstr), "%s_mv%s", drv->devname, drv->devnum);
+ snprintf(tmpstr, sizeof(tmpstr), "%s_mv%s", drv->class->devname, drv->class->devnum);
drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
}
if (drv->fd_video < 0) return;
@@ -346,7 +346,7 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
/* if YUY2 and dimensions changed, we need to re-allocate the
* internal YV12 buffer */
if (frame->vo_frame.format == XINE_IMGFMT_YUY2) {
- int image_size = drv->video_width * drv->video_oheight;
+ int image_size = frame->vo_frame.width * frame->oheight;
this->out[0] = xine_xmalloc_aligned(16, image_size * 3/2,
(void *)&this->buf);
@@ -384,7 +384,7 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
}
this->fp = init_fp;
- this->fp.quality = drv->xine->config->register_range(drv->xine->config,
+ this->fp.quality = drv->class->xine->config->register_range(drv->class->xine->config,
"dxr3.fame_quality", 90, 10, 100,
_("Dxr3enc: fame mpeg encoding quality"),
_("The encoding quality of the libfame mpeg encoder library."), 10,
@@ -396,8 +396,8 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
printf("dxr3_mpeg_encoder: quality %d -> quant scale = %d\n", this->fp.quality,
1 + (30 * (100 - this->fp.quality) + 50) / 100);
#endif
- this->fp.width = drv->video_width;
- this->fp.height = drv->video_oheight;
+ this->fp.width = frame->vo_frame.width;
+ this->fp.height = frame->oheight;
this->fp.profile = "mpeg1";
this->fp.coding = "I";
#if LOG_ENC
@@ -484,7 +484,7 @@ static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame)
frame->vo_frame.displayed(&frame->vo_frame);
if (drv->fd_video == CLOSED_FOR_ENCODER) {
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->devname, drv->devnum);
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->class->devname, drv->class->devnum);
drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
}
if (drv->fd_video < 0) return 0;
diff --git a/src/dxr3/dxr3_scr.c b/src/dxr3/dxr3_scr.c
index e78d0ae54..95cc41105 100644
--- a/src/dxr3/dxr3_scr.c
+++ b/src/dxr3/dxr3_scr.c
@@ -17,7 +17,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: dxr3_scr.c,v 1.5 2002/09/05 12:52:24 mroi Exp $
+ * $Id: dxr3_scr.c,v 1.6 2002/10/26 14:35:04 mroi Exp $
*/
/* dxr3 scr plugin.
@@ -31,7 +31,6 @@
#include <unistd.h>
#include <errno.h>
-#include "xineutils.h"
#include "dxr3.h"
#include "dxr3_scr.h"
@@ -53,14 +52,14 @@ static int dxr3_mvcommand(int fd_control, int command);
static void dxr3_scr_update_priority(void *this_gen, xine_cfg_entry_t *entry);
-dxr3_scr_t *dxr3_scr_init(xine_t *xine)
+dxr3_scr_t *dxr3_scr_init(xine_stream_t *stream)
{
dxr3_scr_t *this;
const char *confstr;
this = (dxr3_scr_t *)malloc(sizeof(dxr3_scr_t));
- confstr = xine->config->register_string(xine->config,
+ confstr = stream->xine->config->register_string(stream->xine->config,
CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, 0, NULL, NULL);
if ((this->fd_control = open(confstr, O_WRONLY)) < 0) {
printf("dxr3_scr: Failed to open control device %s (%s)\n",
@@ -77,8 +76,8 @@ dxr3_scr_t *dxr3_scr_init(xine_t *xine)
this->scr_plugin.set_speed = dxr3_scr_set_speed;
this->scr_plugin.exit = dxr3_scr_exit;
- this->priority = xine->config->register_num(
- xine->config, "dxr3.scr_priority", 10, _("Dxr3: SCR plugin priority"),
+ this->priority = stream->xine->config->register_num(
+ stream->xine->config, "dxr3.scr_priority", 10, _("Dxr3: SCR plugin priority"),
_("Scr priorities greater 5 make the dxr3 xine's master clock."), 20,
dxr3_scr_update_priority, this);
this->offset = 0;
@@ -132,6 +131,8 @@ static int64_t dxr3_scr_get_current(scr_plugin_t *scr)
if (this->last_pts > 0xF0000000 && pts < 0x10000000)
/* wrap around detected, compensate with offset */
this->offset += (int64_t)1 << 33;
+ if (pts == 0)
+ printf("dxr3_scr: WARNING: pts dropped to zero.\n");
this->last_pts = pts;
current = ((int64_t)pts << 1) + this->offset;
pthread_mutex_unlock(&this->mutex);
diff --git a/src/dxr3/dxr3_scr.h b/src/dxr3/dxr3_scr.h
index 8260ce3f0..c038feb90 100644
--- a/src/dxr3/dxr3_scr.h
+++ b/src/dxr3/dxr3_scr.h
@@ -17,7 +17,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: dxr3_scr.h,v 1.2 2002/05/24 22:09:44 miguelfreitas Exp $
+ * $Id: dxr3_scr.h,v 1.3 2002/10/26 14:35:05 mroi Exp $
*/
#include "xine_internal.h"
@@ -37,4 +37,4 @@ typedef struct dxr3_scr_s {
} dxr3_scr_t;
/* plugin initialization function */
-dxr3_scr_t *dxr3_scr_init(xine_t *xine);
+dxr3_scr_t *dxr3_scr_init(xine_stream_t *stream);
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
index 9da93591b..df330b7cc 100644
--- a/src/dxr3/video_out_dxr3.c
+++ b/src/dxr3/video_out_dxr3.c
@@ -17,7 +17,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: video_out_dxr3.c,v 1.57 2002/10/11 10:55:27 mroi Exp $
+ * $Id: video_out_dxr3.c,v 1.58 2002/10/26 14:35:05 mroi Exp $
*/
/* mpeg1 encoding video out plugin for the dxr3.
@@ -63,14 +63,13 @@
#define LOG_OVR 0
-/* plugin initialization function */
+/* plugin class initialization function */
static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen);
/* plugin catalog information */
static vo_info_t vo_info_dxr3 = {
10, /* priority */
- "dxr3", /* description */
XINE_VISUAL_TYPE_X11 /* visual type */
};
@@ -81,7 +80,13 @@ plugin_info_t xine_plugin_info[] = {
};
-/* functions required by xine api */
+/* plugin class functions */
+static xine_vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const void *visual);
+static char *dxr3_vo_get_identifier(video_driver_class_t *class_gen);
+static char *dxr3_vo_get_description(video_driver_class_t *class_gen);
+static void dxr3_vo_class_dispose(video_driver_class_t *class_gen);
+
+/* plugin instance functions */
static uint32_t dxr3_get_capabilities(xine_vo_driver_t *this_gen);
static vo_frame_t *dxr3_alloc_frame(xine_vo_driver_t *this_gen);
static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src);
@@ -102,10 +107,10 @@ static void dxr3_get_property_min_max(xine_vo_driver_t *this_gen, int pro
int *min, int *max);
static int dxr3_gui_data_exchange(xine_vo_driver_t *this_gen,
int data_type, void *data);
-static void dxr3_exit(xine_vo_driver_t *this_gen);
+static void dxr3_dispose(xine_vo_driver_t *this_gen);
/* overlay helper functions only called once during plugin init */
-static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis);
+static void gather_screen_vars(dxr3_driver_t *this, const x11_visual_t *vis);
static int dxr3_overlay_read_state(dxr3_overlay_t *this);
static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this);
static int dxr3_overlay_set_attributes(dxr3_overlay_t *this);
@@ -113,9 +118,6 @@ static int dxr3_overlay_set_attributes(dxr3_overlay_t *this);
/* overlay helper functions */
static void dxr3_overlay_update(dxr3_driver_t *this);
static void dxr3_zoomTV(dxr3_driver_t *this);
-static void dxr3_translate_gui2video(dxr3_driver_t *this, int x, int y,
- int *vid_x, int *vid_y);
-static int is_fullscreen(dxr3_driver_t *this);
/* config callbacks */
static void dxr3_update_add_bars(void *data, xine_cfg_entry_t *entry);
@@ -125,18 +127,75 @@ static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *e
static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
{
+ dxr3_driver_class_t *this;
+ const char *confstr;
+ int dashpos;
+
+ this = (dxr3_driver_class_t *)malloc(sizeof(dxr3_driver_class_t));
+ if (!this) return NULL;
+
+ confstr = xine->config->register_string(xine->config,
+ CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, 0, NULL, NULL);
+ strncpy(this->devname, confstr, 128);
+ this->devname[127] = '\0';
+ dashpos = strlen(this->devname) - 2; /* the dash in the new device naming scheme would be here */
+ if (this->devname[dashpos] == '-') {
+ /* use new device naming scheme with trailing number */
+ strncpy(this->devnum, &this->devname[dashpos], 3);
+ this->devname[dashpos] = '\0';
+ } else {
+ /* use old device naming scheme without trailing number */
+ /* FIXME: remove this when everyone uses em8300 >=0.12.0 */
+ this->devnum[0] = '\0';
+ }
+
+ this->video_driver_class.open_plugin = dxr3_vo_open_plugin;
+ this->video_driver_class.get_identifier = dxr3_vo_get_identifier;
+ this->video_driver_class.get_description = dxr3_vo_get_description;
+ this->video_driver_class.dispose = dxr3_vo_class_dispose;
+
+ this->xine = xine;
+
+ this->instance = 0;
+
+ return &this->video_driver_class;
+}
+
+static char *dxr3_vo_get_identifier(video_driver_class_t *class_gen)
+{
+ return DXR3_VO_ID;
+}
+
+static char *dxr3_vo_get_description(video_driver_class_t *class_gen)
+{
+ return "video output plugin displaying images through your DXR3 decoder card";
+}
+
+static void dxr3_vo_class_dispose(video_driver_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+
+static xine_vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const void *visual_gen)
+{
dxr3_driver_t *this;
+ dxr3_driver_class_t *class = (dxr3_driver_class_t *)class_gen;
+ config_values_t *config = class->xine->config;
char tmpstr[100];
const char *confstr;
- int dashpos, encoder, confnum;
+ int encoder, confnum;
static char *available_encoders[SUPPORTED_ENCODER_COUNT + 2];
#ifdef HAVE_X11
- static char *videoout_modes[] = { "letterboxed tv", "widescreen tv", "overlay", NULL };
+ static char *videoout_modes[] = { "letterboxed tv", "widescreen tv",
+ "letterboxed overlay", "widescreen overlay", NULL };
#else
static char *videoout_modes[] = { "letterboxed tv", "widescreen tv", NULL };
#endif
static char *tv_modes[] = { "ntsc", "pal", "pal60" , "default", NULL };
+ if (class->instance) return NULL;
+
this = (dxr3_driver_t *)malloc(sizeof(dxr3_driver_t));
if (!this) return NULL;
memset(this, 0, sizeof(dxr3_driver_t));
@@ -153,40 +212,27 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
this->vo_driver.set_property = dxr3_set_property;
this->vo_driver.get_property_min_max = dxr3_get_property_min_max;
this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange;
- this->vo_driver.exit = dxr3_exit;
+ this->vo_driver.dispose = dxr3_dispose;
pthread_mutex_init(&this->spu_device_lock, NULL);
- this->xine = xine;
- this->swap_fields = xine->config->register_bool(xine->config,
+ vo_scale_init(&this->scale, 0, 0);
+
+ this->class = class;
+ this->swap_fields = config->register_bool(config,
"dxr3.enc_swap_fields", 0, _("swap odd and even lines"), NULL, 10,
dxr3_update_swap_fields, this);
- this->add_bars = xine->config->register_bool(xine->config,
+ this->add_bars = config->register_bool(config,
"dxr3.enc_add_bars", 1, _("Add black bars to correct aspect ratio"),
_("If disabled, will assume source has 4:3 aspect ratio."), 10,
dxr3_update_add_bars, this);
- this->enhanced_mode = xine->config->register_bool(xine->config,
+ this->enhanced_mode = config->register_bool(config,
"dxr3.enc_alt_play_mode", 1,
_("dxr3: use alternate play mode for mpeg encoder playback"),
_("Enabling this option will utilise a smoother play mode."), 10,
dxr3_update_enhanced_mode, this);
- confstr = xine->config->register_string(xine->config,
- CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, 0, NULL, NULL);
- strncpy(this->devname, confstr, 128);
- this->devname[127] = '\0';
- dashpos = strlen(this->devname) - 2; /* the dash in the new device naming scheme would be here */
- if (this->devname[dashpos] == '-') {
- /* use new device naming scheme with trailing number */
- strncpy(this->devnum, &this->devname[dashpos], 3);
- this->devname[dashpos] = '\0';
- } else {
- /* use old device naming scheme without trailing number */
- /* FIXME: remove this when everyone uses em8300 >=0.12.0 */
- this->devnum[0] = '\0';
- }
-
- snprintf(tmpstr, sizeof(tmpstr), "%s%s", this->devname, this->devnum);
+ snprintf(tmpstr, sizeof(tmpstr), "%s%s", class->devname, class->devnum);
#if LOG_VID
printf("video_out_dxr3: Entering video init, devname = %s.\n", tmpstr);
#endif
@@ -196,7 +242,7 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
return 0;
}
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum);
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", class->devname, class->devnum);
if ((this->fd_video = open (tmpstr, O_WRONLY | O_SYNC )) < 0) {
printf("video_out_dxr3: Failed to open video device %s (%s)\n",
tmpstr, strerror(errno));
@@ -229,8 +275,8 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
printf("none\n");
#endif
if (encoder) {
- encoder = xine->config->register_enum(xine->config, "dxr3.encoder",
- 0, available_encoders, _("the encoder for non mpeg content"),
+ encoder = config->register_enum(config, "dxr3.encoder", 0,
+ available_encoders, _("the encoder for non mpeg content"),
_("Content other than mpeg has to pass an additional reencoding stage, "
"because the dxr3 handles mpeg only."), 10, NULL, NULL);
#ifdef HAVE_LIBRTE
@@ -258,17 +304,21 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
/* init bcs */
if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs))
- printf("video_out_dxr3: cannot read bcs values (%s)\n",
- strerror(errno));
- this->bcs.contrast = xine->config->register_range(xine->config, "dxr3.contrast",
+ printf("video_out_dxr3: cannot read bcs values (%s)\n", strerror(errno));
+ this->bcs.contrast = config->register_range(config, "dxr3.contrast",
this->bcs.contrast, 100, 900, _("Dxr3: contrast control"), NULL, 0, NULL, NULL);
- this->bcs.saturation = xine->config->register_range(xine->config, "dxr3.saturation",
+ this->bcs.saturation = config->register_range(config, "dxr3.saturation",
this->bcs.saturation, 100, 900, _("Dxr3: saturation control"), NULL, 0, NULL, NULL);
- this->bcs.brightness = xine->config->register_range(xine->config, "dxr3.brightness",
+ this->bcs.brightness = config->register_range(config, "dxr3.brightness",
this->bcs.brightness, 100, 900, _("Dxr3: brightness control"), NULL, 0, NULL, NULL);
-
+ if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs))
+ printf("video_out_dxr3: cannot set bcs values (%s)\n", strerror(errno));
+
+ /* init aspect */
+ dxr3_set_property(&this->vo_driver, VO_PROP_ASPECT_RATIO, ASPECT_FULL);
+
/* overlay or tvout? */
- confnum = xine->config->register_enum(xine->config, "dxr3.videoout_mode", 0, videoout_modes,
+ confnum = config->register_enum(config, "dxr3.videoout_mode", 0, videoout_modes,
_("Dxr3: videoout mode (tv or overlay)"), NULL, 0, NULL, NULL);
#if LOG_VID
printf("video_out_dxr3: overlaymode = %s\n", videoout_modes[confnum]);
@@ -282,12 +332,11 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
case 1: /* widescreen tv mode */
this->overlay_enabled = 0;
this->tv_switchable = 0; /* don't allow on-the-fly switching */
- /* switch to fullscreen mode for ever, let the tv set do the anamorphic unsqueezing */
- dxr3_set_property(&this->vo_driver, VO_PROP_ASPECT_RATIO, ASPECT_FULL);
this->widescreen_enabled = 1;
break;
#ifdef HAVE_X11
- case 2: /* overlay mode */
+ case 2: /* letterboxed overlay mode */
+ case 3: /* widescreen overlay mode */
#if LOG_VID
printf("video_out_dxr3: setting up overlay mode\n");
#endif
@@ -295,11 +344,11 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
if (dxr3_overlay_read_state(&this->overlay) == 0) {
this->overlay_enabled = 1;
this->tv_switchable = 1;
- this->widescreen_enabled = 0;
- confstr = xine->config->register_string(xine->config, "dxr3.keycolor", "0x80a040",
+ this->widescreen_enabled = confnum - 2;
+ confstr = config->register_string(config, "dxr3.keycolor", "0x80a040",
_("Dxr3: overlay colorkey value"), NULL, 10, NULL, NULL);
sscanf(confstr, "%x", &this->overlay.colorkey);
- confstr = xine->config->register_string(xine->config, "dxr3.color_interval", "50.0",
+ confstr = config->register_string(config, "dxr3.color_interval", "50.0",
_("Dxr3: overlay colorkey range"),
_("A greater value widens the tolerance for the overlay keycolor"), 10, NULL, NULL);
sscanf(confstr, "%f", &this->overlay.color_interval);
@@ -313,7 +362,7 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
}
/* init tvmode */
- confnum = xine->config->register_enum(xine->config, "dxr3.preferred_tvmode", 3, tv_modes,
+ confnum = config->register_enum(config, "dxr3.preferred_tvmode", 3, tv_modes,
_("dxr3 preferred tv mode"), NULL, 0, NULL, NULL);
switch (confnum) {
case 0: /* ntsc */
@@ -346,14 +395,19 @@ static void *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
if (this->overlay_enabled) {
em8300_overlay_screen_t scr;
int value;
+ XColor dummy;
this->overlay.fd_control = this->fd_control;
/* allocate keycolor */
- this->color.red = ((this->overlay.colorkey >> 16) & 0xff) * 256;
- this->color.green = ((this->overlay.colorkey >> 8) & 0xff) * 256;
- this->color.blue = ((this->overlay.colorkey ) & 0xff) * 256;
- XAllocColor(this->display, DefaultColormap(this->display, 0), &this->color);
+ this->key.red = ((this->overlay.colorkey >> 16) & 0xff) * 256;
+ this->key.green = ((this->overlay.colorkey >> 8) & 0xff) * 256;
+ this->key.blue = ((this->overlay.colorkey ) & 0xff) * 256;
+ XAllocColor(this->display, DefaultColormap(this->display, 0), &this->key);
+
+ /* allocate black for output area borders */
+ XAllocNamedColor(this->display, DefaultColormap(this->display, 0),
+ "black", &this->black, &dummy);
/* set the screen */
scr.xsize = this->overlay.screen_xres;
@@ -434,9 +488,6 @@ static void dxr3_update_frame_format(xine_vo_driver_t *this_gen, vo_frame_t *fra
dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
int oheight;
- /* update the overlay window co-ords if required */
- dxr3_overlay_update(this);
-
if (format == XINE_IMGFMT_DXR3) { /* talking to dxr3 decoder */
/* a bit of a hack. we must release the em8300_mv fd for
* the dxr3 decoder plugin */
@@ -459,7 +510,6 @@ static void dxr3_update_frame_format(xine_vo_driver_t *this_gen, vo_frame_t *fra
frame->vo_frame.height = height;
frame->vo_frame.ratio = ratio_code;
frame->oheight = height;
- frame->pan_scan = (ratio_code == XINE_VO_ASPECT_PAN_SCAN);
frame->aspect = 0;
if (frame->mem) {
@@ -481,7 +531,7 @@ static void dxr3_update_frame_format(xine_vo_driver_t *this_gen, vo_frame_t *fra
if (this->fd_video == CLOSED_FOR_DECODER) { /* decoder should have released it */
this->fd_video = CLOSED_FOR_ENCODER; /* allow encoder to reopen it */
- this->need_redraw = 1;
+ this->scale.force_redraw = 1;
}
if (this->add_bars == 0) {
@@ -502,6 +552,10 @@ static void dxr3_update_frame_format(xine_vo_driver_t *this_gen, vo_frame_t *fra
frame->aspect = ASPECT_ANAMORPHIC;
oheight = height;
break;
+ case XINE_VO_ASPECT_DVB:
+ frame->aspect = ASPECT_ANAMORPHIC;
+ oheight = height * 2.11 * 9.0 / 16.0;
+ break;
default: /* assume square pixel */
frame->aspect = ASPECT_ANAMORPHIC;
oheight = (int)(width * 9./16.);
@@ -520,12 +574,12 @@ static void dxr3_update_frame_format(xine_vo_driver_t *this_gen, vo_frame_t *fra
printf("video_out_dxr3: adding %d black lines to get %s aspect ratio.\n",
oheight - height, frame->aspect == ASPECT_FULL ? "4:3" : "16:9");
- this->video_width = width;
- this->video_iheight = height;
- this->video_oheight = oheight;
- this->video_ratio = ratio_code;
- this->need_redraw = 1;
- this->need_update = 1;
+ this->video_width = width;
+ this->video_iheight = height;
+ this->video_oheight = oheight;
+ this->video_ratio = ratio_code;
+ this->scale.force_redraw = 1;
+ this->need_update = 1;
if (!this->enc) {
/* no encoder plugin! Let's bug the user! */
@@ -669,7 +723,7 @@ static void dxr3_overlay_end(xine_vo_driver_t *this_gen, vo_frame_t *frame_gen)
/* try to open the dxr3 spu device */
if (!this->fd_spu) {
- snprintf (tmpstr, sizeof(tmpstr), "%s_sp%s", this->devname, this->devnum);
+ snprintf (tmpstr, sizeof(tmpstr), "%s_sp%s", this->class->devname, this->class->devnum);
if ((this->fd_spu = open (tmpstr, O_WRONLY)) < 0) {
printf("video_out_dxr3: Failed to open spu device %s (%s)\n",
tmpstr, strerror(errno));
@@ -750,8 +804,9 @@ static void dxr3_display_frame(xine_vo_driver_t *this_gen, vo_frame_t *frame_gen
frame->aspect = ASPECT_ANAMORPHIC;
}
}
- if (frame->aspect != this->aspect)
- dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, frame->aspect);
+ if ((this->widescreen_enabled ? ASPECT_FULL : frame->aspect) != this->aspect)
+ dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO,
+ (this->widescreen_enabled ? ASPECT_FULL : frame->aspect));
if (frame->pan_scan && !this->pan_scan) {
dxr3_set_property(this_gen, VO_PROP_ZOOM_X, 1);
this->pan_scan = 1;
@@ -761,6 +816,26 @@ static void dxr3_display_frame(xine_vo_driver_t *this_gen, vo_frame_t *frame_gen
dxr3_set_property(this_gen, VO_PROP_ZOOM_X, -1);
}
+ if (this->overlay_enabled) {
+ if (this->scale.force_redraw ||
+ this->scale.delivered_width != frame_gen->width ||
+ this->scale.delivered_height != frame->oheight ||
+ this->scale.delivered_ratio_code != frame_gen->ratio ||
+ this->scale.user_ratio != (this->widescreen_enabled ? frame->aspect : ASPECT_FULL)) {
+
+ this->scale.delivered_width = frame_gen->width;
+ this->scale.delivered_height = frame->oheight;
+ this->scale.delivered_ratio_code = frame_gen->ratio;
+ this->scale.user_ratio = (this->widescreen_enabled ? frame->aspect : ASPECT_FULL);
+ this->scale.force_redraw = 1;
+
+ vo_scale_compute_ideal_size(&this->scale);
+
+ /* prepare the overlay window */
+ dxr3_overlay_update(this);
+ }
+ }
+
if (frame_gen->format != XINE_IMGFMT_DXR3 && this->enc && this->enc->on_display_frame) {
if (this->need_update) {
/* we cannot do this earlier, because vo_frame.duration is only valid here */
@@ -780,7 +855,9 @@ static int dxr3_redraw_needed(xine_vo_driver_t *this_gen)
{
dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
- dxr3_overlay_update(this);
+ if (this->overlay_enabled)
+ dxr3_overlay_update(this);
+
return 0;
}
@@ -803,10 +880,6 @@ static int dxr3_get_property(xine_vo_driver_t *this_gen, int property)
case VO_PROP_ZOOM_Y:
case VO_PROP_TVMODE:
return 0;
- case VO_PROP_VO_TYPE:
- if (this->overlay_enabled && is_fullscreen(this)) return VO_TYPE_DXR3_LETTERBOXED;
- if (this->overlay_enabled || this->widescreen_enabled) return VO_TYPE_DXR3_WIDE;
- return VO_TYPE_DXR3_LETTERBOXED;
}
printf("video_out_dxr3: property %d not implemented.\n", property);
return 0;
@@ -816,7 +889,6 @@ static int dxr3_set_property(xine_vo_driver_t *this_gen, int property, int value
{
dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
int val, bcs_changed = 0;
- int fullscreen;
switch (property) {
case VO_PROP_SATURATION:
@@ -842,17 +914,12 @@ static int dxr3_set_property(xine_vo_driver_t *this_gen, int property, int value
* can switch to 16:9 mode. I don't know if the dxr3 can do this. */
break;
}
- fullscreen = this->overlay_enabled ? is_fullscreen(this) : 0;
if (value == ASPECT_ANAMORPHIC) {
#if LOG_VID
printf("video_out_dxr3: setting aspect ratio to anamorphic\n");
#endif
- if (!this->overlay_enabled || fullscreen)
- /* FIXME: Is it necessary to switch to anamorphic mode in fullscreen? */
- val = EM8300_ASPECTRATIO_16_9;
- else /* The overlay window can adapt to the ratio */
- val = EM8300_ASPECTRATIO_4_3;
+ val = EM8300_ASPECTRATIO_16_9;
} else {
#if LOG_VID
printf("video_out_dxr3: setting aspect ratio to full\n");
@@ -863,7 +930,7 @@ static int dxr3_set_property(xine_vo_driver_t *this_gen, int property, int value
if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
printf("video_out_dxr3: failed to set aspect ratio (%s)\n", strerror(errno));
- dxr3_overlay_update(this);
+ this->scale.force_redraw = 1;
break;
case VO_PROP_COLORKEY:
printf("video_out_dxr3: VO_PROP_COLORKEY not implemented!");
@@ -908,9 +975,9 @@ static int dxr3_set_property(xine_vo_driver_t *this_gen, int property, int value
if (bcs_changed) {
if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs))
printf("video_out_dxr3: bcs set failed (%s)\n", strerror(errno));
- this->xine->config->update_num(this->xine->config, "dxr3.contrast", this->bcs.contrast);
- this->xine->config->update_num(this->xine->config, "dxr3.saturation", this->bcs.saturation);
- this->xine->config->update_num(this->xine->config, "dxr3.brightness", this->bcs.brightness);
+ this->class->xine->config->update_num(this->class->xine->config, "dxr3.contrast", this->bcs.contrast);
+ this->class->xine->config->update_num(this->class->xine->config, "dxr3.saturation", this->bcs.saturation);
+ this->class->xine->config->update_num(this->class->xine->config, "dxr3.brightness", this->bcs.brightness);
}
return value;
@@ -941,8 +1008,7 @@ static int dxr3_gui_data_exchange(xine_vo_driver_t *this_gen, int data_type, voi
switch (data_type) {
case XINE_GUI_SEND_EXPOSE_EVENT:
- this->need_redraw = 1;
- dxr3_overlay_update(this);
+ this->scale.force_redraw = 1;
break;
case XINE_GUI_SEND_DRAWABLE_CHANGED:
this->win = (Drawable)data;
@@ -954,10 +1020,10 @@ static int dxr3_gui_data_exchange(xine_vo_driver_t *this_gen, int data_type, voi
{
int x1, y1, x2, y2;
x11_rectangle_t *rect = data;
- dxr3_translate_gui2video(this, rect->x, rect->y, &x1, &y1);
- dxr3_translate_gui2video(this, rect->w, rect->h, &x2, &y2);
+ vo_scale_translate_gui2video(&this->scale, rect->x, rect->y, &x1, &y1);
+ vo_scale_translate_gui2video(&this->scale, rect->x + rect->w, rect->y + rect->h, &x2, &y2);
rect->x = x1;
- rect->y = y1;
+ rect->y = y1 - this->top_bar;
rect->w = x2 - x1;
rect->h = y2 - y1;
}
@@ -978,7 +1044,7 @@ static int dxr3_gui_data_exchange(xine_vo_driver_t *this_gen, int data_type, voi
#endif
val = EM8300_OVERLAY_MODE_OVERLAY;
this->overlay_enabled = 1;
- this->need_redraw = 1;
+ this->scale.force_redraw = 1;
}
ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val);
dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect);
@@ -991,7 +1057,7 @@ static int dxr3_gui_data_exchange(xine_vo_driver_t *this_gen, int data_type, voi
return 0;
}
-static void dxr3_exit(xine_vo_driver_t *this_gen)
+static void dxr3_dispose(xine_vo_driver_t *this_gen)
{
dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
int val = EM8300_OVERLAY_MODE_OFF;
@@ -1011,7 +1077,7 @@ static void dxr3_exit(xine_vo_driver_t *this_gen)
#ifdef HAVE_X11
-static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis)
+static void gather_screen_vars(dxr3_driver_t *this, const x11_visual_t *vis)
{
int scrn;
#ifdef HAVE_XINERAMA
@@ -1020,11 +1086,11 @@ static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis)
XineramaScreenInfo *screeninfo = NULL;
#endif
- this->win = vis->d;
- this->display = vis->display;
- this->user_data = vis->user_data;
- this->gc = XCreateGC(this->display, this->win, 0, NULL);
- scrn = DefaultScreen(this->display);
+ this->win = vis->d;
+ this->display = vis->display;
+ this->scale.user_data = vis->user_data;
+ this->gc = XCreateGC(this->display, this->win, 0, NULL);
+ scrn = DefaultScreen(this->display);
#ifdef HAVE_XINERAMA
if (XineramaQueryExtension(this->display, &dummy_a, &dummy_b) &&
@@ -1039,8 +1105,8 @@ static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis)
this->overlay.screen_yres = DisplayHeight(this->display, scrn);
}
- this->overlay.screen_depth = DisplayPlanes(this->display, scrn);
- this->frame_output_cb = (void *)vis->frame_output_cb;
+ this->overlay.screen_depth = DisplayPlanes(this->display, scrn);
+ this->scale.frame_output_cb = (void *)vis->frame_output_cb;
#if LOG_OVR
printf("video_out_dxr3: xres: %d, yres: %d, depth: %d\n",
@@ -1254,58 +1320,36 @@ static int dxr3_overlay_set_attributes(dxr3_overlay_t *this)
static void dxr3_overlay_update(dxr3_driver_t *this)
{
- if (this->overlay_enabled) {
- double video_aspect, gui_aspect;
- int gui_win_x, gui_win_y, win_off_x, win_off_y, gui_width, gui_height;
+ if (vo_scale_redraw_needed(&this->scale)) {
+ em8300_overlay_window_t win;
- switch (this->aspect) {
- case ASPECT_FULL:
- video_aspect = 4 / 3;
- break;
- case ASPECT_ANAMORPHIC:
- video_aspect = 16 / 9;
- break;
- default:
- video_aspect = 4 / 3;
- }
+ vo_scale_compute_output_size(&this->scale);
- this->frame_output_cb(this->user_data,
- this->video_width, this->video_oheight, video_aspect,
- &win_off_x, &win_off_y, &gui_width, &gui_height, &gui_aspect, &gui_win_x, &gui_win_y);
-
- if (this->xpos != (gui_win_x + win_off_x) ||
- this->ypos != (gui_win_y + win_off_y) ||
- this->width != gui_width ||
- this->height != gui_height ||
- this->need_redraw) {
- em8300_overlay_window_t win;
-
- this->xpos = gui_win_x + win_off_x;
- this->ypos = gui_win_y + win_off_y;
- this->width = gui_width;
- this->height = gui_height;
+ /* fill video window with keycolor */
+ XLockDisplay(this->display);
+ XSetForeground(this->display, this->gc, this->black.pixel);
+ XFillRectangle(this->display, this->win, this->gc,
+ this->scale.gui_x, this->scale.gui_y,
+ this->scale.gui_width, this->scale.gui_height);
+ XSetForeground(this->display, this->gc, this->key.pixel);
+ XFillRectangle(this->display, this->win, this->gc,
+ this->scale.output_xoffset, this->scale.output_yoffset,
+ this->scale.output_width, this->scale.output_height);
+ XFlush(this->display);
+ XUnlockDisplay(this->display);
- /* fill video window with keycolor */
- XLockDisplay(this->display);
- XSetForeground(this->display, this->gc, this->color.pixel);
- XFillRectangle(this->display, this->win, this->gc,
- win_off_x, win_off_y, this->width, this->height);
- XUnlockDisplay(this->display);
- this->need_redraw = 0;
-
- /* is some part of the picture visible? */
- if (this->xpos + this->width < 0) return;
- if (this->ypos + this->height < 0) return;
- if (this->xpos > this->overlay.screen_xres) return;
- if (this->ypos > this->overlay.screen_yres) return;
+ win.xpos = this->scale.output_xoffset + this->scale.gui_win_x;
+ win.ypos = this->scale.output_yoffset + this->scale.gui_win_y;
+ win.width = this->scale.output_width;
+ win.height = this->scale.output_height;
+
+ /* is some part of the picture visible? */
+ if (win.xpos + win.width < 0) return;
+ if (win.ypos + win.height < 0) return;
+ if (win.xpos > this->overlay.screen_xres) return;
+ if (win.ypos > this->overlay.screen_yres) return;
- win.xpos = this->xpos;
- win.ypos = this->ypos;
- win.width = this->width;
- win.height = this->height;
-
- ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win);
- }
+ ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win);
}
}
#endif
@@ -1349,32 +1393,6 @@ static void dxr3_zoomTV(dxr3_driver_t *this)
ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update);
}
-#ifdef HAVE_X11
-static void dxr3_translate_gui2video(dxr3_driver_t *this, int x, int y,
- int *vid_x, int *vid_y)
-{
- *vid_x = x * this->video_width / this->width;
- *vid_y = y * this->video_oheight / this->height - this->top_bar;
-}
-#endif
-
-static int is_fullscreen(dxr3_driver_t *this)
-{
-#ifdef HAVE_X11
- XWindowAttributes a;
-
- XGetWindowAttributes(this->display, this->win, &a);
-
- return
- a.x == 0 &&
- a.y == 0 &&
- a.width == this->overlay.screen_xres &&
- a.height == this->overlay.screen_yres;
-#else
- return 0;
-#endif
-}
-
static void dxr3_update_add_bars(void *data, xine_cfg_entry_t *entry)
{
diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h
index 17507bcf5..83d7f80d2 100644
--- a/src/dxr3/video_out_dxr3.h
+++ b/src/dxr3/video_out_dxr3.h
@@ -17,7 +17,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: video_out_dxr3.h,v 1.11 2002/10/11 10:55:28 mroi Exp $
+ * $Id: video_out_dxr3.h,v 1.12 2002/10/26 14:35:05 mroi Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -29,6 +29,7 @@
#endif
#include "xine_internal.h"
+#include "vo_scale.h"
#include "dxr3.h"
/* values for fd_video indicating why it is closed */
@@ -68,58 +69,59 @@ typedef struct dxr3_overlay_s {
struct coeff colcal_lower[3];
} dxr3_overlay_t;
-typedef struct dxr3_driver_s {
- xine_vo_driver_t vo_driver;
- xine_t *xine;
+typedef struct dxr3_driver_class_s {
+ video_driver_class_t video_driver_class;
+ xine_t *xine;
+
+ int instance; /* we allow only one instance of this plugin */
+
+ char devname[128];
+ char devnum[3];
+} dxr3_driver_class_t;
- char devname[128];
- char devnum[3];
- int fd_control;
- int fd_video;
- pthread_mutex_t spu_device_lock;
- int fd_spu; /* to access the relevant dxr3 devices */
- int clut_cluttered;/* to tell spu decoder that it has to restore the palette */
+typedef struct dxr3_driver_s {
+ xine_vo_driver_t vo_driver;
+ dxr3_driver_class_t *class;
+
+ int fd_control;
+ int fd_video;
+ pthread_mutex_t spu_device_lock;
+ int fd_spu; /* to access the relevant dxr3 devices */
+ int clut_cluttered; /* to tell spu decoder that it has to restore the palette */
+
+ int enhanced_mode;
+ int swap_fields; /* swap fields */
+ int add_bars; /* add black bars to correct a.r. */
- int enhanced_mode;
- int swap_fields; /* swap fields */
- int add_bars; /* add black bars to correct a.r. */
+ int aspect;
+ int tv_mode;
+ int pan_scan;
+ int overlay_enabled;
+ int tv_switchable; /* can switch from overlay<->tvout */
+ int widescreen_enabled;
+ em8300_bcs_t bcs;
+
+ encoder_data_t *enc; /* mpeg encoder data */
+ spu_encoder_t *spu_enc; /* spu encoder */
+ int need_update; /* the mpeg encoder needs to be updated */
- int aspect;
- int tv_mode;
- int pan_scan;
- int overlay_enabled;
- int tv_switchable; /* can switch from overlay<->tvout */
- int widescreen_enabled;
- em8300_bcs_t bcs;
-
- encoder_data_t *enc; /* mpeg encoder data */
- spu_encoder_t *spu_enc; /* spu encoder */
- int video_iheight; /* input height (before adding black bars) */
- int video_oheight; /* output height (after adding bars) */
- int video_width;
- int video_ratio;
- int top_bar; /* the height of the upper black bar */
- int need_redraw; /* the image on screen needs redrawing */
- int need_update; /* the mpeg encoder needs to be updated */
-
- dxr3_overlay_t overlay;
+ int video_iheight; /* input height (before adding black bars) */
+ int video_oheight; /* output height (after adding black bars) */
+ int video_width;
+ int video_ratio;
+ int top_bar; /* the height of the upper black bar */
+
+ vo_scale_t scale;
+
+ dxr3_overlay_t overlay;
#ifdef HAVE_X11
- Display *display;
- Drawable win;
- GC gc;
- XColor color;
- int xpos, ypos;
- int width, height;
+ Display *display;
+ Drawable win;
+ GC gc;
+ XColor black;
+ XColor key;
#endif
- char *user_data;
- void (*frame_output_cb)(void *user_data,
- int video_width, int video_height,
- double video_pixel_aspect,
- int *dest_x, int *dest_y,
- int *dest_height, int *dest_width,
- double *dest_pixel_aspect,
- int *win_x, int *win_y);
} dxr3_driver_t;
typedef struct dxr3_frame_s {