--- 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},