Mercurial > mplayer.hg
changeset 33247:a2483e1a3db3
Use xvmc_render struct to hold both xvmc_pix_fmt shared struct and the
specific flags needed by MPlayer. These flags were removed from FFmpeg
after the version bump.
author | iive |
---|---|
date | Tue, 26 Apr 2011 23:31:25 +0000 |
parents | 881d0b46bc62 |
children | 747e5068118c |
files | libvo/vo_xvmc.c |
diffstat | 1 files changed, 89 insertions(+), 103 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/vo_xvmc.c Tue Apr 26 18:48:19 2011 +0000 +++ b/libvo/vo_xvmc.c Tue Apr 26 23:31:25 2011 +0000 @@ -90,21 +90,22 @@ #define MAX_SURFACES 8 static int number_of_surfaces=0; static XvMCSurface surface_array[MAX_SURFACES]; -static struct render_info { +struct xvmc_render{ + struct xvmc_pix_fmt shared; #define STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */ #define STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */ #define STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */ int state; void *p_osd_target_surface_render; mp_image_t *mpi; -} surface_render_info[MAX_SURFACES]; -static struct xvmc_pix_fmt *surface_render; +}; +static struct xvmc_render *surface_render; -static struct xvmc_pix_fmt *p_render_surface_to_show = NULL; -static struct xvmc_pix_fmt *p_render_surface_visible = NULL; +static struct xvmc_render *p_render_surface_to_show = NULL; +static struct xvmc_render *p_render_surface_visible = NULL; //display queue, kinda render ahead -static struct xvmc_pix_fmt *show_queue[MAX_SURFACES]; +static struct xvmc_render *show_queue[MAX_SURFACES]; static int free_element; @@ -132,7 +133,7 @@ static void xvmc_free(void); static void xvmc_clean_surfaces(void); static int count_free_surfaces(void); -static struct xvmc_pix_fmt *find_free_surface(void); +static struct xvmc_render *find_free_surface(void); static const vo_info_t info = { "XVideo Motion Compensation", @@ -150,47 +151,33 @@ #endif static XvImage * xvimage; -static struct render_info *get_render_info(struct xvmc_pix_fmt *cur_render) +static void add_state(struct xvmc_render *cur_render, int flags) { - int idx; - if (!surface_render || !cur_render) - return NULL; - idx = cur_render - surface_render; - if (idx < 0 || idx >= MAX_SURFACES) - return NULL; - return surface_render_info + idx; -} - -static void add_state(struct xvmc_pix_fmt *cur_render, int flags) -{ - struct render_info *info = get_render_info(cur_render); int bit; - if (info->mpi) { + if (cur_render->mpi) { for (bit = 1; flags >= bit; bit <<= 1) { - if (flags & ~info->state & bit) - info->mpi->usage_count++; + if (flags & ~cur_render->state & bit) + cur_render->mpi->usage_count++; } } - info->state |= flags; + cur_render->state |= flags; } -static void remove_state(struct xvmc_pix_fmt *cur_render, int flags) +static void remove_state(struct xvmc_render *cur_render, int flags) { - struct render_info *info = get_render_info(cur_render); int bit; - if (info->mpi) { + if (cur_render->mpi) { for (bit = 1; flags >= bit; bit <<= 1) { - if (flags & info->state & bit) - info->mpi->usage_count--; + if (flags & cur_render->state & bit) + cur_render->mpi->usage_count--; } } - info->state &= ~flags; + cur_render->state &= ~flags; } -static int in_use(struct xvmc_pix_fmt *cur_render) +static int in_use(struct xvmc_render *cur_render) { - struct render_info *info = get_render_info(cur_render); - return info->state || (info->mpi && info->mpi->usage_count); + return cur_render->state || (cur_render->mpi && cur_render->mpi->usage_count); } static void allocate_xvimage(int xvimage_width,int xvimage_height,int xv_format) @@ -398,15 +385,15 @@ } static uint32_t xvmc_draw_image(mp_image_t *mpi){ - struct xvmc_pix_fmt *rndr; + struct xvmc_render *rndr; assert(mpi!=NULL); assert(mpi->flags &MP_IMGFLAG_DIRECT); // assert(mpi->flags &MP_IMGFLAGS_DRAWBACK); - rndr = (struct xvmc_pix_fmt*)mpi->priv; //there is copy in plane[2] + rndr = (struct xvmc_render*)mpi->priv; //there is copy in plane[2] assert( rndr != NULL ); - assert( rndr->xvmc_id == AV_XVMC_ID ); + assert( rndr->shared.xvmc_id == AV_XVMC_ID ); mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: draw_image(show rndr=%p)\n",rndr); // the surface have passed vf system without been skiped, it will be displayed add_state(rndr, STATE_DISPLAY_PENDING); @@ -555,21 +542,21 @@ mp_msg(MSGT_VO,MSGL_INFO,"vo_xvmc: mv_blocks allocated\n"); if(surface_render==NULL) - surface_render = malloc(MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //easy mem debug - memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); + surface_render = malloc(MAX_SURFACES * sizeof(struct xvmc_render)); //easy mem debug + memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_render)); for(i=0; i<MAX_SURFACES; i++){ rez=XvMCCreateSurface(mDisplay,&ctx,&surface_array[i]); if( rez != Success ) break; - surface_render[i].xvmc_id = AV_XVMC_ID; - surface_render[i].data_blocks = data_blocks.blocks; - surface_render[i].mv_blocks = mv_blocks.macro_blocks; - surface_render[i].allocated_mv_blocks = numblocks; - surface_render[i].allocated_data_blocks = numblocks*blocks_per_macroblock; - surface_render[i].idct = (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT; - 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].shared.xvmc_id = AV_XVMC_ID; + surface_render[i].shared.data_blocks = data_blocks.blocks; + surface_render[i].shared.mv_blocks = mv_blocks.macro_blocks; + surface_render[i].shared.allocated_mv_blocks = numblocks; + surface_render[i].shared.allocated_data_blocks = numblocks*blocks_per_macroblock; + surface_render[i].shared.idct = (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT; + surface_render[i].shared.unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; + surface_render[i].shared.p_surface = &surface_array[i]; mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: surface[%d] = %p .rndr=%p\n", i,&surface_array[i], &surface_render[i]); } @@ -866,7 +853,7 @@ } static void draw_osd(void){ - struct xvmc_pix_fmt *osd_rndr; + struct xvmc_render *osd_rndr; int osd_has_changed; int have_osd_to_draw; int rez; @@ -903,7 +890,7 @@ return;// no free surface to draw OSD in rez = XvMCBlendSubpicture2(mDisplay, - p_render_surface_to_show->p_surface, osd_rndr->p_surface, + p_render_surface_to_show->shared.p_surface, osd_rndr->shared.p_surface, &subpicture, 0, 0, subpicture.width, subpicture.height, 0, 0, image_width, image_height); @@ -915,13 +902,12 @@ // XvMCFlushSurface(mDisplay,osd_rndr->p_surface);//fixme- should I? //When replaceing the surface with osd one, save the flags too! - osd_rndr->picture_structure = p_render_surface_to_show->picture_structure; + osd_rndr->shared.picture_structure = p_render_surface_to_show->shared.picture_structure; //add more if needed osd_rndr-> = p_render_surface_to_show->; add_state(p_render_surface_to_show, STATE_OSD_SOURCE); remove_state(p_render_surface_to_show, STATE_DISPLAY_PENDING); - info = get_render_info(p_render_surface_to_show); - info->p_osd_target_surface_render = osd_rndr; + p_render_surface_to_show->p_osd_target_surface_render = osd_rndr; p_render_surface_to_show = osd_rndr; add_state(p_render_surface_to_show, STATE_DISPLAY_PENDING); @@ -930,7 +916,7 @@ }//endof if(BLEND) if(subpicture_mode == BACKEND_SUBPICTURE){ rez = XvMCBlendSubpicture(mDisplay, - p_render_surface_to_show->p_surface, + p_render_surface_to_show->shared.p_surface, &subpicture, 0, 0, subpicture.width, subpicture.height, 0, 0, image_width, image_height); @@ -961,7 +947,7 @@ XvMCSyncSurface(mDisplay, srf); } -static void put_xvmc_image(struct xvmc_pix_fmt *p_render_surface, +static void put_xvmc_image(struct xvmc_render *p_render_surface, int draw_ck){ int rez; struct vo_rect src_rect, dst_rect; @@ -980,7 +966,7 @@ for (i = 1; i <= bob_deinterlace + 1; i++) { int field = top_field_first ? i : i ^ 3; - rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, + rez = XvMCPutSurface(mDisplay, p_render_surface->shared.p_surface, vo_window, src_rect.left, src_rect.top, src_rect.width, src_rect.height, dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height, @@ -999,7 +985,7 @@ mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: flip_page show(rndr=%p)\n\n",p_render_surface_to_show); if(p_render_surface_to_show == NULL) return; - assert( p_render_surface_to_show->xvmc_id == AV_XVMC_ID ); + assert( p_render_surface_to_show->shared.xvmc_id == AV_XVMC_ID ); //fixme assert( p_render_surface_to_show != p_render_surface_visible); if(use_queue){ @@ -1009,7 +995,7 @@ show_queue[free_element++] = p_render_surface_to_show; if(cfs > 3){//well have 3 free surfaces after add queue if(free_element > 1)//a little voodoo magic - xvmc_sync_surface(show_queue[0]->p_surface); + xvmc_sync_surface(show_queue[0]->shared.p_surface); return; } p_render_surface_to_show=show_queue[0]; @@ -1022,7 +1008,7 @@ } // make sure the rendering is done - xvmc_sync_surface(p_render_surface_to_show->p_surface); + xvmc_sync_surface(p_render_surface_to_show->shared.p_surface); //the visible surface won't be displayed anymore, mark it as free if(p_render_surface_visible != NULL) @@ -1074,13 +1060,13 @@ XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope XvMCDestroySurface(mDisplay,&surface_array[i]); - if( (surface_render_info[i].state != 0) && + if( (surface_render[i].state != 0) && (p_render_surface_visible != &surface_render[i]) ) mp_msg(MSGT_VO,MSGL_INFO,"vo_xvmc::uninit surface_render[%d].status=%d\n",i, - surface_render_info[i].state); + surface_render[i].state); } - memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //for debugging + memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_render)); //for debugging free(surface_render);surface_render=NULL; XvMCDestroyContext(mDisplay,&ctx); @@ -1132,21 +1118,21 @@ static int draw_slice(uint8_t *image[], int stride[], int w, int h, int x, int y){ - struct xvmc_pix_fmt *rndr; + struct xvmc_render *rndr; int rez; mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: draw_slice y=%d\n",y); - rndr = (struct xvmc_pix_fmt*)image[2]; //this is copy of priv-ate + rndr = (struct xvmc_render*)image[2]; //this is copy of priv-ate assert( rndr != NULL ); - assert( rndr->xvmc_id == AV_XVMC_ID ); + assert( rndr->shared.xvmc_id == AV_XVMC_ID ); - rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, - rndr->p_surface, - rndr->p_past_surface, - rndr->p_future_surface, - rndr->flags, - rndr->filled_mv_blocks_num,rndr->start_mv_blocks_num, + rez = XvMCRenderSurface(mDisplay,&ctx,rndr->shared.picture_structure, + rndr->shared.p_surface, + rndr->shared.p_past_surface, + rndr->shared.p_future_surface, + rndr->shared.flags, + rndr->shared.filled_mv_blocks_num,rndr->shared.start_mv_blocks_num, &mv_blocks,&data_blocks); if(rez != Success) { @@ -1154,12 +1140,12 @@ mp_msg(MSGT_VO,MSGL_ERR,"vo_xvmc::slice: RenderSirface returned %d\n",rez); mp_msg(MSGT_VO,MSGL_ERR,"vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", - rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, - rndr->filled_mv_blocks_num); + rndr->shared.picture_structure,rndr->shared.flags,rndr->shared.start_mv_blocks_num, + rndr->shared.filled_mv_blocks_num); mp_msg(MSGT_VO,MSGL_ERR,"vo_xvmc::slice: this_surf=%p, past_surf=%p, future_surf=%p\n", - rndr->p_surface,rndr->p_past_surface,rndr->p_future_surface); + rndr->shared.p_surface,rndr->shared.p_past_surface,rndr->shared.p_future_surface); - for(i=0; i<rndr->filled_mv_blocks_num; i++){ + for(i=0; i<rndr->shared.filled_mv_blocks_num; i++){ XvMCMacroBlock* testblock; testblock = &mv_blocks.macro_blocks[i]; @@ -1175,29 +1161,29 @@ } assert(rez==Success); mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: flush surface\n"); - rez = XvMCFlushSurface(mDisplay, rndr->p_surface); + rez = XvMCFlushSurface(mDisplay, rndr->shared.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; + rndr->shared.start_mv_blocks_num = 0; + rndr->shared.filled_mv_blocks_num = 0; - rndr->next_free_data_block_num = 0; + rndr->shared.next_free_data_block_num = 0; return VO_TRUE; } //XvMCHide hides the surface on next retrace, so //check if the surface is not still displaying -static void check_osd_source(struct xvmc_pix_fmt *src_rndr) { - struct xvmc_pix_fmt *osd_rndr; +static void check_osd_source(struct xvmc_render *src_rndr) { + struct xvmc_render *osd_rndr; int stat; //If this is source surface, check does the OSD rendering is compleate - if(get_render_info(src_rndr)->state & STATE_OSD_SOURCE){ + if(src_rndr->state & STATE_OSD_SOURCE){ mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: OSD surface=%p querying\n",src_rndr); - osd_rndr = get_render_info(src_rndr)->p_osd_target_surface_render; - XvMCGetSurfaceStatus(mDisplay, osd_rndr->p_surface, &stat); + osd_rndr = src_rndr->p_osd_target_surface_render; + XvMCGetSurfaceStatus(mDisplay, osd_rndr->shared.p_surface, &stat); if(!(stat & XVMC_RENDERING)) remove_state(src_rndr, STATE_OSD_SOURCE); } @@ -1214,17 +1200,17 @@ return num; } -static struct xvmc_pix_fmt *find_free_surface(void) { +static struct xvmc_render *find_free_surface(void) { int i,t; int stat; - struct xvmc_pix_fmt *visible_rndr; + struct xvmc_render *visible_rndr; visible_rndr = NULL; for(i=0; i<number_of_surfaces; i++){ check_osd_source(&surface_render[i]); if( !in_use(surface_render + i)){ - XvMCGetSurfaceStatus(mDisplay, surface_render[i].p_surface,&stat); + XvMCGetSurfaceStatus(mDisplay, surface_render[i].shared.p_surface,&stat); if( (stat & XVMC_DISPLAYING) == 0 ) return &surface_render[i]; visible_rndr = &surface_render[i];// remember it, use as last resort @@ -1237,7 +1223,7 @@ mp_msg(MSGT_VO,MSGL_INFO,"vo_xvmc: waiting retrace\n"); for(t=0;t<1000;t++){ usec_sleep(1000);//1ms - XvMCGetSurfaceStatus(mDisplay, visible_rndr->p_surface,&stat); + XvMCGetSurfaceStatus(mDisplay, visible_rndr->shared.p_surface,&stat); if( (stat & XVMC_DISPLAYING) == 0 ) return visible_rndr; } @@ -1245,7 +1231,7 @@ //todo remove when stable mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: no free surfaces, this should not happen in g1\n"); for(i=0;i<number_of_surfaces;i++) - mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n",i,surface_render_info[i].state); + mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n",i,surface_render[i].state); return NULL; } @@ -1255,17 +1241,17 @@ for(i=0; i<number_of_surfaces; i++){ remove_state(surface_render + i, STATE_DISPLAY_PENDING | STATE_OSD_SOURCE); - surface_render_info[i].p_osd_target_surface_render=NULL; - if(surface_render_info[i].state != 0){ + surface_render[i].p_osd_target_surface_render=NULL; + if(surface_render[i].state != 0){ mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n", - i,surface_render_info[i].state); + i,surface_render[i].state); } } free_element=0;//clean up the queue } static uint32_t get_image(mp_image_t *mpi){ - struct xvmc_pix_fmt *rndr; + struct xvmc_render *rndr; rndr = find_free_surface(); @@ -1274,15 +1260,15 @@ return VO_FALSE; } -assert(rndr->start_mv_blocks_num == 0); -assert(rndr->filled_mv_blocks_num == 0); -assert(rndr->next_free_data_block_num == 0); +assert(rndr->shared.start_mv_blocks_num == 0); +assert(rndr->shared.filled_mv_blocks_num == 0); +assert(rndr->shared.next_free_data_block_num == 0); mpi->flags |= MP_IMGFLAG_DIRECT; //keep strides 0 to avoid field manipulations mpi->stride[0] = 0; mpi->stride[1] = 0; - mpi->stride[2] = 0; + mpi->stride[2] = sizeof(rndr); // these are shared!! so watch out // do call RenderSurface before overwriting @@ -1291,16 +1277,16 @@ mpi->priv = mpi->planes[2] = (char*)rndr; - rndr->picture_structure = 0; - rndr->flags = 0; - get_render_info(rndr)->state = 0; - get_render_info(rndr)->mpi = mpi; - rndr->start_mv_blocks_num = 0; - rndr->filled_mv_blocks_num = 0; - rndr->next_free_data_block_num = 0; + rndr->shared.picture_structure = 0; + rndr->shared.flags = 0; + rndr->state = 0; + rndr->mpi = mpi; + rndr->shared.start_mv_blocks_num = 0; + rndr->shared.filled_mv_blocks_num = 0; + rndr->shared.next_free_data_block_num = 0; mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc: get_image: rndr=%p (surface=%p) \n", - rndr,rndr->p_surface); + rndr,rndr->shared.p_surface); return VO_TRUE; }