Sophie

Sophie

distrib > Arklinux > devel > i586 > by-pkgid > 9482443bfa78fcd0975e9204e634806b > files > 25

mplayer-1.0-0.svn34182.1ark.src.rpm

--- mplayer/Makefile.unichrome~	2007-02-25 01:30:32.000000000 +0100
+++ mplayer/Makefile	2007-02-25 01:30:32.000000000 +0100
@@ -62,6 +62,10 @@
               libswscale/libswscale.a \
               libvo/libosd.a \
 
+ifeq ($(HAVE_XVMC_ACCEL), yes)
+COMMON_LIBS += -lXvMC -lXvMCW
+endif
+
 LIBS_MPLAYER = libvo/libvo.a \
                libao2/libao2.a \
                input/libinput.a \
--- mplayer/libavcodec/mpeg12.c.unichrome~	2007-02-09 22:07:26.000000000 +0100
+++ mplayer/libavcodec/mpeg12.c	2007-02-25 01:30:32.000000000 +0100
@@ -85,10 +85,16 @@
 extern void XVMC_init_block(MpegEncContext *s);//set s->block
 #endif
 
+#ifdef HAVE_XVMC_VLD
+extern int XVMC_decode_slice(MpegEncContext *s, int start_code,
+		uint8_t *buffer, int buf_size);
+#endif
+
 static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,-1};
 static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,-1};
 static const enum PixelFormat pixfmt_yuv_444[]= {PIX_FMT_YUV444P,-1};
 static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {
+                                           PIX_FMT_XVMC_MPEG2_VLD,
                                            PIX_FMT_XVMC_MPEG2_IDCT,
                                            PIX_FMT_XVMC_MPEG2_MC,
                                            -1};
@@ -2558,6 +2564,16 @@
         return -1;
     }
 
+#ifdef HAVE_XVMC_VLD
+    if (s->avctx->xvmc_acceleration == 4){
+        int used = XVMC_decode_slice(s, mb_y, *buf, buf_size);
+        if (used < 0)
+            return DECODE_SLICE_ERROR;
+        *buf += used - 1;
+        return DECODE_SLICE_OK;
+    }
+#endif
+
     init_get_bits(&s->gb, *buf, buf_size*8);
 
     ff_mpeg1_clean_buffers(s);
@@ -3512,7 +3528,42 @@
 };
 #endif /* !CONFIG_MPEGVIDEO_PARSER */
 
-/* this is ugly i know, but the alternative is too make
+#ifdef HAVE_XVMC_VLD
+static int mpeg_xxmc_decode_init(AVCodecContext *avctx){
+    Mpeg1Context *s;
+    if( avctx->thread_count > 1)
+        return -1;
+    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->pix_fmt = PIX_FMT_XVMC_MPEG2_VLD;
+    avctx->xvmc_acceleration = 4;
+
+    return 0;
+}
+
+AVCodec mpeg_xxmc_decoder = {
+    "mpegvideo_xvmc",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MPEG2VIDEO_XVMC,
+    sizeof(Mpeg1Context),
+    mpeg_xxmc_decode_init,
+    NULL,
+    mpeg_decode_end,
+    mpeg_decode_frame,
+    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL,
+    .flush= ff_mpeg_flush,
+};
+
+#endif
+
+
+/* this is ugly i know, but the alternative is too make 
    hundreds of vars global and prefix them with ff_mpeg1_
    which is far uglier. */
 #include "mdec.c"
--- mplayer/libavcodec/avcodec.h.unichrome~	2007-02-25 01:30:32.000000000 +0100
+++ mplayer/libavcodec/avcodec.h	2007-02-25 01:31:31.000000000 +0100
@@ -2267,6 +2267,7 @@
 extern AVCodec mpeg4_decoder;
 extern AVCodec mpeg4aac_decoder;
 extern AVCodec mpeg_xvmc_decoder;
+extern AVCodec mpeg_xxmc_decoder;
 extern AVCodec mpegvideo_decoder;
 extern AVCodec msmpeg4v1_decoder;
 extern AVCodec msmpeg4v2_decoder;
--- mplayer/libavcodec/allcodecs.c.unichrome~	2007-02-25 01:30:32.000000000 +0100
+++ mplayer/libavcodec/allcodecs.c	2007-02-25 01:32:07.000000000 +0100
@@ -95,6 +95,9 @@
     REGISTER_DECODER(MJPEGB, mjpegb);
     REGISTER_DECODER(MMVIDEO, mmvideo);
     REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc);
+#ifdef HAVE_XVMC_VLD
+    REGISTER_DECODER(MPEG_XVMC, mpeg_xxmc);
+#endif
     REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
     REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
     REGISTER_ENCDEC (MPEG4, mpeg4);
--- mplayer/libavcodec/xvmcvideo.c.unichrome~	2006-11-18 21:06:50.000000000 +0100
+++ mplayer/libavcodec/xvmcvideo.c	2007-02-25 01:30:32.000000000 +0100
@@ -72,11 +72,68 @@
     }
 }
 
+#ifdef HAVE_XVMC_VLD
+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 (B_TYPE==last->pict_type)
+            av_log(s->avctx,AV_LOG_DEBUG, "Past frame is a B frame in findPastSurface, this is bad.\n");
+        //assert(B_TYPE!=last->pict_type);
+    }
+
+    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 (B_TYPE==next->pict_type)
+            av_log(s->avctx,AV_LOG_DEBUG, "Next frame is a B frame in findFutureSurface, thisis bad.\n");
+        //assert(B_TYPE!=next->pict_type);
+    }
+
+    assert(NULL!=next);
+
+    if (next->magic != MP_XVMC_RENDER_MAGIC)
+        return 0;
+
+    return (next->state & MP_XVMC_STATE_PREDICTION) ? next->p_surface : 0;
+}
+#endif //HAVE_XVMC_VLD
+
 //these functions should be called on every new field or/and frame
 //They should be safe if they are called few times for same field!
 int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx){
-xvmc_render_state_t * render,* last, * next;
+    xvmc_render_state_t * render, * last, * next;
+
+#ifdef HAVE_XVMC_VLD
+    XvMCMpegControl     binfo;
+    XvMCQMatrix         qmatrix;
+    int                 i;
+    Status              status;
 
+    memset(&binfo, 0, sizeof(binfo));
+    memset(&qmatrix, 0, sizeof(qmatrix));
+#endif
+    
     assert(avctx != NULL);
 
     render = (xvmc_render_state_t*)s->current_picture.data[2];
@@ -87,12 +144,53 @@
     render->picture_structure = s->picture_structure;
     render->flags = (s->first_field)? 0: XVMC_SECOND_FIELD;
 
+#ifdef HAVE_XVMC_VLD
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        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;
+    }
+    else
+#endif
+    {
 //make sure that all data is drawn by XVMC_end_frame
     assert(render->filled_mv_blocks_num==0);
+    }
 
     render->p_future_surface = NULL;
     render->p_past_surface = NULL;
 
+    render->pict_type = s->pict_type; // for later frame dropping use
+
+#ifdef HAVE_XVMC_VLD
+    if (s->avctx->xvmc_acceleration == 4)
+{
+    switch(s->pict_type){
+        case  I_TYPE:
+            break;
+        case  B_TYPE:
+            render->p_past_surface = findPastSurface(s, render);
+            render->p_future_surface = findFutureSurface(s);
+            if (!render->p_past_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding B frame and past frame is null!");
+            else if (!render->p_future_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding B frame and future frame is null!");
+            break;
+            
+        case  P_TYPE:
+            render->p_past_surface = findPastSurface(s, render);
+            render->p_future_surface = render->p_surface;
+            if (!render->p_past_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding P frame and past frame is null!");
+            break;
+    }
+} else
+#endif
+{
     switch(s->pict_type){
         case  I_TYPE:
             return 0;// no prediction from other frames
@@ -113,8 +211,96 @@
             render->p_past_surface = last->p_surface;
             return 0;
     }
+}
+
+#ifdef HAVE_XVMC_VLD
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        for (i = 0; i < 64; i++){
+        qmatrix.intra_quantiser_matrix[i] = s->intra_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.non_intra_quantiser_matrix[i] = s->inter_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[s->dsp.idct_permutation[i]];
+        }
 
-return -1;
+    qmatrix.load_intra_quantiser_matrix = 1;
+    qmatrix.load_non_intra_quantiser_matrix = 1;
+    qmatrix.load_chroma_intra_quantiser_matrix = 1;
+    qmatrix.load_chroma_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 && !s->progressive_sequence)
+        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:    av_log(avctx, AV_LOG_ERROR, "%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;
+
+    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;
+
+    if (s->codec_id == CODEC_ID_MPEG2VIDEO)
+{
+    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);
+}
+else
+{
+    binfo.FVMV_range = (s->mpeg_f_code[0][0] - 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][1] - 1);
+}
+
+    status = XvMCLoadQMatrix(render->disp, render->ctx, &qmatrix);
+    if (status)
+        av_log(avctx,AV_LOG_ERROR, "XvMCLoadQMatrix: Error: %d\n", status);
+
+    status = XvMCBeginSurface(render->disp, render->ctx, render->p_surface,
+                              render->p_past_surface, render->p_future_surface,
+                              &binfo);
+    if (status)
+        av_log(avctx,AV_LOG_ERROR, "XvMCBeginSurface: Error: %d\n", status);
+
+    if (!status)
+        return 0;
+    }
+#endif
+
+    return -1;
 }
 
 void XVMC_field_end(MpegEncContext *s){
@@ -122,10 +308,22 @@
     render = (xvmc_render_state_t*)s->current_picture.data[2];
     assert(render != NULL);
 
+#ifdef HAVE_XVMC_VLD
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        XvMCFlushSurface(render->disp, render->p_surface);
+        XvMCSyncSurface(render->disp, render->p_surface);
+
+    	s->error_count = 0;
+    }
+    else
+#endif
+    {
     if(render->filled_mv_blocks_num > 0){
 //        printf("xvmcvideo.c: rendering %d left blocks after last slice!!!\n",render->filled_mv_blocks_num );
         ff_draw_horiz_band(s,0,0);
     }
+    }
 }
 
 void XVMC_decode_mb(MpegEncContext *s){
@@ -315,4 +513,50 @@
 
 }
 
+#ifdef HAVE_XVMC_VLD
+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
+
+void XVMC_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;
+
+    if (slicelen < 0)
+    {
+        if ((mb_y == s->mb_height - 1) || 
+            (!s->progressive_sequence && mb_y == (s->mb_height >> 1) -1) ||
+	    (s->codec_id != CODEC_ID_MPEG2VIDEO))
+            slicelen = buf_size;
+        else
+            return;
+    }
+
+    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;
+
+    ff_draw_horiz_band(s, 0, 0);
+}
 #endif
+
+#endif
+
--- mplayer/help/help_mp-en.h.unichrome~	2007-02-24 23:51:47.000000000 +0100
+++ mplayer/help/help_mp-en.h	2007-02-25 01:30:32.000000000 +0100
@@ -1631,6 +1631,7 @@
 #define MSGTR_MPCODECS_DRIFailure "[VD_FFMPEG] DRI failure.\n"
 #define MSGTR_MPCODECS_CouldntAllocateImageForCodec "[VD_FFMPEG] Couldn't allocate image for codec.\n"
 #define MSGTR_MPCODECS_XVMCAcceleratedMPEG2 "[VD_FFMPEG] XVMC-accelerated MPEG-2.\n"
+#define MSGTR_MPCODECS_XVMCVLDAcceleratedMPEG2 "[VD_FFMPEG] XVMC-VLD-accelerated MPEG-2.\n"
 #define MSGTR_MPCODECS_TryingPixfmt "[VD_FFMPEG] Trying pixfmt=%d.\n"
 #define MSGTR_MPCODECS_McGetBufferShouldWorkOnlyWithXVMC "[VD_FFMPEG] The mc_get_buffer should work only with XVMC acceleration!!"
 #define MSGTR_MPCODECS_UnexpectedInitVoError "[VD_FFMPEG] Unexpected init_vo error.\n"
--- mplayer/libavutil/avutil.h.unichrome~	2007-02-09 22:07:22.000000000 +0100
+++ mplayer/libavutil/avutil.h	2007-02-25 01:30:32.000000000 +0100
@@ -88,6 +88,7 @@
     PIX_FMT_YUVJ444P,  ///< Planar YUV 4:4:4, 24bpp, full scale (jpeg)
     PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h)
     PIX_FMT_XVMC_MPEG2_IDCT,
+    PIX_FMT_XVMC_MPEG2_VLD,
     PIX_FMT_UYVY422,   ///< Packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
     PIX_FMT_UYYVYY411, ///< Packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
     PIX_FMT_BGR32,     ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in cpu endianness
--- mplayer/libmpcodecs/img_format.h.unichrome~	2006-08-09 18:36:33.000000000 +0200
+++ mplayer/libmpcodecs/img_format.h	2007-02-25 01:30:32.000000000 +0100
@@ -106,6 +106,7 @@
 //these are chroma420
 #define IMGFMT_XVMC_MOCO_MPEG2 (IMGFMT_XVMC|0x02)
 #define IMGFMT_XVMC_IDCT_MPEG2 (IMGFMT_XVMC|0x82)
+#define IMGFMT_XVMC_VLD_MPEG2 (IMGFMT_XVMC|0x42)
 
 typedef struct {
     void* data;
--- mplayer/libmpcodecs/img_format.c.unichrome~	2006-08-09 18:36:33.000000000 +0200
+++ mplayer/libmpcodecs/img_format.c	2007-02-25 01:30:32.000000000 +0100
@@ -65,6 +65,7 @@
 	case IMGFMT_ZRMJPEGIB: return("Zoran MJPEG bottom field first");
 	case IMGFMT_XVMC_MOCO_MPEG2: return("MPEG1/2 Motion Compensation");
 	case IMGFMT_XVMC_IDCT_MPEG2: return("MPEG1/2 Motion Compensation and IDCT");
+	case IMGFMT_XVMC_VLD_MPEG2: return("MPEG1/2 Motion Compensation and VLD");
     }
     return("Unknown");
 }
--- mplayer/libmpcodecs/vd_ffmpeg.c.unichrome~	2007-02-24 23:51:41.000000000 +0100
+++ mplayer/libmpcodecs/vd_ffmpeg.c	2007-02-25 01:30:32.000000000 +0100
@@ -155,6 +155,8 @@
         case IMGFMT_XVMC_IDCT_MPEG2:
         case IMGFMT_XVMC_MOCO_MPEG2:
             if(avctx->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) return CONTROL_TRUE;
+        case IMGFMT_XVMC_VLD_MPEG2:
+            if(avctx->pix_fmt==PIX_FMT_XVMC_MPEG2_VLD) return CONTROL_TRUE;
 #endif
 	}
         return CONTROL_FALSE;
@@ -532,6 +534,7 @@
 #ifdef HAVE_XVMC
         case PIX_FMT_XVMC_MPEG2_MC:ctx->best_csp=IMGFMT_XVMC_MOCO_MPEG2;break;
         case PIX_FMT_XVMC_MPEG2_IDCT:ctx->best_csp=IMGFMT_XVMC_IDCT_MPEG2;break;
+        case PIX_FMT_XVMC_MPEG2_VLD:ctx->best_csp=IMGFMT_XVMC_VLD_MPEG2;break;
 #endif
 	default:
 	    ctx->best_csp=0;
@@ -920,7 +923,11 @@
         avctx->get_buffer= mc_get_buffer;
         avctx->release_buffer= mc_release_buffer;
         avctx->draw_horiz_band = mc_render_slice;
-        mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedMPEG2);
+        if (avctx->xvmc_acceleration != 4)
+            mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedMPEG2);
+        else
+            mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCVLDAcceleratedMPEG2);
+
         assert(ctx->do_dr1);//these are must to!
         assert(ctx->do_slices); //it is (vo_)ffmpeg bug if this fails
         avctx->flags|= CODEC_FLAG_EMU_EDGE;//do i need that??!!
--- mplayer/libvo/vo_xvmc.c.unichrome~	2007-02-19 13:11:39.000000000 +0100
+++ mplayer/libvo/vo_xvmc.c	2007-02-25 01:30:32.000000000 +0100
@@ -24,6 +24,10 @@
 #include <X11/extensions/Xvlib.h>
 #include <X11/extensions/XvMClib.h>
 
+#ifdef HAVE_XVMC_VLD
+#include <X11/extensions/vldXvMC.h>
+#endif
+
 #include "x11_common.h"
 #include "xvmc_render.h"
 
@@ -117,7 +121,7 @@
   "XVideo Motion Compensation",
   "xvmc",
   "Ivan Kalvachev <iive@users.sf.net>",
-  ""
+  "Ivor Hewitt <ivor@ivor.org> - VIA VLD support"
 };
 
 LIBVO_EXTERN(xvmc);
@@ -190,7 +194,23 @@
 }
 //end of vo_xv shm/xvimage code
 
+int hasVLDAcceleration()
+{
+#ifdef HAVE_XVMC_VLD
+    return XVMC_VLD == (surface_info.mc_type & XVMC_VLD);
+#else
+    return 0;
+#endif
+}            
+
 static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){
+#ifdef HAVE_XVMC_VLD
+    if (format == IMGFMT_XVMC_VLD_MPEG2 ){
+        if( surf_info->mc_type != (XVMC_VLD|XVMC_MPEG_2) ) return -1;
+        if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1;
+        return 0;
+    }
+#endif
    if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ 
       if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1;
       if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1;
@@ -484,6 +504,8 @@
    if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444)
       blocks_per_macroblock = 12;
 
+if (!hasVLDAcceleration())
+{
    rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks);
    if( rez != Success ){
       XvMCDestroyContext(mDisplay,&ctx);
@@ -499,6 +521,8 @@
    }
    printf("vo_xvmc: mv_blocks allocated\n");
 
+}
+
    if(surface_render==NULL)
       surface_render=malloc(MAX_SURFACES*sizeof(xvmc_render_state_t));//easy mem debug
    memset(surface_render,0,MAX_SURFACES*sizeof(xvmc_render_state_t));
@@ -517,6 +541,11 @@
       surface_render[i].chroma_format = surface_info.chroma_format;
       surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED;
       surface_render[i].p_surface = &surface_array[i];
+
+      surface_render[i].state = 0;
+      surface_render[i].disp = mDisplay;
+      surface_render[i].ctx = &ctx;
+
       if( mp_msg_test(MSGT_VO,MSGL_DBG4) )
           printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]);
    }
@@ -1146,9 +1175,11 @@
 
    if( number_of_surfaces ){
 
+      if (!hasVLDAcceleration())
+      {
       XvMCDestroyMacroBlocks(mDisplay,&mv_blocks);
       XvMCDestroyBlocks(mDisplay,&data_blocks);
-
+      }
       for(i=0; i<number_of_surfaces; i++)
       {
          XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope
@@ -1226,6 +1257,17 @@
    assert( rndr != NULL );
    assert( rndr->magic == MP_XVMC_RENDER_MAGIC );
 
+   if (hasVLDAcceleration())
+   {
+        rez = XvMCPutSlice2(mDisplay,&ctx,(char*)rndr->slice_data,
+                            rndr->slice_datalen,
+                            rndr->slice_code);
+        if (rez)
+           printf("vo_xxmc::slice Error %d\n",rez);
+
+   }
+   else
+   {
    rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure,
              		   rndr->p_surface,
                            rndr->p_past_surface,
@@ -1237,7 +1279,7 @@
    if(rez != Success)
    {
    int i;
-      printf("vo_xvmc::slice: RenderSirface returned %d\n",rez);
+      printf("vo_xvmc::slice: RenderSurface returned %d\n",rez);
 
       printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n",
              rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num,
@@ -1265,6 +1307,7 @@
    rez = XvMCFlushSurface(mDisplay, rndr->p_surface);
    assert(rez==Success);
 
+}
 //   rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num;
    rndr->start_mv_blocks_num = 0;
    rndr->filled_mv_blocks_num = 0;
@@ -1374,8 +1417,16 @@
 
 // these are shared!! so watch out
 // do call RenderSurface before overwriting
+if (!hasVLDAcceleration())
+{
    mpi->planes[0] = (char*)data_blocks.blocks;   
    mpi->planes[1] = (char*)mv_blocks.macro_blocks;
+}
+else
+{
+   mpi->planes[0] = 1;
+   mpi->planes[1] = 0;
+}
    mpi->priv =
    mpi->planes[2] = (char*)rndr;
 
--- mplayer/xvmc_render.h.unichrome~	2006-07-04 21:58:10.000000000 +0200
+++ mplayer/xvmc_render.h	2007-02-25 01:30:32.000000000 +0100
@@ -5,6 +5,9 @@
 #include <X11/extensions/Xvlib.h>
 #include <X11/extensions/XvMClib.h>
 
+#ifdef HAVE_XVMC_VLD
+#include <X11/extensions/vldXvMC.h>
+#endif
 
 //the surface should be shown, video driver manipulate this
 #define MP_XVMC_STATE_DISPLAY_PENDING 1
@@ -27,7 +30,20 @@
   int idct;//does we use IDCT acceleration?
   int chroma_format;//420,422,444
   int unsigned_intra;//+-128 for intra pictures after clip
+
+#ifdef HAVE_XVMC_VLD
+  int reserved1[3];
+  // These are for the XVMC VLD slice interface
+  int pict_type; //this is for skipping frames
+  int   slice_code; 
+  int   slice_datalen;
+  unsigned char *slice_data;
+  Display *disp;
+  XvMCContext *ctx;
+#else
   int reserved1[12];//future extenstions (e.g. gmc,qpel)
+#endif
+  
   void * p_osd_target_surface_render;//pointer to the surface where subpicture is rendered
   XvMCSurface* p_surface;//pointer to rendered surface, never changed
 
@@ -47,4 +63,6 @@
   
   int next_free_data_block_num;//used in add_mv_block, pointer to next free block
 
+
+
 } xvmc_render_state_t;
--- mplayer/vidix/drivers/radeon_vid.c.unichrome~	2007-01-06 14:56:12.000000000 +0100
+++ mplayer/vidix/drivers/radeon_vid.c	2007-02-25 01:30:32.000000000 +0100
@@ -907,7 +907,7 @@
  DEVICE_ATI_RADEON_RV350_AP,
  DEVICE_ATI_RADEON_RV350_AQ,
  DEVICE_ATI_RADEON_RV350_AR,
- DEVICE_ATI_RADEON_RV350_BK,
+// DEVICE_ATI_RADEON_RV350_BK,
  DEVICE_ATI_RADEON_R350_AH,
  DEVICE_ATI_RADEON_R350_AI,
  DEVICE_ATI_RADEON_R350_NH,
--- mplayer/configure.unichrome~	2007-02-25 01:30:32.000000000 +0100
+++ mplayer/configure	2007-02-25 01:31:00.000000000 +0100
@@ -473,6 +473,7 @@
 _runtime_cpudetection=no
 _cross_compile=auto
 _prefix="/usr/local"
+_xvmclib=""
 _libavutil=auto
 _libavutil_so=auto
 _libavcodec=auto
@@ -3962,35 +3963,90 @@
 fi
 echores "$_xv"
 
+xvmc_check()
+{
+  if test "$_xvmcvld" = yes; then
+    _xvmcinc="vlcXvMC.h"
+  else
+    _xvmcinc="XvMClib.h"
+  fi
 
-echocheck "XvMC"
-if test "$_xv" = yes && test "$_xvmc" != no ; then
-  _xvmc=no
   cat > $TMPC <<EOF
 #include <X11/Xlib.h>
 #include <X11/extensions/Xvlib.h>
-#include <X11/extensions/XvMClib.h>
+#include <X11/extensions/$_xvmcinc>
 int main(void) { 
   (void) XvMCQueryExtension(0,0,0);
   (void) XvMCCreateContext(0,0,0,0,0,0,0);
   return 0; }
 EOF
-  for _ld_tmp in $_xvmclib XvMCNVIDIA XvMCW I810XvMC ; do
-    cc_check -lXvMC -l$_ld_tmp && _xvmc=yes && _xvmclib="$_ld_tmp" && break
+  _success=0
+  for _ld_tmp in $_xvmclib XvMCW XvMCNVIDIA I810XvMC ; do
+    cc_check -lXvMC -l$_ld_tmp $_ld_xv $_ld_x11 && _xvmc=yes && _xvmclib="$_ld_tmp" && _success=1 && break
   done
-fi
-if test "$_xvmc" = yes ; then
-  _def_xvmc='#define HAVE_XVMC 1'
-  _libs_mplayer="$_libs_mplayer -lXvMC -l$_xvmclib"
-  _vosrc="$_vosrc vo_xvmc.c"
-  _vomodules="xvmc $_vomodules"
-  _res_comment="using $_xvmclib"
-else
-  _def_xvmc='#undef HAVE_XVMC'
-  _novomodules="xvmc $_novomodules"
-fi
-echores "$_xvmc"
+  return $_success
+}
+
+# Note: here we try to determine what xvmc capability is available
+# if the xvmc wrapper is available when we link to that, also we
+# check whether we can include the vld (slice) level xvmc include file
+if test "$_xv" = yes && test "$_xvmc" != no ; then
+  _xvmc=no
+  # No explicit xvmc lib specified so try and find one
+  if test "$_xvmclib" = ""; then
+    # Try with the xvmc wrapper+vld first
+    echocheck "XvMC (Wrapper+vld)"
+    _xvmclib="XvMCW"
+    _xvmcvld=yes
+    xvmc_check && _xvmc=yes
+    echores $_xvmc
+
+    # Try with the xvmc wrapper
+    if test "$_xvmc" = no; then
+      echocheck "XvMC (Wrapper)"
+      _xvmcvld=no
+      xvmc_check && _xvmc=yes
+      echores $_xvmc
+    fi
+
+    # Try with the nvidia lib
+    if test "$_xvmc" = no; then
+      echocheck "XvMC (NVIDIA)"
+      _xvmclib="XvMCNVIDIA"
+      xvmc_check && _xvmc=yes
+      echores $_xvmc
+    fi
+  else
+    # check for specified xvmc lib
+    echocheck "XvMC vld+($_xvmclib)"
+    _xvmcvld=yes
+    xvmc_check && _xvmc=yes
+    echores $_xvmc
+
+    if test "$_xvmc" = no; then
+      echocheck "XvMC ($_xvmclib)"
+      _xvmcvld=no
+      xvmc_check && _xvmc=yes
+      echores $_xvmc
+    fi
+  fi
+  
+  if test "$_xvmc" = yes; then
+    _def_xvmc='#define HAVE_XVMC 1'
+    _ld_xvmc="-lXvMC -l$_xvmclib"
+    _vosrc="$_vosrc vo_xvmc.c"
+    _vomodules="xvmc $_vomodules"
+  else
+    _novomodules="xvmc $_novomodules"
+    _def_xvmc='#undef HAVE_XVMC'
+  fi
 
+  if test "$_xvmcvld" = yes; then
+    _def_xvmc_vld='#define HAVE_XVMC_VLD 1'
+  else
+    _def_xvmc_vld='#undef HAVE_XVMC_VLD'
+  fi
+fi
 
 echocheck "Xinerama"
 if test "$_xinerama" = auto ; then
@@ -8355,6 +8411,7 @@
 $_def_x11
 $_def_xv
 $_def_xvmc
+$_def_xvmc_vld
 $_def_vm
 $_def_xf86keysym
 $_def_xinerama
--- mplayer/etc/codecs.conf.unichrome~	2007-02-25 01:30:32.000000000 +0100
+++ mplayer/etc/codecs.conf	2007-02-25 01:30:32.000000000 +0100
@@ -104,6 +104,7 @@
   fourcc mx5p        ; MPEG IMX 625/50 (50 Mb/s)
   driver ffmpeg
   dll "mpegvideo_xvmc"
+  out VLD_MPEG2
   out IDCT_MPEG2
   out MOCO_MPEG2
 
--- mplayer/codec-cfg.c.unichrome~	2006-08-09 18:36:59.000000000 +0200
+++ mplayer/codec-cfg.c	2007-02-25 01:30:32.000000000 +0100
@@ -178,6 +178,7 @@
 		{"ZRMJPEGIT", IMGFMT_ZRMJPEGIT},
 		{"ZRMJPEGIB", IMGFMT_ZRMJPEGIB},
 
+		{"VLD_MPEG2",IMGFMT_XVMC_VLD_MPEG2},
 		{"IDCT_MPEG2",IMGFMT_XVMC_IDCT_MPEG2},
 		{"MOCO_MPEG2",IMGFMT_XVMC_MOCO_MPEG2},