diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/allcodecs.c mythtv-0.15.1.xvmc/libs/libavcodec/allcodecs.c
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/allcodecs.c	2004-05-31 16:18:05.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/allcodecs.c	2004-09-01 09:30:59.000000000 +0100
***************
*** 110,115 ****
--- 110,118 ----
  #ifdef HAVE_XVMC
      register_avcodec(&mpeg_xvmc_decoder);
  #endif
+ #ifdef HAVE_XVMC_VLD
+     register_avcodec(&mpeg_xvmc_vld_decoder);
+ #endif
  #ifdef HAVE_VIASLICE
      register_avcodec(&mpeg_via_decoder);
  #endif
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/avcodec.h mythtv-0.15.1.xvmc/libs/libavcodec/avcodec.h
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/avcodec.h	2004-05-21 06:30:53.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/avcodec.h	2004-09-03 07:06:23.000000000 +0100
***************
*** 34,39 ****
--- 34,40 ----
      CODEC_ID_MPEG1VIDEO,
      CODEC_ID_MPEG2VIDEO, /* prefered ID for MPEG Video 1 or 2 decoding */
      CODEC_ID_MPEG2VIDEO_XVMC,
+     CODEC_ID_MPEG2VIDEO_XVMC_VLD,
      CODEC_ID_MPEG2VIDEO_VIA,
      CODEC_ID_H263,
      CODEC_ID_RV10,
***************
*** 688,694 ****
       * - decoding: unused.
       */
      int rate_emu;
!        
      /**
       * if non NULL, 'draw_horiz_band' is called by the libavcodec
       * decoder to draw an horizontal band. It improve cache usage. Not
--- 689,703 ----
       * - decoding: unused.
       */
      int rate_emu;
! 
! #if USING_XVMC_VLD
!     /* This is used on changes to the qmatrix to configure a HwMpeg controller */
!     void (*qmatrix_load)(struct AVCodecContext *s, const AVFrame *src, void* data);
! 
!     /* This is used on the start of each field to initialise a HwMpeg controller */
!     void (*field_start)(struct AVCodecContext *s, const AVFrame *src, void* data);
! #endif
!     
      /**
       * if non NULL, 'draw_horiz_band' is called by the libavcodec
       * decoder to draw an horizontal band. It improve cache usage. Not
***************
*** 1602,1607 ****
--- 1611,1624 ----
       * - decoding: set by decoder
       */
      int via_hwslice;
+     
+     /**
+      * XVMC_VLD (VIA CLE266) Hardware MPEG decoding
+      * - encoding: forbidden
+      * - decoding: set by decoder
+      */
+     int xvmc_vld_hwslice;
+     
  
  } AVCodecContext;
  
***************
*** 1743,1748 ****
--- 1760,1766 ----
  extern AVCodec mpeg2video_decoder;
  extern AVCodec mpegvideo_decoder;
  extern AVCodec mpeg_xvmc_decoder;
+ extern AVCodec mpeg_xvmc_vld_decoder;
  extern AVCodec mpeg_via_decoder;
  extern AVCodec h263i_decoder;
  extern AVCodec flv_decoder;
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/libavcodec.pro mythtv-0.15.1.xvmc/libs/libavcodec/libavcodec.pro
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/libavcodec.pro	2004-08-31 16:18:36.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/libavcodec.pro	2004-08-31 15:06:53.000000000 +0100
***************
*** 54,59 ****
--- 54,64 ----
      DEFINES += HAVE_XVMC
  }
  
+ using_xvmc_vld {
+     SOURCES += xvmcvldvideo.c
+     DEFINES += HAVE_XVMC_VLD
+ }
+ 
  using_viahwslice {
      SOURCES += viaslice.c
      DEFINES += HAVE_VIASLICE
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/mpeg12.c mythtv-0.15.1.xvmc/libs/libavcodec/mpeg12.c
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/mpeg12.c	2004-05-21 06:30:55.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/mpeg12.c	2004-09-01 06:22:23.000000000 +0100
***************
*** 80,85 ****
--- 80,92 ----
  extern void XVMC_init_block(MpegEncContext *s);//set s->block
  #endif
  
+ #ifdef HAVE_XVMC_VLD
+ extern int XVMC_VLD_field_start(MpegEncContext *s, AVCodecContext *avctx);
+ extern int XVMC_VLD_field_end(MpegEncContext *s);
+ extern int XVMC_VLD_decode_slice(MpegEncContext *s, int start_code, uint8_t *buffer,
+                             int buf_size);
+ #endif
+ 
  #ifdef HAVE_VIASLICE
  extern int VIA_field_start(MpegEncContext *s, AVCodecContext *avctx);
  extern int VIA_field_end(MpegEncContext *s);
***************
*** 1909,1914 ****
--- 1916,1923 ----
          if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
              if( avctx->idct_algo == FF_IDCT_AUTO )
                  avctx->idct_algo = FF_IDCT_SIMPLE;
+         if( avctx->xvmc_vld_hwslice == 1)
+             avctx->idct_algo = FF_IDCT_LIBMPEG2MMX;
          if( avctx->via_hwslice == 1)
              avctx->idct_algo = FF_IDCT_LIBMPEG2MMX;
  
***************
*** 2261,2266 ****
--- 2270,2279 ----
      if(s->avctx->xvmc_acceleration)
           XVMC_field_start(s,avctx);
  #endif
+ #ifdef HAVE_XVMC_VLD
+       if(s->avctx->xvmc_vld_hwslice)
+         XVMC_VLD_field_start(s, avctx);
+ #endif
  #ifdef HAVE_VIASLICE
        if(s->avctx->via_hwslice)
          VIA_field_start(s, avctx);
***************
*** 2293,2298 ****
--- 2306,2320 ----
          return -1;
      }
  
+ #ifdef HAVE_XVMC_VLD
+     if (s->avctx->xvmc_vld_hwslice){
+         int used = XVMC_VLD_decode_slice(s, mb_y, *buf, buf_size);
+         if (used < 0)
+             return DECODE_SLICE_ERROR;
+         *buf += used - 1;
+         return DECODE_SLICE_OK;
+     }
+ #endif
  #ifdef HAVE_VIASLICE
      if (s->avctx->via_hwslice){
          int used = VIA_decode_slice(s, mb_y, *buf, buf_size);
***************
*** 2511,2516 ****
--- 2533,2542 ----
      if(s->avctx->xvmc_acceleration)
          XVMC_field_end(s);
  #endif
+ #ifdef HAVE_XVMC_VLD
+     if(s->avctx->xvmc_vld_hwslice)
+         XVMC_VLD_field_end(s);
+ #endif
  #ifdef HAVE_VIASLICE
      if(s->avctx->via_hwslice)
          VIA_field_end(s);
***************
*** 2676,2681 ****
--- 2702,2709 ----
      if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
          if( avctx->idct_algo == FF_IDCT_AUTO )
              avctx->idct_algo = FF_IDCT_SIMPLE;
+     if( avctx->xvmc_vld_hwslice == 1)
+         avctx->idct_algo = FF_IDCT_LIBMPEG2MMX;
      if( avctx->via_hwslice == 1)
          avctx->idct_algo = FF_IDCT_LIBMPEG2MMX;
  
***************
*** 3078,3083 ****
--- 3106,3143 ----
  
  #endif
  
+ #ifdef HAVE_XVMC_VLD
+ static int mpeg_xvmc_vld_decode_init(AVCodecContext *avctx){
+     Mpeg1Context *s;
+ 
+     if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+         return -1;
+     if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) )
+         dprintf("mpeg12.c: XVMC_VLD decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
+ 
+     mpeg_decode_init(avctx);
+     s = avctx->priv_data;
+ 
+     avctx->xvmc_vld_hwslice = 1;
+ 
+     return 0;
+ }
+ 
+ AVCodec mpeg_xvmc_vld_decoder = {
+     "mpegvideo_xvmc_vld",
+     CODEC_TYPE_VIDEO,
+     CODEC_ID_MPEG2VIDEO_XVMC_VLD,
+     sizeof(Mpeg1Context),
+     mpeg_xvmc_vld_decode_init,
+     NULL,
+     mpeg_decode_end,
+     mpeg_decode_frame,
+     CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL,
+     .flush= mpeg12_flush,
+ };
+ 
+ #endif
+ 
  #ifdef HAVE_VIASLICE
  static int mpeg_via_decode_init(AVCodecContext *avctx){
      Mpeg1Context *s;
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/xvmc_render.h mythtv-0.15.1.xvmc/libs/libavcodec/xvmc_render.h
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/xvmc_render.h	2004-04-30 07:54:35.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/xvmc_render.h	2004-09-03 16:09:05.000000000 +0100
***************
*** 7,13 ****
  #include <X11/extensions/Xv.h>
  #include <X11/extensions/Xvlib.h>
  #include <X11/extensions/XvMClib.h>
! 
  
  //the surface should be shown, video driver manipulate this
  #define MP_XVMC_STATE_DISPLAY_PENDING 1
--- 7,16 ----
  #include <X11/extensions/Xv.h>
  #include <X11/extensions/Xvlib.h>
  #include <X11/extensions/XvMClib.h>
! #if USING_XVMC_VLD
! #include <stdint.h>
! #include <X11/extensions/viaXvMC.h>
! #endif
  
  //the surface should be shown, video driver manipulate this
  #define MP_XVMC_STATE_DISPLAY_PENDING 1
***************
*** 50,55 ****
--- 53,65 ----
    
    int next_free_data_block_num;//used in add_mv_block, pointer to next free block
    int pict_type; //this is for skipping frames
+ 
+ #if USING_XVMC_VLD
+   // These are for the XVMC VLD slice interface
+   int		slice_code;
+   uint8_t*	slice_data;
+   int		slice_datalen;
+ #endif
  } xvmc_render_state_t;
  
  #endif
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libavcodec/xvmcvldvideo.c mythtv-0.15.1.xvmc/libs/libavcodec/xvmcvldvideo.c
*** mythtv-0.15.1.orig.rpm/libs/libavcodec/xvmcvldvideo.c	1970-01-01 01:00:00.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libavcodec/xvmcvldvideo.c	2004-09-03 19:36:13.000000000 +0100
***************
*** 0 ****
--- 1,261 ----
+ /******************************************************************************************************
+  * Copyright (C) 2004 Beam Ltd
+  *
+  * This file is part of MythTv.
+  *
+  * This file contains free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This file is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+  *
+  * Author: Terry Barnaby
+  * Description:	This file contains the Video Codec interface for the XvMC VLD X-Windows extension
+  *	that supports the Hardware MPEG decoding engine in the Via Unichrome Chipset.
+  * Date: 3/9/04
+  *
+  ******************************************************************************************************
+  */
+ #include "avcodec.h"
+ #include "dsputil.h"
+ #include "mpegvideo.h"
+ #include "xvmc_render.h"
+ 
+ #define	DEBUG	0
+ 
+ #undef printf
+ #undef fprintf
+ 
+ #if DEBUG
+ #define dprintf(fmt, a...)	printf(fmt, ##a)
+ 
+ static void bhd(void* data, int nbytes){
+ 	uint8_t*	p = (uint8_t*)data;
+ 	int		n;
+ 	
+ 	for(n = 0; n < nbytes; n++){
+ 		printf("%2.2x ", *p++);
+ 		if((n % 16) == 15)
+ 			printf("\n");
+ 	}
+ 	if((n % 16) != 15)
+ 		printf("\n");
+ }
+ 
+ #else
+ #define dprintf(fmt, a...)
+ #endif
+ 
+ static XvMCSurface* findPastSurface(MpegEncContext* s, xvmc_render_state_t* render){
+ 	Picture*		lastp = s->last_picture_ptr;
+ 	xvmc_render_state_t*	last = NULL;
+ 
+ 	if(NULL != lastp){
+ 		last = (xvmc_render_state_t*)(lastp->data[2]);
+ #if DEBUG
+ 		if(B_TYPE == last->pict_type)
+ 			fprintf(stderr, "Past frame is a B frame in findPastSurface, this is bad.\n");
+ #else
+ 		assert(B_TYPE != last->pict_type);
+ #endif
+ 	}
+ 
+ 	if(NULL == last){
+ 		if(!s->first_field)
+ 			last = render; // predict second field from the first
+ 		else
+ 			return 0;
+ 	}
+ 	
+ 	if(last->magic != MP_XVMC_RENDER_MAGIC)
+ 		return 0;
+ 
+ 	return (last->state & MP_XVMC_STATE_PREDICTION) ? last->p_surface : 0;
+ }
+ 
+ static XvMCSurface* findFutureSurface(MpegEncContext* s){
+ 	Picture*		nextp = s->next_picture_ptr;
+ 	xvmc_render_state_t*	next = NULL;
+ 
+ 	if(NULL != nextp){
+ 		next = (xvmc_render_state_t*)(nextp->data[2]);
+ #if DEBUG
+ 		if(B_TYPE == next->pict_type)
+ 			fprintf(stderr, "Next frame is a B frame in findFutureSurface, this is bad.\n");
+ #else
+ 		assert(B_TYPE != next->pict_type);
+ #endif
+ 	}
+ 
+ 	assert(NULL != next);
+ 
+ 	if(next->magic != MP_XVMC_RENDER_MAGIC)
+ 		return 0;
+ 
+ 	return (next->state & MP_XVMC_STATE_PREDICTION) ? next->p_surface : 0;
+ }
+ 
+ int XVMC_VLD_field_start(MpegEncContext* s, AVCodecContext* avctx){
+ 	xvmc_render_state_t*	render;
+ 	XvMCMpegControl		binfo;
+ 	XvMCQMatrix		qmatrix;
+ 	int			i;
+ 
+ 	memset(&binfo, 0, sizeof(binfo));
+ 	memset(&qmatrix, 0, sizeof(qmatrix));
+ 
+ 	dprintf("BEAM: %s AVCodecContext: %p\n", __FUNCTION__, avctx);
+ 	render = (xvmc_render_state_t *)s->current_picture.data[2];
+ 	assert(render != NULL);
+ 
+ 	render->picture_structure = s->picture_structure;
+ 	if(render->picture_structure == PICT_FRAME)
+ 		render->flags = XVMC_FRAME_PICTURE;
+ 	else if(render->picture_structure == PICT_TOP_FIELD)
+ 		render->flags = XVMC_TOP_FIELD;
+ 	else if(render->picture_structure == PICT_BOTTOM_FIELD)
+ 		render->flags = XVMC_BOTTOM_FIELD;
+ 	if(!s->first_field) 
+ 		render->flags |= XVMC_SECOND_FIELD;
+ 	render->p_future_surface = NULL;
+ 	render->p_past_surface = NULL;
+ 
+ 	render->pict_type = s->pict_type; // for later frame dropping use
+ 	switch(s->pict_type){
+ 	case  I_TYPE:
+ 		// no prediction from other frames
+ 		break;
+ 
+ 	case  B_TYPE:
+ 		render->p_past_surface = findPastSurface(s, render);
+ 		render->p_future_surface = findFutureSurface(s);
+ 		if(!render->p_past_surface)
+ 			fprintf(stderr, "error: decoding B frame and past frame is null!");
+ 		else if(!render->p_future_surface)
+ 			fprintf(stderr, "error: decoding B frame and future frame is null!");
+ 		break;
+ 	case  P_TYPE:
+ 		render->p_past_surface = findPastSurface(s, render);
+ 		if(!render->p_past_surface)
+ 			fprintf(stderr, "error: decoding P frame and past frame is null!");
+ 		break;
+ 	}
+ 	dprintf("BEAMPicture: Type: %d Frames: %p %p\n", s->pict_type, render->p_past_surface, render->p_future_surface);
+ 
+ 	for(i = 0; i < 64; i++){
+ 		qmatrix.intra_quantiser_matrix[i] = s->intra_matrix[i];
+ 		qmatrix.non_intra_quantiser_matrix[i] = s->inter_matrix[i];
+ 	}
+ 	qmatrix.load_intra_quantiser_matrix = 1;
+ 	qmatrix.load_non_intra_quantiser_matrix = 1;
+ 
+ 	binfo.flags = 0;
+ 	if(s->alternate_scan)
+ 		binfo.flags |= XVMC_ALTERNATE_SCAN;
+ 	if(s->top_field_first)
+ 		binfo.flags |= XVMC_TOP_FIELD_FIRST;
+ 	if(s->frame_pred_frame_dct)
+ 		binfo.flags |= XVMC_PRED_DCT_FRAME;
+ 	else
+ 		binfo.flags |= XVMC_PRED_DCT_FIELD;
+ 
+ 	if(s->intra_vlc_format)
+ 		binfo.flags |= XVMC_INTRA_VLC_FORMAT;
+ 	if(s->first_field)
+ 		binfo.flags |= XVMC_SECOND_FIELD;
+ 	if(s->q_scale_type)
+ 		binfo.flags |= XVMC_Q_SCALE_TYPE;
+ 	if(s->concealment_motion_vectors)
+ 		binfo.flags |= XVMC_CONCEALMENT_MOTION_VECTORS;
+ 	if(s->progressive_sequence)
+ 		binfo.flags |= XVMC_PROGRESSIVE_SEQUENCE;
+ 
+ 	binfo.picture_structure = s->picture_structure;
+ 	switch(s->pict_type){
+ 	case I_TYPE:	binfo.picture_coding_type = XVMC_I_PICTURE;	break;
+ 	case P_TYPE:	binfo.picture_coding_type = XVMC_P_PICTURE;	break;
+ 	case B_TYPE:	binfo.picture_coding_type = XVMC_B_PICTURE;	break;
+ 	default:	fprintf(stderr, "%s: Unknown picture coding type: %d\n", __FUNCTION__, s->pict_type);
+ 	}
+ 	binfo.intra_dc_precision = s->intra_dc_precision;;
+ 
+ 	if (s->codec_id == CODEC_ID_MPEG2VIDEO)
+ 		binfo.mpeg_coding = 2;
+ 	else
+ 		binfo.mpeg_coding = 1;
+ 
+ #ifdef ZAP
+ 	/* Don't know if these are needed ??? */
+ 	s->mb_width = (s->width + 15) / 16;
+ 	s->mb_height = (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) ?
+ 		2 * ((s->height + 31) / 32) : (s->height + 15) / 16;
+ #endif
+ 
+ 	binfo.FVMV_range = (s->mpeg_f_code[0][1] - 1);
+ 	binfo.FHMV_range = (s->mpeg_f_code[0][0] - 1);
+ 	binfo.BVMV_range = (s->mpeg_f_code[1][1] - 1);
+ 	binfo.BHMV_range = (s->mpeg_f_code[1][0] - 1);
+ 
+ 	dprintf("BEAM: %s\n", __FUNCTION__);
+ 	if(s->avctx->qmatrix_load)
+ 		s->avctx->qmatrix_load(s->avctx, (AVFrame*)s->current_picture_ptr, &qmatrix);
+ 	if(s->avctx->field_start)
+ 		s->avctx->field_start(s->avctx, (AVFrame*)s->current_picture_ptr, &binfo);
+ 
+ 	return 0;
+ }
+ 
+ void XVMC_VLD_field_end(MpegEncContext* s){
+ 	s->error_count = 0;
+ }
+ 
+ static int length_to_next_start(uint8_t* pbuf_ptr, int buf_size){
+ 	uint8_t*	buf_ptr;
+ 	unsigned int	state = 0xFFFFFFFF, v;
+ 
+ 	buf_ptr = pbuf_ptr;
+ 	while(buf_ptr < pbuf_ptr + buf_size){
+ 		v = *buf_ptr++;
+ 		if(state == 0x000001) {
+ 			return buf_ptr - pbuf_ptr - 4;
+ 		}
+ 		state = ((state << 8) | v) & 0xffffff;
+ 	}
+ 	return -1;
+ }
+ 
+ #define SLICE_MIN_START_CODE   0x00000101
+ #define SLICE_MAX_START_CODE   0x000001af
+ 
+ 
+ int XVMC_VLD_decode_slice(MpegEncContext* s, int mb_y, uint8_t* buffer, int buf_size){
+ 	int			slicelen = length_to_next_start(buffer, buf_size);
+ 	xvmc_render_state_t*	render;
+ 
+ 	dprintf("BEAM: %s: Slicelen: %d %d\n", __FUNCTION__, buf_size, slicelen);
+ //	bhd(buffer, 128);
+ 	if(slicelen < 0){
+ 		if(mb_y == s->mb_height - 1)
+ 			slicelen = buf_size;
+ 		else
+ 			return -1;
+ 	}
+ 
+ 	render = (xvmc_render_state_t*)s->current_picture.data[2];
+ 	render->slice_code = SLICE_MIN_START_CODE + mb_y;
+ 	render->slice_data = buffer;
+ 	render->slice_datalen = slicelen;
+ 
+ 	dprintf("Call ff_draw_horiz_band: SliceLen: %p %d\n", render, render->slice_datalen);
+ 	ff_draw_horiz_band(s, 0, 0);
+ 
+ 	return slicelen;
+ }
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/avformatdecoder.cpp mythtv-0.15.1.xvmc/libs/libmythtv/avformatdecoder.cpp
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/avformatdecoder.cpp	2004-05-26 07:18:36.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/avformatdecoder.cpp	2004-09-04 12:00:07.316105000 +0100
***************
*** 19,24 ****
--- 19,28 ----
  #include "libavcodec/liba52/a52.h"
  }
  
+ #ifdef USING_XVMC_VLD
+ #include "videoout_xvmc.h"
+ #endif
+ 
  #define MAX_AC3_FRAME_SIZE 6144
  
  extern pthread_mutex_t avcodeclock;
***************
*** 365,370 ****
--- 369,380 ----
                      if (gContext->GetNumSetting("UseViaSlice", 1))
                          enc->codec_id = CODEC_ID_MPEG2VIDEO_VIA;
  #endif
+ #ifdef USING_XVMC_VLD
+                     if (gContext->GetNumSetting("UseXvMcVld", 1))
+                     {
+                         enc->codec_id = CODEC_ID_MPEG2VIDEO_XVMC_VLD;
+                     }
+ #endif            
                  }
  
                  AVCodec *codec = avcodec_find_decoder(enc->codec_id);
***************
*** 382,387 ****
--- 392,414 ----
                      setLowBuffers();
                      m_parent->ForceVideoOutputType(kVideoOutput_XvMC);
                  }
+                 else if (codec && codec->id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)
+                 {
+                     enc->flags |= CODEC_FLAG_EMU_EDGE;
+                     enc->get_buffer = get_avf_buffer_xvmc;
+                     enc->release_buffer = release_avf_buffer_xvmc;
+                     enc->field_start = render_field_start_xvmc;
+                     enc->qmatrix_load = render_qmatrix_load_xvmc;
+                     enc->draw_horiz_band = render_slice_xvmc;
+                     enc->opaque = (void *)this;
+                     directrendering = true;
+                     enc->slice_flags = SLICE_FLAG_CODED_ORDER |
+                                        SLICE_FLAG_ALLOW_FIELD;
+                     setLowBuffers();
+                     m_parent->ForceVideoOutputType(kVideoOutput_XvMC);
+ 		    
+ 		    // BEAM_TODO: Force VLD mode in XvMC Videoout ?
+                 }
                  else if (codec && codec->id == CODEC_ID_MPEG2VIDEO_VIA)
                  {
                      enc->flags |= CODEC_FLAG_EMU_EDGE;
***************
*** 739,744 ****
--- 766,788 ----
  
  }
  
+ #ifdef USING_XVMC_VLD
+ void render_field_start_xvmc(struct AVCodecContext *s, const AVFrame *pic, void* data)
+ {
+     AvFormatDecoder *nd = (AvFormatDecoder *)(s->opaque);
+     VideoFrame *frame = (VideoFrame *)pic->opaque;
+   
+     ((VideoOutputXvMC*)nd->m_parent->getVideoOutput())->FieldStart(s, frame, data);
+ }
+ void render_qmatrix_load_xvmc(struct AVCodecContext *s, const AVFrame *pic, void* data)
+ {
+     AvFormatDecoder *nd = (AvFormatDecoder *)(s->opaque);
+     VideoFrame *frame = (VideoFrame *)pic->opaque;
+   
+     ((VideoOutputXvMC*)nd->m_parent->getVideoOutput())->QmatrixLoad(s, frame, data);
+ }
+ #endif
+ 
  void render_slice_xvmc(struct AVCodecContext *s, const AVFrame *src, 
                         int offset[4], int y, int type, int height)
  {
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/avformatdecoder.h mythtv-0.15.1.xvmc/libs/libmythtv/avformatdecoder.h
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/avformatdecoder.h	2004-05-20 08:09:01.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/avformatdecoder.h	2004-09-03 16:22:11.000000000 +0100
***************
*** 73,78 ****
--- 73,82 ----
      friend void release_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
      friend void render_slice_xvmc(struct AVCodecContext *c, const AVFrame *src, 
                                    int offset[4], int y, int type, int height);
+ #if USING_XVMC_VLD
+     friend void render_qmatrix_load_xvmc(struct AVCodecContext *s, const AVFrame *pic, void* data);
+     friend void render_field_start_xvmc(struct AVCodecContext *s, const AVFrame *pic, void* data);
+ #endif
  
      friend int get_avf_buffer_via(struct AVCodecContext *c, AVFrame *pic);
      friend void release_avf_buffer_via(struct AVCodecContext *c, AVFrame *pic);
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/NuppelVideoPlayer.cpp mythtv-0.15.1.xvmc/libs/libmythtv/NuppelVideoPlayer.cpp
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/NuppelVideoPlayer.cpp	2004-05-20 08:09:01.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/NuppelVideoPlayer.cpp	2004-09-04 12:02:24.716842000 +0100
***************
*** 392,397 ****
--- 392,398 ----
                            widget->height(), 0);
  
  #ifdef USING_XVMC
+ 	// BEAM XvMcVld TODO ???
          // We must tell the AvFormatDecoder whether we are using
          // an IDCT or MC pixel format.
          if (kVideoOutput_XvMC == forceVideoOutput) 
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/videoout_xvmc.cpp mythtv-0.15.1.xvmc/libs/libmythtv/videoout_xvmc.cpp
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/videoout_xvmc.cpp	2004-05-20 08:09:02.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/videoout_xvmc.cpp	2004-09-03 19:35:53.000000000 +0100
***************
*** 1,3 ****
--- 1,15 ----
+ /******************************************************************************************************
+  *
+  * Videoout_xvmc.cpp
+  *
+  * This file is part of MythTv.
+  *
+  * Modified: 3.9/04, Terry Barnaby
+  *	Added support for the VIA XvMC VLD X-Windows extension
+  *	that supports the Hardware MPEG decoding engine in the Via Unichrome Chipset.
+  *
+  ******************************************************************************************************
+  */
  #include <cstdio>
  #include <cstdlib>
  #include <cstring>
***************
*** 35,40 ****
--- 47,58 ----
  #define XMD_H 1
  #include <X11/extensions/xf86vmode.h>
  
+ #ifdef USING_XVMC_VLD
+ extern "C" {
+ #include "X11/extensions/viaXvMC.h"
+ }
+ #endif
+ 
  extern "C" {
  #include <X11/extensions/Xinerama.h>
  
***************
*** 43,48 ****
--- 61,71 ----
  extern XvImage  *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
  }
  
+ #if USING_XVMC_VLD
+ // #define dprintf(fmt, a...)	printf(fmt, ##a)
+ #define dprintf(fmt, a...)
+ #endif
+ 
  const int kNumBuffers = 7;
  const int kPrebufferFrames = 4;
  const int kNeedFreeFrames = 2;
***************
*** 191,196 ****
--- 214,220 ----
  
      XvAdaptorInfo *ai;
  
+     dprintf("BEAM: %s: Start\n", __FUNCTION__);
      VideoOutput::InitBuffers(kNumBuffers, false, kNeedFreeFrames,
                               kPrebufferFrames, kKeepPrebuffer);
      VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh, 
***************
*** 282,297 ****
  
                  XvPortID p = 0;
                  int s;
                  XvMCSurfaceTypes::find(width, height, chroma,
!                                        true, 2, 0, 0,
                                         data->XJ_disp, ai[i].base_id,
                                         ai[i].base_id + ai[i].num_ports - 1,
                                         p, s);
                  if (0 == p) 
                  {
                      // No IDCT surface found, try to find MC surface
                      XvMCSurfaceTypes::find(width, height, chroma,
!                                            false, 2, 0, 0,
                                             data->XJ_disp, ai[i].base_id,
                                             ai[i].base_id + ai[i].num_ports - 1,
                                             p, s);
--- 306,334 ----
  
                  XvPortID p = 0;
                  int s;
+ 		
+ 		// Find VLD Surface if possible first
                  XvMCSurfaceTypes::find(width, height, chroma,
!                                        true, false, 2, 0, 0,
                                         data->XJ_disp, ai[i].base_id,
                                         ai[i].base_id + ai[i].num_ports - 1,
                                         p, s);
+ 		
+                 if (0 == p) 
+                 {
+                     // No VLD surface found, try to find IDCT surface
+ 	                XvMCSurfaceTypes::find(width, height, chroma,
+ 	                                       false, true, 2, 0, 0,
+ 	                                       data->XJ_disp, ai[i].base_id,
+ 	                                       ai[i].base_id + ai[i].num_ports - 1,
+ 	                                       p, s);
+ 		}
+ 
                  if (0 == p) 
                  {
                      // No IDCT surface found, try to find MC surface
                      XvMCSurfaceTypes::find(width, height, chroma,
!                                            false, false, 2, 0, 0,
                                             data->XJ_disp, ai[i].base_id,
                                             ai[i].base_id + ai[i].num_ports - 1,
                                             p, s);
***************
*** 312,317 ****
--- 349,355 ----
                  XvFreeAdaptorInfo(ai);
          }
      }
+     dprintf("BEAM: %s: Port: %d\n", __FUNCTION__, xv_port);
  
  #ifndef QWS
      GetMythTVGeometry(data->XJ_disp, XJ_screen_num,
***************
*** 353,359 ****
      {
          for (int i = 0; i < num_subpic; i++)
          {
!             if (xvfmv[i].id == GUID_IA44)
              {
                  data->ia44 = true;
                  data->subpicture_info = xvfmv[i];
--- 391,397 ----
      {
          for (int i = 0; i < num_subpic; i++)
          {
!             if (0 && xvfmv[i].id == GUID_IA44)
              {
                  data->ia44 = true;
                  data->subpicture_info = xvfmv[i];
***************
*** 434,444 ****
--- 472,484 ----
  
      XJ_started = true;
  
+     dprintf("BEAM: %s: End\n", __FUNCTION__);
      return true;
  }
  
  bool VideoOutputXvMC::CreateXvMCBuffers(void)
  {
+     int rez = 0;
      int ret = XvMCCreateContext(data->XJ_disp, xv_port, data->mode_id, 
                                  XJ_width, XJ_height, XVMC_DIRECT, &(data->ctx));
  
***************
*** 457,489 ****
          return false;
      }
  
      int numblocks = ((XJ_width + 15) / 16) * ((XJ_height + 15) / 16);
      int blocks_per_macroblock = 6;
  
!     for (int i = 0; i < 8; i++)
!     {
!         ret = XvMCCreateBlocks(data->XJ_disp, &data->ctx,
!                                numblocks * blocks_per_macroblock,
!                                &(data->data_blocks[i]));
!         if (ret != Success)
          {
!             cerr << "Unable to create XvMC Blocks\n";
!             XvMCDestroyContext(data->XJ_disp, &data->ctx);
!             return false;
!         }
  
!         ret = XvMCCreateMacroBlocks(data->XJ_disp, &data->ctx, numblocks,
!                                     &(data->mv_blocks[i]));
!         if (ret != Success)
!         {
!             cerr << "Unable to create XvMC Macro Blocks\n";
!             XvMCDestroyBlocks(data->XJ_disp,&(data->data_blocks[i]));
!             XvMCDestroyContext(data->XJ_disp, &data->ctx);
!             return false;
          }
      }
  
-     int rez = 0;
      for (int i = 0; i < numbuffers; i++)
      {
          XvMCSurface *surface = new XvMCSurface;
--- 497,533 ----
          return false;
      }
  
+     dprintf("BEAM: %s: HasVldAcceleration: %d\n", __FUNCTION__, hasVLDAcceleration());
+     dprintf("BEAM: %s: NumBuffers: %d\n", __FUNCTION__, numbuffers);
+ 
      int numblocks = ((XJ_width + 15) / 16) * ((XJ_height + 15) / 16);
      int blocks_per_macroblock = 6;
  
!     if(!hasVLDAcceleration()){
!         for (int i = 0; i < 8; i++)
          {
!             ret = XvMCCreateBlocks(data->XJ_disp, &data->ctx,
!                                    numblocks * blocks_per_macroblock,
!                                    &(data->data_blocks[i]));
!             if (ret != Success)
!             {
!                 cerr << "Unable to create XvMC Blocks\n";
!                 XvMCDestroyContext(data->XJ_disp, &data->ctx);
!                 return false;
!             }
  
!             ret = XvMCCreateMacroBlocks(data->XJ_disp, &data->ctx, numblocks,
!                                         &(data->mv_blocks[i]));
!             if (ret != Success)
!             {
!                 cerr << "Unable to create XvMC Macro Blocks\n";
!                 XvMCDestroyBlocks(data->XJ_disp,&(data->data_blocks[i]));
!                 XvMCDestroyContext(data->XJ_disp, &data->ctx);
!                 return false;
!             }
          }
      }
  
      for (int i = 0; i < numbuffers; i++)
      {
          XvMCSurface *surface = new XvMCSurface;
***************
*** 494,500 ****
              cerr << "unable to create: " << i << " buffer\n";
              break;
          }
!                                 
          xvmc_render_state_t *render = new xvmc_render_state_t;
          memset(render, 0, sizeof(xvmc_render_state_t));
  
--- 538,544 ----
              cerr << "unable to create: " << i << " buffer\n";
              break;
          }
! 
          xvmc_render_state_t *render = new xvmc_render_state_t;
          memset(render, 0, sizeof(xvmc_render_state_t));
  
***************
*** 522,527 ****
--- 566,572 ----
          vbuffers[i].codec = FMT_XVMC_IDCT_MPEG2;
      }
  
+ 
      data->subpicture_clear_color = 0;
  
      rez = XvMCCreateSubpicture(data->XJ_disp, &data->ctx, &data->subpicture,
***************
*** 586,591 ****
--- 631,637 ----
  
      data->p_render_surface_to_show = NULL;
      data->p_render_surface_visible = NULL;
+     dprintf("BEAM: %s: End\n", __FUNCTION__);
      return true;
  }
  
***************
*** 605,614 ****
  
  void VideoOutputXvMC::DeleteXvMCBuffers()
  {
!     for (int i = 0; i < 8; i++)
!     {
!         XvMCDestroyMacroBlocks(data->XJ_disp, &data->mv_blocks[i]);
!         XvMCDestroyBlocks(data->XJ_disp, &data->data_blocks[i]);
      }
  
      for (int i = 0; i < numbuffers; i++)
--- 651,662 ----
  
  void VideoOutputXvMC::DeleteXvMCBuffers()
  {
!     if(!hasVLDAcceleration()){
!         for (int i = 0; i < 8; i++)
!         {
!             XvMCDestroyMacroBlocks(data->XJ_disp, &data->mv_blocks[i]);
!             XvMCDestroyBlocks(data->XJ_disp, &data->data_blocks[i]);
!         }
      }
  
      for (int i = 0; i < numbuffers; i++)
***************
*** 773,782 ****
          data->curosd = osdframe;
          render->p_osd_target_surface_render = NULL;
      }
!    
      pthread_mutex_unlock(&lock);
  }
  
  void VideoOutputXvMC::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
  {
      (void)x;
--- 821,899 ----
          data->curosd = osdframe;
          render->p_osd_target_surface_render = NULL;
      }
! 
      pthread_mutex_unlock(&lock);
  }
  
+ #if USING_XVMC_VLD
+ void bhd(void* data, int nbytes){
+ 	uint8_t*	p = (uint8_t*)data;
+ 	int		n;
+ 	
+ 	for(n = 0; n < nbytes; n++){
+ 		printf("%2.2x ", *p++);
+ 		if((n % 16) == 15)
+ 			printf("\n");
+ 	}
+ 	if((n % 16) != 15)
+ 		printf("\n");
+ }
+ 
+ void bprint_XvMCMpegControl(XvMCMpegControl* p){
+ 	printf("XvMCMpegControl:\n");
+ 	printf("BVMV_range:\t%x\n", p->BVMV_range);
+ 	printf("BHMV_range:\t%x\n", p->BHMV_range);
+ 	printf("FVMV_range:\t%x\n", p->FVMV_range);
+ 	printf("FHMV_range:\t%x\n", p->FHMV_range);
+ 	printf("picture_structure:\t%x\n", p->picture_structure);
+ 	printf("intra_dc_precision:\t%x\n", p->intra_dc_precision);
+ 	printf("picture_coding_type:\t%x\n", p->picture_coding_type);
+ 	printf("mpeg_coding:\t%x\n", p->mpeg_coding);
+ 	printf("flags:\t%x\n", p->flags);
+ 	printf("Progresive(%d), AlternateScan(%d), PredDctFrame(%d), TopFieldFirst(%d)\n",
+ 		(p->flags&XVMC_PROGRESSIVE_SEQUENCE)==XVMC_PROGRESSIVE_SEQUENCE,
+ 		(p->flags&XVMC_ALTERNATE_SCAN)==XVMC_ALTERNATE_SCAN,
+ 		(p->flags&XVMC_PRED_DCT_FRAME)==XVMC_PRED_DCT_FRAME,
+ 		(p->flags&XVMC_TOP_FIELD_FIRST)==XVMC_TOP_FIELD_FIRST);
+ 	printf("ConcealMotionVect(%d), QscaleType(%d), IntraVlcFormat(%d)\n",
+ 		(p->flags&XVMC_CONCEALMENT_MOTION_VECTORS)==XVMC_CONCEALMENT_MOTION_VECTORS,
+ 		(p->flags&XVMC_Q_SCALE_TYPE)==XVMC_Q_SCALE_TYPE,
+ 		(p->flags&XVMC_INTRA_VLC_FORMAT)==XVMC_INTRA_VLC_FORMAT);
+ }
+ 
+ 
+ void VideoOutputXvMC::FieldStart(struct AVCodecContext *avContext, VideoFrame *frame, void* v){
+     (void)avContext;
+     XvMCMpegControl*		control = (XvMCMpegControl*)v;
+     xvmc_render_state_t*	render = (xvmc_render_state_t *)frame->buf;
+     Status			status;
+     
+     dprintf("BEAM: %s: This: %p\n", __FUNCTION__, this);
+     dprintf("BEAM: %s: Surfaces: %p,%p,%p\n", __FUNCTION__, render->p_surface, render->p_past_surface, render->p_future_surface);
+ //  bprint_XvMCMpegControl(control);
+ 
+     status = XvMCBeginSurface(data->XJ_disp, &data->ctx, render->p_surface, render->p_past_surface, render->p_future_surface, control);
+     if(status){
+     	fprintf(stderr, "XvMCBeginSurface: Error: %d\n", status);
+     }
+     dprintf("BEAM: %s: End\n", __FUNCTION__);
+ }
+ 
+ void VideoOutputXvMC::QmatrixLoad(struct AVCodecContext *avContext, VideoFrame *frame, void* v){
+     (void)avContext;
+     (void)frame;
+     XvMCQMatrix*		qmatrix = (XvMCQMatrix*)v;
+     Status			status;
+ 
+     dprintf("BEAM: %s: This: %p\n", __FUNCTION__, this);
+     
+     status = XvMCLoadQMatrix(data->XJ_disp, &data->ctx, qmatrix);
+     if(status){
+         fprintf(stderr, "XvMCLoadQMatrix: Error: %d\n", status);
+     }
+ }
+ #endif
+ 
  void VideoOutputXvMC::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
  {
      (void)x;
***************
*** 787,812 ****
      xvmc_render_state_t *render = (xvmc_render_state_t *)frame->buf;
  
      pthread_mutex_lock(&lock);
! 
!     if (render->p_past_surface != NULL)
!         SyncSurface(data->XJ_disp, render->p_past_surface);
!     if (render->p_future_surface != NULL)
!         SyncSurface(data->XJ_disp, render->p_future_surface);
! 
!     int res = XvMCRenderSurface(data->XJ_disp, &data->ctx, 
!                                 render->picture_structure, render->p_surface,
!                                 render->p_past_surface, 
!                                 render->p_future_surface,
!                                 render->flags, render->filled_mv_blocks_num,
!                                 render->start_mv_blocks_num,
!                                 (XvMCMacroBlockArray *)frame->priv[1], 
!                                 (XvMCBlockArray *)frame->priv[0]);
!     if (res != Success)
!     {
!         cerr << "XvMCRenderSurface error\n";
      }
  
!     XvMCFlushSurface(data->XJ_disp, render->p_surface);
  
      pthread_mutex_unlock(&lock);
  
--- 904,944 ----
      xvmc_render_state_t *render = (xvmc_render_state_t *)frame->buf;
  
      pthread_mutex_lock(&lock);
!     
!     if(hasVLDAcceleration()){
! #if USING_XVMC_VLD
!         Status status;
! 
! 	dprintf("BEAM: %s: Slice: %p SliceCode: %x SliceLen: %d\n", __FUNCTION__, render, render->slice_code, render->slice_datalen);
! //	bhd(render->slice_data, render->slice_datalen);
!         status = XvMCPutSlice2(data->XJ_disp, &data->ctx, (char*)render->slice_data, render->slice_datalen, render->slice_code);
! 	if(status){
! 		printf("XvMCPutSlice: Error: %d\n", status);
! 	}
! //	dprintf("BEAM: %s: End\n", __FUNCTION__);
! #endif
      }
+     else {
+         if (render->p_past_surface != NULL)
+             SyncSurface(data->XJ_disp, render->p_past_surface);
+         if (render->p_future_surface != NULL)
+             SyncSurface(data->XJ_disp, render->p_future_surface);
+ 
+         int res = XvMCRenderSurface(data->XJ_disp, &data->ctx, 
+                                     render->picture_structure, render->p_surface,
+                                     render->p_past_surface, 
+                                     render->p_future_surface,
+                                     render->flags, render->filled_mv_blocks_num,
+                                     render->start_mv_blocks_num,
+                                     (XvMCMacroBlockArray *)frame->priv[1], 
+                                     (XvMCBlockArray *)frame->priv[0]);
+         if (res != Success)
+         {
+             cerr << "XvMCRenderSurface error\n";
+         }
  
!         XvMCFlushSurface(data->XJ_disp, render->p_surface);
!     }
  
      pthread_mutex_unlock(&lock);
  
***************
*** 863,868 ****
--- 995,1002 ----
      xvmc_render_state_t *render = (xvmc_render_state_t *)frame->buf;
      render->p_osd_target_surface_render = NULL;
  
+ printf("BEAM: %s %p mode: %d\n", __FUNCTION__, osd, data->subpicture_mode);
+ 
      if (osd)
      {
          if (data->subpicture_mode == BLEND_SUBPICTURE ||
***************
*** 873,878 ****
--- 1007,1013 ----
                  tmpframe.codec = FMT_IA44;
              else
                  tmpframe.codec = FMT_AI44;
+ 
              tmpframe.buf = (unsigned char *)(data->xvimage->data);
  
              int ret = DisplayOSD(&tmpframe, osd);
***************
*** 909,915 ****
                                      &data->subpicture, 0, 0, XJ_width,
                                      XJ_height, 0, 0, XJ_width, XJ_height);
              }
!             
              pthread_mutex_unlock(&lock);
          }
      }
--- 1044,1050 ----
                                      &data->subpicture, 0, 0, XJ_width,
                                      XJ_height, 0, 0, XJ_width, XJ_height);
              }
! 
              pthread_mutex_unlock(&lock);
          }
      }
***************
*** 984,986 ****
--- 1119,1129 ----
      return XVMC_IDCT == (data->surface_info.mc_type & XVMC_IDCT);
  }
  
+ bool VideoOutputXvMC::hasVLDAcceleration() const 
+ {
+ #if USING_XVMC_VLD
+     return XVMC_VLD == (data->surface_info.mc_type & XVMC_VLD);
+ #else
+     return 0;
+ #endif
+ }
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/videoout_xvmc.h mythtv-0.15.1.xvmc/libs/libmythtv/videoout_xvmc.h
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/videoout_xvmc.h	2004-05-20 08:09:02.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/videoout_xvmc.h	2004-09-03 16:22:51.000000000 +0100
***************
*** 25,30 ****
--- 25,34 ----
  
      int GetRefreshRate(void);
  
+ #if USING_XVMC_VLD
+     void QmatrixLoad(struct AVCodecContext *avContext, VideoFrame *frame, void* data);
+     void FieldStart(struct AVCodecContext *avContext, VideoFrame *frame, void* data);
+ #endif
      void DrawSlice(VideoFrame *frame, int x, int y, int w, int h);
  
      void DrawUnusedRects(void);
***************
*** 39,44 ****
--- 43,49 ----
      int ChangePictureAttribute(int attributeType, int newValue);
  
      bool hasIDCTAcceleration() const;
+     bool hasVLDAcceleration() const;
  
    private:
      void Exit(void);
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/libs/libmythtv/XvMCSurfaceTypes.h mythtv-0.15.1.xvmc/libs/libmythtv/XvMCSurfaceTypes.h
*** mythtv-0.15.1.orig.rpm/libs/libmythtv/XvMCSurfaceTypes.h	2004-05-20 08:09:01.000000000 +0100
--- mythtv-0.15.1.xvmc/libs/libmythtv/XvMCSurfaceTypes.h	2004-09-01 13:45:14.000000000 +0100
***************
*** 7,12 ****
--- 7,15 ----
  
  extern "C" {
  #include "../libavcodec/xvmc_render.h"
+ #ifdef USING_XVMC_VLD
+ #include <X11/extensions/viaXvMC.h>
+ #endif
  }
  
  class XvMCSurfaceTypes 
***************
*** 23,29 ****
      }
  
      /// Find an appropriate surface on the current port.
!     inline int find(int pminWidth, int pminHeight, int chroma, bool idct, 
                      int mpeg, int pminSubpictureWidth, 
                      int pminSubpictureHeight);
          
--- 26,32 ----
      }
  
      /// Find an appropriate surface on the current port.
!     inline int find(int pminWidth, int pminHeight, int chroma, bool vld, bool idct, 
                      int mpeg, int pminSubpictureWidth, 
                      int pminSubpictureHeight);
          
***************
*** 79,84 ****
--- 82,94 ----
          return XVMC_IDCT == (surfaces[surface].mc_type & XVMC_IDCT);
      }
  
+ #ifdef USING_XVMC_VLD
+     bool hasVLDAcceleration(int surface) const 
+     {
+         return XVMC_VLD == (surfaces[surface].mc_type & XVMC_VLD);
+     }
+ #endif
+ 
      bool hasMPEG1Support(int surface) const 
      {
          return XVMC_MPEG_1 == (surfaces[surface].mc_type & 0x7);
***************
*** 132,138 ****
      int size() const { return num; }
  
      /// Find an appropriate surface on the current display.
!     static inline void find(int minWidth, int minHeight, int chroma, bool idct,
                              int mpeg, int minSubpictureWidth, 
                              int minSubpictureHeight, Display *dpy, 
                              XvPortID portMin, XvPortID portMax,
--- 142,148 ----
      int size() const { return num; }
  
      /// Find an appropriate surface on the current display.
!     static inline void find(int minWidth, int minHeight, int chroma, bool vld, bool idct,
                              int mpeg, int minSubpictureWidth, 
                              int minSubpictureHeight, Display *dpy, 
                              XvPortID portMin, XvPortID portMax,
***************
*** 185,191 ****
  }
  
  inline int XvMCSurfaceTypes::find(int pminWidth, int pminHeight, 
!                                   int chroma, bool idct, int mpeg,
                                    int pminSubpictureWidth,
                                    int pminSubpictureHeight) 
  {
--- 195,201 ----
  }
  
  inline int XvMCSurfaceTypes::find(int pminWidth, int pminHeight, 
!                                   int chroma, bool vld, bool idct, int mpeg,
                                    int pminSubpictureWidth,
                                    int pminSubpictureHeight) 
  {
***************
*** 194,199 ****
--- 204,210 ----
      
      for (int s = 0; s < size(); s++) 
      {
+ printf("BEAM: %s: Surface: %d Type: %x\n", __FUNCTION__, s, surfaces[s].mc_type);
          if (pminWidth > maxWidth(s))
              continue;
          if (pminHeight > maxHeight(s))
***************
*** 204,209 ****
--- 215,226 ----
              continue;
          if (!idct && hasIDCTAcceleration(s))
              continue;
+ #ifdef USING_XVMC_VLD
+         if (vld && !hasVLDAcceleration(s))
+             continue;
+         if (!vld && hasVLDAcceleration(s))
+             continue;
+ #endif
          if (1 == mpeg && !hasMPEG1Support(s))
              continue;
          if (2 == mpeg && !hasMPEG2Support(s))
***************
*** 224,230 ****
  }
  
  inline void XvMCSurfaceTypes::find(int minWidth, int minHeight,
!                                    int chroma, bool idct, int mpeg,
                                     int minSubpictureWidth, 
                                     int minSubpictureHeight,
                                     Display *dpy, XvPortID portMin, 
--- 241,247 ----
  }
  
  inline void XvMCSurfaceTypes::find(int minWidth, int minHeight,
!                                    int chroma, bool vld, bool idct, int mpeg,
                                     int minSubpictureWidth, 
                                     int minSubpictureHeight,
                                     Display *dpy, XvPortID portMin, 
***************
*** 244,250 ****
      {
          VERBOSE(VB_PLAYBACK, QString("Trying XvMC port %1").arg(p));
          XvMCSurfaceTypes surf(dpy, p);
!         int s = surf.find(minWidth, minHeight, chroma, idct, mpeg,
                            minSubpictureWidth, minSubpictureHeight);
          if (s >= 0) 
          {
--- 261,267 ----
      {
          VERBOSE(VB_PLAYBACK, QString("Trying XvMC port %1").arg(p));
          XvMCSurfaceTypes surf(dpy, p);
!         int s = surf.find(minWidth, minHeight, chroma, vld, idct, mpeg,
                            minSubpictureWidth, minSubpictureHeight);
          if (s >= 0) 
          {
***************
*** 292,298 ****
          if (ai[i].type == 0)
              continue;
          XvMCSurfaceTypes::find(width, height, chroma,
!                                true, 2, 0, 0,
                                 disp, ai[i].base_id, 
                                 ai[i].base_id + ai[i].num_ports - 1,
                                 p, s);
--- 309,315 ----
          if (ai[i].type == 0)
              continue;
          XvMCSurfaceTypes::find(width, height, chroma,
!                                false, true, 2, 0, 0,
                                 disp, ai[i].base_id, 
                                 ai[i].base_id + ai[i].num_ports - 1,
                                 p, s);
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/programs/mythfrontend/globalsettings.cpp mythtv-0.15.1.xvmc/programs/mythfrontend/globalsettings.cpp
*** mythtv-0.15.1.orig.rpm/programs/mythfrontend/globalsettings.cpp	2004-05-31 02:21:54.000000000 +0100
--- mythtv-0.15.1.xvmc/programs/mythfrontend/globalsettings.cpp	2004-09-03 19:40:50.000000000 +0100
***************
*** 1914,1919 ****
--- 1914,1930 ----
  };
  #endif
  
+ #ifdef USING_XVMC_VLD
+ class UseXvMcVld: public CheckBoxSetting, public GlobalSetting {
+ public:
+     UseXvMcVld(): GlobalSetting("UseXvMcVld") {
+         setLabel(QObject::tr("Use HW XVMC VLD Decoding (Via only)"));
+         setValue(true);
+         setHelpText(QObject::tr("Enables the use of viaXvMC HW Mpeg decoding for the Via Unichome Chipset"));
+     };
+ };
+ #endif
+ 
  #ifdef USING_VIASLICE
  class UseViaSlice: public CheckBoxSetting, public GlobalSetting {
  public:
***************
*** 1944,1949 ****
--- 1955,1963 ----
  
           addTarget("0", new VerticalConfigurationGroup(true));
  
+ #ifdef USING_XVMC_VLD
+          addChild(new UseXvMcVld());
+ #endif
  #ifdef USING_XVMC
           addChild(new UseXVMC());
  #endif
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/README.viaXvMc mythtv-0.15.1.xvmc/README.viaXvMc
*** mythtv-0.15.1.orig.rpm/README.viaXvMc	1970-01-01 01:00:00.000000000 +0100
--- mythtv-0.15.1.xvmc/README.viaXvMc	2004-09-04 11:44:36.517672000 +0100
***************
*** 0 ****
--- 1,81 ----
+ 	Using The Unichome Projects viaXvMC Hardware MPEG Interface with MythTv
+ 	-----------------------------------------------------------------------
+ 
+ Date:	3/9/04
+ Author:	Terry Barnaby
+ 
+ Introduction
+ ------------
+ There is no generic MPEG interface to the Linux/Unix X-Window system at this
+ time. There are a few vender/project extentions that support Hardware MPEG
+ Decoders, but none are as yet generic enough to be hardware independent.
+ There was a special HW interface to the Via CLE266 Unichrome chipset available
+ based on libddmpeg. This however required root access and accessed the
+ HW Mpeg engine in a very device specific manner.
+ Thomas Hellström, of the Unichome project has developed an extension to the
+ X-Windows XvMC interface that provides the ability to drive a HW MPeg controller.
+ Although this is still Via specific, it is much much better and closer to a
+ generic X-Server MPEG API.
+ This describes how to build and use MythTv with the Unichome Projects viaXvMC
+ interface library which provides a Hardware MPEG decoding implementation.
+ 
+ Required Bits
+ -------------
+ In order for this to work your system requires the following:
+ 
+ 	1. Recent Via DRM module
+ 	2. Recent Unichrome Via X-Server driver. Tested with release r25.
+ 	3. Recent Unichrome viaXvMC library.
+ 
+ Patching MythTV sources
+ -----------------------
+ The Mythtv-viaXvMC-beam-0.1.patch should be applied to a clean set of
+ Mythtv-0.15.1 sources using the command: "patch -p1 -s < mythtv-beam-viaxvmc-1.patch"
+ performed within the top level directory of the MythTv source.
+ 
+ Configuration for Build
+ ----------------------
+ In the file "settings.pro" the lines under the comment "XvMC_VLD support"
+ should be uncommented. MythTv can now be build as normal.
+ Note that as, at the moment, there is a separate libXvMC interface library
+ for each specific hardware type only one libXvMC library can be linked
+ at a time into MythTV. Thus  -lXvMCNVIDIA and -lviaXvMC cannot be
+ configured to be linked in the same build.
+ 
+ Configuration for Run
+ ---------------------
+ There is a toggle button in the "TV Player" settings screen titled
+ "Use HW XVMC VLD Decoding (Via only)". This should be set to enable
+ the viaXvMC HW Mpeg decoding.
+ 
+ Issues
+ ------
+ 1. The OSD is not working properly as yet.
+ 2. The MPEG Qmatrix may not be set up correctly. This may lead to blockiness.
+ 3. Some CPU usage performance gains could be had.
+ 4. There should be some calls to viaXvMC at the end of each MPEG picture.
+ 
+ Test Environment
+ ----------------
+ I have tested this in the following environment:
+ 
+ Hardware:	Via M10000 Motherboard with 256M RAM, Network boot/NFSRoot
+ Software OS:	Fedora 2 with updates to date
+ Software:	MythTv and dependentcies installed from ATRPMS using yum.
+ Kernel:		Standard 2.6.7 Linux kernel, with latest DRM from CVS
+ 		configured for VIA Motherboard.
+ X-Driver:	Unichrome Via driver from CVS.
+ ViaXvMC:	Unichrome Via XvMC library from CVS.
+ MythTv:		MythTv 0.15.1 as patched for ATRPMS and with mythtv-beam-viaxvmc-1.patch patch
+ 
+ Performance
+ -----------
+ With this system a Via M10000 system can decode and display an DVB MPEG2 stream
+ using about 20% CPU rather than about 60% with software decode and Xv picture
+ display.
+ 
+ Web Links
+ ---------
+ Unichrome Project:	http://unichrome.sourceforge.net
+ DRM:			http://sourceforge.net/projects/dri
+ ATRPMS:			http://atrpms.net
diff -cr --new-file --exclude='ERR?' --exclude=Makefile --exclude=config.mak --exclude=config.h --exclude=mysql.txt --exclude=settings.pro.beam --exclude=settings.pro.rpm mythtv-0.15.1.orig.rpm/settings.pro mythtv-0.15.1.xvmc/settings.pro
*** mythtv-0.15.1.orig.rpm/settings.pro	2004-09-04 11:47:11.684760864 +0100
--- mythtv-0.15.1.xvmc/settings.pro	2004-09-04 11:47:42.411589000 +0100
***************
*** 65,70 ****
--- 65,75 ----
  #DEFINES += USING_XVMC
  #EXTRA_LIBS += -lXvMCNVIDIA -lXvMC
  
+ # XvMC_VLD support, modify as necessary.
+ #CONFIG += using_xvmc using_xvmc_vld
+ #DEFINES += USING_XVMC USING_XVMC_VLD
+ #EXTRA_LIBS += -lviaXvMC -lXvMC
+ 
  # VIA cle266 support
  #CONFIG += using_viahwslice
  #DEFINES += USING_VIASLICE
