changeset 33197:17dba462c48c

Fix compilation with XvMC, only lightly tested.
author reimar
date Fri, 22 Apr 2011 07:28:44 +0000
parents 8e423915a5bb
children 1f418f605d13
files libmpcodecs/vd_ffmpeg.c libvo/vo_xvmc.c
diffstat 2 files changed, 43 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/vd_ffmpeg.c	Fri Apr 22 07:26:23 2011 +0000
+++ b/libmpcodecs/vd_ffmpeg.c	Fri Apr 22 07:28:44 2011 +0000
@@ -681,7 +681,6 @@
             mp_msg(MSGT_DECVIDEO, MSGL_DBG5, "vd_ffmpeg::get_buffer (xvmc render=%p)\n", render);
         assert(render != 0);
         assert(render->xvmc_id == AV_XVMC_ID);
-        render->state |= AV_XVMC_STATE_PREDICTION;
     }
 #endif
 
@@ -761,16 +760,6 @@
         // Palette support: free palette buffer allocated in get_buffer
         if (mpi->bpp == 8)
             av_freep(&mpi->planes[1]);
-#if CONFIG_XVMC
-        if (IMGFMT_IS_XVMC(mpi->imgfmt)) {
-            struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)pic->data[2]; //same as mpi->priv
-            if(mp_msg_test(MSGT_DECVIDEO, MSGL_DBG5))
-                mp_msg(MSGT_DECVIDEO, MSGL_DBG5, "vd_ffmpeg::release_buffer (xvmc render=%p)\n", render);
-            assert(render!=NULL);
-            assert(render->xvmc_id == AV_XVMC_ID);
-            render->state&=~AV_XVMC_STATE_PREDICTION;
-        }
-#endif
         // release mpi (in case MPI_IMGTYPE_NUMBERED is used, e.g. for VDPAU)
         mpi->usage_count--;
     }
--- a/libvo/vo_xvmc.c	Fri Apr 22 07:26:23 2011 +0000
+++ b/libvo/vo_xvmc.c	Fri Apr 22 07:28:44 2011 +0000
@@ -101,6 +101,7 @@
 #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;
 
@@ -165,6 +166,38 @@
     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) {
+        for (bit = 1; flags >= bit; bit <<= 1) {
+            if (flags & ~info->state & bit)
+                info->mpi->usage_count++;
+        }
+    }
+    info->state |= flags;
+}
+
+static void remove_state(struct xvmc_pix_fmt *cur_render, int flags)
+{
+    struct render_info *info = get_render_info(cur_render);
+    int bit;
+    if (info->mpi) {
+        for (bit = 1; flags >= bit; bit <<= 1) {
+            if (flags & info->state & bit)
+                info->mpi->usage_count--;
+        }
+    }
+    info->state &= ~flags;
+}
+
+static int in_use(struct xvmc_pix_fmt *cur_render)
+{
+    struct render_info *info = get_render_info(cur_render);
+    return info->state || (info->mpi && info->mpi->usage_count);
+}
+
 static void allocate_xvimage(int xvimage_width,int xvimage_height,int xv_format)
 {
  /*
@@ -381,7 +414,7 @@
     assert( rndr->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
-    get_render_info(rndr)->state |= STATE_DISPLAY_PENDING;
+    add_state(rndr, STATE_DISPLAY_PENDING);
     p_render_surface_to_show = rndr;
     top_field_first = mpi->fields & MP_IMGFIELD_TOP_FIRST;
     return VO_TRUE;
@@ -890,14 +923,13 @@
             osd_rndr->picture_structure = p_render_surface_to_show->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->state &= ~STATE_DISPLAY_PENDING;
-            info->state |= STATE_OSD_SOURCE;
             info->p_osd_target_surface_render = osd_rndr;
 
             p_render_surface_to_show = osd_rndr;
-            info = get_render_info(p_render_surface_to_show);
-            info->state = STATE_DISPLAY_PENDING;
+            add_state(p_render_surface_to_show, STATE_DISPLAY_PENDING);
 
             mp_msg(MSGT_VO,MSGL_DBG4,"vo_xvmc:draw_osd: surface_to_show changed to %p\n",osd_rndr);
         }//endof if(BLEND)
@@ -999,7 +1031,7 @@
 
 //the visible surface won't be displayed anymore, mark it as free
     if(p_render_surface_visible != NULL)
-        get_render_info(p_render_surface_visible)->state &= ~STATE_DISPLAY_PENDING;
+        remove_state(p_render_surface_visible, STATE_DISPLAY_PENDING);
 
 //!!fixme   assert(p_render_surface_to_show->state & STATE_DISPLAY_PENDING);
 
@@ -1172,7 +1204,7 @@
         osd_rndr = get_render_info(src_rndr)->p_osd_target_surface_render;
         XvMCGetSurfaceStatus(mDisplay, osd_rndr->p_surface, &stat);
         if(!(stat & XVMC_RENDERING))
-            get_render_info(src_rndr)->state &= ~STATE_OSD_SOURCE;
+            remove_state(src_rndr, STATE_OSD_SOURCE);
     }
 }
 static int count_free_surfaces(void) {
@@ -1181,7 +1213,7 @@
     num=0;
     for(i=0; i<number_of_surfaces; i++){
         check_osd_source(&surface_render[i]);
-        if(surface_render_info[i].state == 0)
+        if(!in_use(surface_render + i))
             num++;
     }
     return num;
@@ -1196,7 +1228,7 @@
     for(i=0; i<number_of_surfaces; i++){
 
         check_osd_source(&surface_render[i]);
-        if( surface_render_info[i].state == 0){
+        if( !in_use(surface_render + i)){
             XvMCGetSurfaceStatus(mDisplay, surface_render[i].p_surface,&stat);
             if( (stat & XVMC_DISPLAYING) == 0 )
                 return &surface_render[i];
@@ -1227,9 +1259,7 @@
 
     for(i=0; i<number_of_surfaces; i++){
 
-        surface_render_info[i].state&=!( STATE_DISPLAY_PENDING |
-                                    STATE_OSD_SOURCE |
-                                    0);
+        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){
             mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n",
@@ -1269,6 +1299,7 @@
     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;