diff options
-rw-r--r-- | src/dxr3/dxr3_decoder.c | 50 | ||||
-rw-r--r-- | src/dxr3/dxr3_video_out.c | 34 | ||||
-rw-r--r-- | src/dxr3/dxr3_video_out.h | 9 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 3 |
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; } |