summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dxr3/dxr3_decoder.c50
-rw-r--r--src/dxr3/dxr3_video_out.c34
-rw-r--r--src/dxr3/dxr3_video_out.h9
-rw-r--r--src/xine-engine/metronom.c3
4 files changed, 52 insertions, 44 deletions
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c
index e40b6c318..8a1c08d58 100644
--- a/src/dxr3/dxr3_decoder.c
+++ b/src/dxr3/dxr3_decoder.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_decoder.c,v 1.62 2002/03/07 13:33:44 jcdutton Exp $
+ * $Id: dxr3_decoder.c,v 1.63 2002/03/08 00:24:40 jcdutton Exp $
*
* dxr3 video and spu decoder plugin. Accepts the video and spu data
* from XINE and sends it directly to the corresponding dxr3 devices.
@@ -172,6 +172,7 @@ typedef struct dxr3scr_s {
int priority;
int64_t offset; /* difference between real scr and internal dxr3 clock */
uint32_t last_pts; /* last known value of internal dxr3 clock to detect wrap around */
+ pthread_mutex_t mutex;
} dxr3scr_t;
static int dxr3scr_get_priority (scr_plugin_t *scr) {
@@ -248,6 +249,7 @@ static void dxr3scr_adjust (scr_plugin_t *scr, int64_t vpts) {
int32_t offset32;
int64_t cpts;
+ pthread_mutex_lock(&self->mutex);
if (ioctl(self->fd_control, EM8300_IOCTL_SCR_GET, &cpts32))
printf("dxr3scr: adjust get failed (%s)\n", strerror(errno));
cpts = (int64_t)cpts32 << 1;
@@ -264,6 +266,7 @@ static void dxr3scr_adjust (scr_plugin_t *scr, int64_t vpts) {
/* the internal clock in the dxr3 is 33 bits wide, so the upper bits
remain as an offset */
}
+ pthread_mutex_unlock(&self->mutex);
}
/* *** dxr3scr_start ***
@@ -275,6 +278,7 @@ static void dxr3scr_start (scr_plugin_t *scr, int64_t start_vpts) {
dxr3scr_t *self = (dxr3scr_t*) scr;
uint32_t vpts32 = start_vpts >> 1;
+ pthread_mutex_lock(&self->mutex);
self->last_pts = vpts32;
self->offset = start_vpts & ~0x1FFFFFFFF;
if (ioctl(self->fd_control, EM8300_IOCTL_SCR_SET, &vpts32))
@@ -282,6 +286,7 @@ static void dxr3scr_start (scr_plugin_t *scr, int64_t start_vpts) {
/* mis-use vpts32 */
vpts32 = 0x900;
ioctl(self->fd_control, EM8300_IOCTL_SCR_SETSPEED, &vpts32);
+ pthread_mutex_unlock(&self->mutex);
}
@@ -294,14 +299,25 @@ static int64_t dxr3scr_get_current (scr_plugin_t *scr) {
dxr3scr_t *self = (dxr3scr_t*) scr;
uint32_t pts;
- if (ioctl(self->fd_control, EM8300_IOCTL_SCR_GET, &pts))
+ pthread_mutex_lock(&self->mutex);
+ if (ioctl(self->fd_control, EM8300_IOCTL_SCR_GET, &pts))
printf("dxr3scr: get current failed (%s)\n", strerror(errno));
if (pts < self->last_pts) /* wrap around detected, compensate with offset */
self->offset += (int64_t)1 << 33;
self->last_pts = pts;
+ pthread_mutex_unlock(&self->mutex);
return ((int64_t)pts << 1) + self->offset;
}
+ /* *** dxr3scr_exit ***
+ clean up for exit
+ */
+static void dxr3scr_exit (scr_plugin_t *scr) {
+ dxr3scr_t *self = (dxr3scr_t*) scr;
+
+ pthread_mutex_destroy(&self->mutex);
+ free (self);
+}
/* *** dxr3scr_init ***
@@ -320,9 +336,11 @@ static scr_plugin_t* dxr3scr_init (dxr3_decoder_t *dxr3) {
self->scr.adjust = dxr3scr_adjust;
self->scr.start = dxr3scr_start;
self->scr.get_current = dxr3scr_get_current;
+ self->scr.exit = dxr3scr_exit;
self->offset = 0;
self->last_pts = 0;
+ pthread_mutex_init(&self->mutex, NULL);
snprintf (tmpstr, sizeof(tmpstr), "%s%s", devname, devnum);
if ((self->fd_control = open (tmpstr, O_WRONLY)) < 0) {
@@ -333,7 +351,7 @@ static scr_plugin_t* dxr3scr_init (dxr3_decoder_t *dxr3) {
self->priority = dxr3->scr_prio;
- printf("dxr3scr: init complete\n");
+ printf("dxr3scr_init: init complete\n");
return &self->scr;
}
@@ -557,12 +575,12 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
duration = get_duration(this->frame_rate_code,
this->repeat_first_field);
/* pretend like we have decoded a frame */
- img = this->video_out->get_frame (this->video_out,
+ img = this->video_out->get_frame (this->video_out,
this->width,
this->height,
this->aspect,
- IMGFMT_YV12,
- DXR3_VO_UPDATE_FLAG);
+ IMGFMT_MPEG,
+ VO_BOTH_FIELDS);
img->pts=buf->pts;
img->bad_frame = 0;
img->duration = duration;
@@ -570,9 +588,11 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
and stores the return value in img->vpts
Calling draw with buf->pts==0 is okay; metronome will
extrapolate a value. */
- skip = img->draw(img);
+ skip = img->draw(img) + (21600 / duration);
if (skip <= 0) { /* don't skip */
- vpts = img->pts; /* copy so we can free img */
+ vpts = img->vpts - 21600; /* copy so we can free img */
+ /* a note on the 21600: this seems to be a necessary offset,
+ maybe the dxr3 needs some internal time, however it improves sync a lot */
}
else { /* metronom says skip, so don't set pts */
printf("dxr3: skip = %d\n", skip);
@@ -625,7 +645,7 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
if ((delay > 0) && (delay < 90000) &&
(this->sync_every_frame || buf->pts)) {
uint32_t vpts32 = vpts;
- /* update the dxr3's current pts value */
+ /* update the dxr3's current pts value */
if (ioctl(this->fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vpts32))
printf("dxr3: set video pts failed (%s)\n",
strerror(errno));
@@ -676,6 +696,8 @@ static void dxr3_close (video_decoder_t *this_gen)
if (this->scr) {
this->video_decoder.metronom->unregister_scr(
this->video_decoder.metronom, this->scr);
+ this->scr->exit(this->scr);
+ this->scr = 0;
}
if (this->fd_video >= 0)
@@ -926,13 +948,13 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf)
#if LOG_SPU
printf("dxr3_spu: Got NAV packet\n");
#endif
- uint8_t *p;
- pci_t *pci;
+ uint8_t *p = buf->content;
- p = buf->content;
/* just watch out for menus */
if (p[3] == 0xbf && p[6] == 0x00) { /* Private stream 2 */
- pci=xine_xmalloc(sizeof(pci_t));
+ pci_t *pci;
+
+ pci = xine_xmalloc(sizeof(pci_t));
nav_read_pci(pci, p + 7);
if (pci->hli.hl_gi.hli_ss == 1)
@@ -944,6 +966,8 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf)
xine_fast_memcpy(&this->pci, pci, sizeof(pci_t));
ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, NULL);
}
+
+ free(pci);
}
return;
}
diff --git a/src/dxr3/dxr3_video_out.c b/src/dxr3/dxr3_video_out.c
index c6d612898..b36d49614 100644
--- a/src/dxr3/dxr3_video_out.c
+++ b/src/dxr3/dxr3_video_out.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_video_out.c,v 1.9 2002/03/07 13:33:44 jcdutton Exp $
+ * $Id: dxr3_video_out.c,v 1.10 2002/03/08 00:24:40 jcdutton Exp $
*
* mpeg1 encoding video out plugin for the dxr3.
*
@@ -217,34 +217,24 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen,
aspect = this->aspectratio;
oheight = this->oheight;
- if (flags == DXR3_VO_UPDATE_FLAG) { /* talking to dxr3 decoder */
- this->mpeg_source = 1;
+ if (format == IMGFMT_MPEG) { /* talking to dxr3 decoder */
+ int aspect;
+
/* a bit of a hack. we must release the em8300_mv fd for
* the dxr3 decoder plugin */
if (this->fd_video >= 0) {
close(this->fd_video);
this->fd_video = -1;
}
- }
- else {
- /* FIXME: Disable reset of mpeg_source
- * video_out.c can call us without the DXR3_VO_UPDATE_FLAG in
- * the still frames code. Needs a better fix... */
- this->mpeg_source = 0;
- }
-
- /* for mpeg source, we don't have to do much. */
- if (this->mpeg_source) {
- int aspect;
+ /* for mpeg source, we don't have to do much. */
this->video_width = width;
this->video_height = height;
this->video_aspect = ratio_code;
/* remember, there are no buffers malloc'ed for this frame!
- * the dxr3 decoder plugin is cool about this */
+ * the dxr3 decoder plugin is cool about this */
frame->width = width;
frame->height = height;
frame->oheight = oheight;
- frame->format = format;
if (frame->mem) {
free (frame->mem);
frame->mem = NULL;
@@ -322,7 +312,7 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen,
);
}
- if (this->mpeg_source == 0 && this->enc && this->enc->on_update_format)
+ if (this->enc && this->enc->on_update_format)
this->enc->on_update_format(this);
}
@@ -396,7 +386,6 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen,
frame->width = width;
frame->height = height;
frame->oheight = oheight;
- frame->format = format;
frame->swap_fields = this->swap_fields;
if(this->aspectratio!=aspect)
dxr3_set_property (this_gen,VO_PROP_ASPECT_RATIO, aspect);
@@ -407,7 +396,7 @@ static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src)
{
dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
dxr3_driver_t *this = (dxr3_driver_t *) frame_gen->driver;
- if (this->mpeg_source == 0 && this->enc && this->enc->on_frame_copy)
+ if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_frame_copy)
this->enc->on_frame_copy(this, frame, src);
}
@@ -415,7 +404,7 @@ static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
{
dxr3_driver_t *this = (dxr3_driver_t*)this_gen;
dxr3_frame_t *frame = (dxr3_frame_t*)frame_gen;
- if (this->mpeg_source == 0 && this->enc && this->enc->on_display_frame) {
+ if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_display_frame) {
this->enc->on_display_frame(this, frame);
} else {
frame_gen->displayed(frame_gen);
@@ -427,8 +416,7 @@ static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
static void dxr3_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
vo_overlay_t *overlay)
{
- dxr3_driver_t *this = (dxr3_driver_t*)this_gen;
- if ( this->mpeg_source == 0 )
+ if ( frame_gen->format != IMGFMT_MPEG )
{
/* we have regular YUV frames, so in principle we can blend
* it just like the Xv driver does. Problem is that the
@@ -447,7 +435,6 @@ void dxr3_exit (vo_driver_t *this_gen)
if (this->enc && this->enc->on_close)
this->enc->on_close(this);
printf("dxr3: vo exit called\n");
- this->mpeg_source = 0;
if(this->overlay_enabled)
dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF);
@@ -510,7 +497,6 @@ printf("dxr3_video_out:init_plugin\n");
this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange;
this->vo_driver.exit = dxr3_exit;
this->config=config;
- this->mpeg_source = 0; /* set by update_frame, by checking the flag */
this->swap_fields = config->register_bool(config, "dxr3.enc_swap_fields", 0, "swap odd and even lines", NULL, dxr3_update_swap_fields, this);
diff --git a/src/dxr3/dxr3_video_out.h b/src/dxr3/dxr3_video_out.h
index 1c5bbe777..2f5964a94 100644
--- a/src/dxr3/dxr3_video_out.h
+++ b/src/dxr3/dxr3_video_out.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_video_out.h,v 1.14 2002/03/07 13:33:44 jcdutton Exp $
+ * $Id: dxr3_video_out.h,v 1.15 2002/03/08 00:24:40 jcdutton Exp $
*
*/
@@ -54,9 +54,8 @@
#define LOOKUP_DEV "dxr3.devicename"
#define DEFAULT_DEV "/dev/em8300"
-/* flag for video_out->get_frame, to tell dxr3 vo to update
- image size and aspect ratio */
-#define DXR3_VO_UPDATE_FLAG 6667
+/* image format used by dxr3_decoder to tag undecoded mpeg data */
+#define IMGFMT_MPEG (('G'<<24)|('E'<<16)|('P'<<8)|'M')
struct coeff {
float k,m;
@@ -90,7 +89,6 @@ typedef struct dxr3_driver_s {
int fd_video;
int aspectratio;
int tv_mode;
- int mpeg_source; /* receiving mpeg data or raw YUV? */
int enhanced_mode; /* enhanced play mode */
em8300_bcs_t bcs;
char devname[128];
@@ -141,7 +139,6 @@ typedef struct dxr3_frame_s {
int width, height,oheight;
uint8_t *mem; /* allocated for YV12 or YUY2 buffers */
uint8_t *real_base[3]; /* yuv/yuy2 buffers in mem aligned on 16 */
- int format;
int copy_calls; /* counts calls to dxr3_frame_copy function */
int swap_fields; /* shifts Y buffer one line to exchange odd/even lines*/
} dxr3_frame_t;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index d24f28ac7..382b037ab 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.60 2002/03/01 09:29:50 guenter Exp $
+ * $Id: metronom.c,v 1.61 2002/03/08 00:24:40 jcdutton Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -179,6 +179,7 @@ static scr_plugin_t* unixscr_init () {
pthread_mutex_init (&this->lock, NULL);
unixscr_set_speed (&this->scr, SPEED_PAUSE);
+ printf("xine-scr_init: complete\n");
return &this->scr;
}