From 8a4e62c97bb64a11892f07f6a7c38e9fb4e94d41 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Thu, 4 Apr 2002 00:08:36 +0000 Subject: latest dxr3 patches from Michael Roitzsch and Zoltan Boszormenyi It adresses the following issues: * the dxr3 now handles overlays * dxr3 video decoder priority is now customizable, this way the user can choose between hardware decoding and libmpeg2 decoding (because overlays don't work with hardware decoding) * I hope I finally got the dxr3 playmode handling right CVS patchset: 1673 CVS date: 2002/04/04 00:08:36 --- src/dxr3/Makefile.am | 6 ++--- src/dxr3/alphablend.c | 1 + src/dxr3/alphablend.h | 1 + src/dxr3/dxr3_decoder.c | 62 ++++++++++++++++++++++++++++++++------------- src/dxr3/dxr3_video_out.c | 22 ++++++++-------- src/dxr3/dxr3_video_out.h | 3 ++- src/libmpeg2/xine_decoder.c | 4 +-- 7 files changed, 65 insertions(+), 34 deletions(-) create mode 100644 src/dxr3/alphablend.c create mode 100644 src/dxr3/alphablend.h (limited to 'src') diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index 8e19c4868..5494e4aaf 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -1,6 +1,6 @@ CFLAGS = @CFLAGS@ $(X_CFLAGS) $(LINUX_INCLUDE) -EXTRA_DIST = dxr3_decoder.c dxr3_vo_core.c dxr3_video_out.c nav_read.c +EXTRA_DIST = dxr3_decoder.c dxr3_vo_core.c dxr3_video_out.c nav_read.c alphablend.c LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic @@ -22,13 +22,11 @@ xineplug_decode_dxr3_la_SOURCES = dxr3_decoder.c nav_read.c xineplug_decode_dxr3_la_LDFLAGS = -avoid-version -module xineplug_vo_out_dxr3_la_SOURCES = dxr3_video_out.c \ - dxr3_vo_core.c mpeg_encoders.c + dxr3_vo_core.c mpeg_encoders.c alphablend.c xineplug_vo_out_dxr3_la_LIBADD = $(X_LIBS) -lXext xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version \ -module $(link_fame) $(link_rte) $(X_LIBS) -include_HEADERS = dxr3_video_out.h - debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(LINUX_INCLUDE)" diff --git a/src/dxr3/alphablend.c b/src/dxr3/alphablend.c new file mode 100644 index 000000000..39949ab51 --- /dev/null +++ b/src/dxr3/alphablend.c @@ -0,0 +1 @@ +#include "../video_out/alphablend.c" diff --git a/src/dxr3/alphablend.h b/src/dxr3/alphablend.h new file mode 100644 index 000000000..86dec99d4 --- /dev/null +++ b/src/dxr3/alphablend.h @@ -0,0 +1 @@ +#include "../video_out/alphablend.h" diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c index da8305a5b..dea84f78f 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.68 2002/04/01 12:09:08 miguelfreitas Exp $ + * $Id: dxr3_decoder.c,v 1.69 2002/04/04 00:08:36 miguelfreitas Exp $ * * dxr3 video and spu decoder plugin. Accepts the video and spu data * from XINE and sends it directly to the corresponding dxr3 devices. @@ -95,6 +95,10 @@ static char devnum[3]; #define MV_COMMAND 0 +/* the number of frames to pass after an out-of-sync situation + before locking the stream again */ +#define RESYNC_WINDOW_SIZE 50 + typedef struct dxr3_decoder_s { video_decoder_t video_decoder; @@ -117,6 +121,7 @@ typedef struct dxr3_decoder_s { /* if disabled by repeat first field, retry after 500 frames */ int sync_retry; int enhanced_mode; + int resync_window; int have_header_info; int in_buffer_fill; pthread_t decoder_thread; /* reference to self */ @@ -192,40 +197,41 @@ static int dxr3scr_set_speed (scr_plugin_t *scr, int speed) { switch(speed){ case SPEED_PAUSE: em_speed = 0; - playmode=EM8300_PLAYMODE_PAUSED; + playmode=MVCOMMAND_PAUSE; break; case SPEED_SLOW_4: em_speed = 0x900/4; - playmode=EM8300_PLAYMODE_PLAY; + playmode=MVCOMMAND_START; break; case SPEED_SLOW_2: em_speed = 0x900/2; - playmode=EM8300_PLAYMODE_PLAY; + playmode=MVCOMMAND_START; break; case SPEED_NORMAL: em_speed = 0x900; - playmode=EM8300_PLAYMODE_PLAY; + playmode=MVCOMMAND_SYNC; break; case SPEED_FAST_2: em_speed = 0x900*2; - playmode=EM8300_PLAYMODE_SCAN; + playmode=MVCOMMAND_START; break; case SPEED_FAST_4: em_speed = 0x900*4; - playmode=EM8300_PLAYMODE_SCAN; + playmode=MVCOMMAND_START; break; default: em_speed = 0; - playmode = EM8300_PLAYMODE_PAUSED; + playmode = MVCOMMAND_PAUSE; } + + if (dxr3_mvcommand(self->fd_control, playmode)) + printf("dxr3scr: failed to playmode (%s)\n", strerror(errno)); + if(em_speed>0x900) scanning_mode=1; else scanning_mode=0; - if (ioctl(self->fd_control, EM8300_IOCTL_SET_PLAYMODE, &playmode)) - printf("dxr3scr: failed to playmode (%s)\n", strerror(errno)); - if (ioctl(self->fd_control, EM8300_IOCTL_SCR_SETSPEED, &em_speed)) printf("dxr3scr: failed to set speed (%s)\n", strerror(errno)); @@ -296,6 +302,9 @@ static int64_t dxr3scr_get_current (scr_plugin_t *scr) { pthread_mutex_lock(&self->mutex); if (ioctl(self->fd_control, EM8300_IOCTL_SCR_GET, &pts)) printf("dxr3scr: get current failed (%s)\n", strerror(errno)); + /* FIXME: The pts value read from the card sometimes drops to zero for + unknown reasons. We catch this here, but we should better find out, why. */ + if (pts == 0) pts = self->last_pts; if (pts < self->last_pts) /* wrap around detected, compensate with offset */ self->offset += (int64_t)1 << 33; self->last_pts = pts; @@ -380,6 +389,8 @@ static void dxr3_init (video_decoder_t *this_gen, vo_instance_t *video_out) this->last_pts = metronom->get_current_time(metronom); this->decoder_thread = pthread_self(); + this->resync_window = 0; + cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset - 21600); /* a note on the 21600: this seems to be a necessary offset, @@ -548,10 +559,29 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf) skip = img->draw(img); if (skip <= 0) { /* don't skip */ vpts = img->vpts; /* copy so we can free img */ + + if (this->resync_window == 0 && this->scr && this->enhanced_mode && !scanning_mode) { + /* we are in sync, so we can lock the stream now */ + printf("dxr3: in sync, stream locked\n"); + dxr3_mvcommand(this->fd_control, MVCOMMAND_SYNC); + this->resync_window = -RESYNC_WINDOW_SIZE; + } + if (this->resync_window != 0 && this->resync_window > -RESYNC_WINDOW_SIZE) + this->resync_window--; } else { /* metronom says skip, so don't set vpts */ printf("dxr3: skip = %d\n", skip); vpts = 0; + + if (scanning_mode) this->resync_window = 0; + if (this->resync_window == 0 && this->scr && this->enhanced_mode && !scanning_mode) { + /* switch off sync mode in the card to allow resyncing */ + printf("dxr3: out of sync, allowing stream resync\n"); + dxr3_mvcommand(this->fd_control, MVCOMMAND_START); + this->resync_window = RESYNC_WINDOW_SIZE; + } + if (this->resync_window != 0 && this->resync_window < RESYNC_WINDOW_SIZE) + this->resync_window++; } img->free(img); this->last_pts += duration; /* predict vpts */ @@ -592,10 +622,6 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf) if (!this->scr) { int64_t time; - /* if the dxr3_alt_play option is used, change the dxr3 playmode */ - if(this->enhanced_mode) - dxr3_mvcommand(this->fd_control, MVCOMMAND_SYNC); - time = this->video_decoder.metronom->get_current_time( this->video_decoder.metronom); @@ -771,7 +797,9 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, this->video_decoder.close = dxr3_close; this->video_decoder.get_identifier = dxr3_get_id; this->video_decoder.flush = dxr3_flush; - this->video_decoder.priority = 10; + this->video_decoder.priority = cfg->register_num(cfg, + "dxr3.decoder_priority", 10, "Dxr3: video decoder priority", NULL, NULL, NULL); + this->config = cfg; this->frame_rate_code = 0; @@ -792,7 +820,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, this->enhanced_mode = cfg->register_bool(cfg, "dxr3.alt_play_mode", - 0, + 1, "Use alternate Play mode", "Enabling this option will utilise a slightly different play mode", dxr3_update_enhanced_mode, this); diff --git a/src/dxr3/dxr3_video_out.c b/src/dxr3/dxr3_video_out.c index 079f7c2a0..727cd5cae 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.14 2002/04/03 09:40:40 mlampard Exp $ + * $Id: dxr3_video_out.c,v 1.15 2002/04/04 00:08:36 miguelfreitas Exp $ * * mpeg1 encoding video out plugin for the dxr3. * @@ -439,16 +439,18 @@ 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) { + /* FIXME: We only blend non-mpeg frames here. + Is there any way to provide overlays for mpeg content? Subpictures? */ if ( frame_gen->format != IMGFMT_MPEG ) { - /* FIXME: Do something useful here. - * we have regular YUV frames, so in principle we can blend - * it just like the Xv driver does. Problem is that the - * alphablend.c code file is not nearby */ - } - else { - /* we're using hardware mpeg decoding and have no YUV frames - * we need something else to blend... */ + dxr3_frame_t *frame = (dxr3_frame_t*)frame_gen; + + if (overlay->rle) { + if( frame_gen->format == IMGFMT_YV12 ) + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height); + else + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height); + } } } @@ -615,7 +617,7 @@ printf("dxr3_video_out:init_plugin\n"); "dxr3: driver. See the README.dxr3 for details on configuring an encoder.\n" ); } - + /* default values */ this->overlay_enabled = 0; this->aspectratio = ASPECT_FULL; diff --git a/src/dxr3/dxr3_video_out.h b/src/dxr3/dxr3_video_out.h index f1d356999..847b41f50 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.18 2002/04/03 09:40:40 mlampard Exp $ + * $Id: dxr3_video_out.h,v 1.19 2002/04/04 00:08:36 miguelfreitas Exp $ * */ @@ -39,6 +39,7 @@ #include #include "video_out.h" #include "xine_internal.h" +#include "alphablend.h" /* for fast_memcpy: */ #include "xineutils.h" diff --git a/src/libmpeg2/xine_decoder.c b/src/libmpeg2/xine_decoder.c index 9eeba9420..56af6324b 100644 --- a/src/libmpeg2/xine_decoder.c +++ b/src/libmpeg2/xine_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: xine_decoder.c,v 1.25 2002/03/21 02:02:30 guenter Exp $ + * $Id: xine_decoder.c,v 1.26 2002/04/04 00:08:36 miguelfreitas Exp $ * * stuff needed to turn libmpeg2 into a xine decoder plugin */ @@ -152,7 +152,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) { this->video_decoder.flush = mpeg2dec_flush; this->video_decoder.close = mpeg2dec_close; this->video_decoder.get_identifier = mpeg2dec_get_id; - this->video_decoder.priority = 1; + this->video_decoder.priority = 5; this->mpeg2.xine = xine; pthread_mutex_init (&this->lock, NULL); -- cgit v1.2.3