vo_xvmc.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,427 行 · 第 1/3 页

C
1,427
字号
         xvmc_clean_surfaces();         goto skip_surface_allocation;      }      xvmc_free();   };   numblocks=((width+15)/16)*((height+15)/16);// Find Supported Surface Type   mode_id = xvmc_find_surface_by_format(format,width,height,&surface_info,0);//false=1 to grab port, not query   if ( mode_id == 0 )   {      return -1;   }   rez = XvMCCreateContext(mDisplay, xv_port,mode_id,width,height,XVMC_DIRECT,&ctx);   if( rez != Success ){      printf("vo_xvmc: XvMCCreateContext failed with error %d\n",rez);      return -1;   }   if( ctx.flags & XVMC_DIRECT ){      printf("vo_xvmc: Allocated Direct Context\n");   }else{      printf("vo_xvmc: Allocated Indirect Context!\n");   }   blocks_per_macroblock = 6;   if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_422)      blocks_per_macroblock = 8;   if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444)      blocks_per_macroblock = 12;   rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks);   if( rez != Success ){      XvMCDestroyContext(mDisplay,&ctx);      return -1;   }   printf("vo_xvmc: data_blocks allocated\n");   rez = XvMCCreateMacroBlocks(mDisplay,&ctx,numblocks,&mv_blocks);   if( rez != Success ){      XvMCDestroyBlocks(mDisplay,&data_blocks);      XvMCDestroyContext(mDisplay,&ctx);      return -1;   }   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));   for(i=0; i<MAX_SURFACES; i++){      rez=XvMCCreateSurface(mDisplay,&ctx,&surface_array[i]);      if( rez != Success )	 break;      surface_render[i].magic = MP_XVMC_RENDER_MAGIC;      surface_render[i].data_blocks = data_blocks.blocks;      surface_render[i].mv_blocks = mv_blocks.macro_blocks;      surface_render[i].total_number_of_mv_blocks = numblocks;      surface_render[i].total_number_of_data_blocks = numblocks*blocks_per_macroblock;;      surface_render[i].mc_type = surface_info.mc_type & (~XVMC_IDCT);      surface_render[i].idct = (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT;      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];      if( mp_msg_test(MSGT_VO,MSGL_DBG4) )          printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]);   }   number_of_surfaces = i;   if( number_of_surfaces < 4 ){// +2 I or P and +2 for B (to avoid visible motion drawing)      printf("vo_xvmc: Unable to allocate at least 4 Surfaces\n");      uninit();      return -1;   }   printf("vo_xvmc: Motion Compensation context allocated - %d surfaces\n",          number_of_surfaces);  //debug   printf("vo_xvmc: idct=%d unsigned_intra=%d\n",           (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT,	   (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED);// Find way to display OSD & subtitle   printf("vo_xvmc: looking for OSD support\n");   subpicture_mode = NO_SUBPICTURE;   if(surface_info.flags & XVMC_OVERLAID_SURFACE)      subpicture_mode = OVERLAY_SUBPICTURE;   if(surface_info.subpicture_max_width  != 0 &&       surface_info.subpicture_max_height != 0  ){      int s,k,num_subpic;      XvImageFormatValues * xvfmv;      xvfmv = XvMCListSubpictureTypes(mDisplay, xv_port,                      surface_info.surface_type_id, &num_subpic);      if(num_subpic != 0 && xvfmv != NULL){         if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){//Print all subpicture types for debug            for(s=0;s<num_subpic;s++)               print_xvimage_format_values(&xvfmv[s]);         }         for(s=0;s<num_subpic;s++){            for(k=0;osd_render[k].draw_func_ptr!=NULL;k++){               if(xvfmv[s].id == osd_render[k].id)               {                    init_osd_fnc  = osd_render[k].init_func_ptr;                  draw_osd_fnc  = osd_render[k].draw_func_ptr;                  clear_osd_fnc = osd_render[k].clear_func_ptr;                  subpicture_mode = BLEND_SUBPICTURE;                  subpicture_info = xvfmv[s];                  printf("    Subpicture id 0x%08X\n",subpicture_info.id);                  goto found_subpic;               }            }         }found_subpic:         XFree(xvfmv);       }      //Blend2 supicture is always possible, blend1 only at backend      if( (subpicture_mode == BLEND_SUBPICTURE) &&          (surface_info.flags & XVMC_BACKEND_SUBPICTURE) )      {         subpicture_mode = BACKEND_SUBPICTURE;      }   }   switch(subpicture_mode){      case NO_SUBPICTURE:         printf("vo_xvmc: No OSD support for this mode\n");         break;      case OVERLAY_SUBPICTURE:         printf("vo_xvmc: OSD support via color key tricks\n");         printf("vo_xvmc: not yet implemented:(\n");         break;      case BLEND_SUBPICTURE:         printf("vo_xvmc: OSD support by additional frontend rendering\n");         break;      case BACKEND_SUBPICTURE:         printf("vo_xvmc: OSD support by backend rendering (fast)\n");         printf("vo_xvmc: Please send feedback to confirm that it works,otherwise send bugreport!\n");         break;   }//take keycolor value and choose method for handling it   if ( !vo_xv_init_colorkey() )   {     return -1; // bail out, colorkey setup failed   }   vo_xv_enable_vsync();//it won't break anything//taken from vo_xv   image_height = height;   image_width = width;skip_surface_allocation:   vo_mouse_autohide = 1;#ifdef HAVE_XF86VM   if( flags&VOFLAG_MODESWITCHING ) vm = 1;#endif#ifdef HAVE_NEW_GUI   if(use_gui)      guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window   else#endif   {      hint.x = vo_dx;      hint.y = vo_dy;      hint.width = d_width;      hint.height = d_height;#ifdef HAVE_XF86VM      if ( vm )      {	 if ((d_width==0) && (d_height==0))	    { vm_width=image_width; vm_height=image_height; }	 else	    { vm_width=d_width; vm_height=d_height; }	 vo_vm_switch(vm_width, vm_height,&modeline_width, &modeline_height);	 hint.x=(vo_screenwidth-modeline_width)/2;	 hint.y=(vo_screenheight-modeline_height)/2;	 hint.width=modeline_width;	 hint.height=modeline_height;	 aspect_save_screenres(modeline_width,modeline_height);      }      else#endif   hint.flags = PPosition | PSize /* | PBaseSize */;   hint.base_width = hint.width; hint.base_height = hint.height;   XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs);   depth=attribs.depth;   if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24;   XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo);   xswa.background_pixel = 0;   if (xv_ck_info.method == CK_METHOD_BACKGROUND)      xswa.background_pixel = xv_colorkey;   xswa.border_pixel     = 0;   xswamask = CWBackPixel | CWBorderPixel;   if ( WinID>=0 ){      vo_window = WinID ? ((Window)WinID) : mRootWin;      if ( WinID )       {         Window mRoot;         uint32_t drwBorderWidth, drwDepth;         XUnmapWindow( mDisplay,vo_window );         XChangeWindowAttributes( mDisplay,vo_window,xswamask,&xswa );	 vo_x11_selectinput_witherr( mDisplay,vo_window,StructureNotifyMask | KeyPressMask | PropertyChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask );         XMapWindow( mDisplay,vo_window );         XGetGeometry(mDisplay, vo_window, &mRoot,                      &drwX, &drwY, &vo_dwidth, &vo_dheight,                      &drwBorderWidth, &drwDepth);         aspect_save_prescale(vo_dwidth, vo_dheight);      }   } else       vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, flags,              CopyFromParent, "xvmc", title);      XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa);      if ( vo_gc != None ) XFreeGC( mDisplay,vo_gc );      vo_gc = XCreateGC(mDisplay, vo_window, GCForeground, &xgcv);      XSync(mDisplay, False);#ifdef HAVE_XF86VM      if ( vm )      {      /* Grab the mouse pointer in our window */         if(vo_grabpointer)         XGrabPointer(mDisplay, vo_window, True, 0,                      GrabModeAsync, GrabModeAsync,                      vo_window, None, CurrentTime );         XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime);      }#endif   }   aspect(&vo_dwidth, &vo_dheight, A_NOZOOM);   if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;   calc_drwXY(&drwX, &drwY);   panscan_calc();   mp_msg(MSGT_VO,MSGL_V, "[xvmc] dx: %d dy: %d dw: %d dh: %d\n",drwX,drwY,vo_dwidth,vo_dheight );   if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop);//end vo_xv   /* store image dimesions for displaying */   p_render_surface_visible = NULL;   p_render_surface_to_show = NULL;   free_element = 0;   first_frame = 1;   vo_directrendering = 1;//ugly hack, coz xvmc works only with direct rendering   image_format=format;   return 0;		}static int draw_frame(uint8_t *srcp[]){   UNUSED(srcp);   assert(0);}static void init_osd_yuv_pal(){   char * palette;   int rez;   int i,j;   int snum,seb;   int Y,U,V;   subpicture_clear_color = 0;   if(subpicture.num_palette_entries > 0){      snum = subpicture.num_palette_entries;      seb = subpicture.entry_bytes;      palette = malloc(snum*seb);//check fail      if(palette == NULL) return;      for(i=0; i<snum; i++){         // 0-black max-white the other are gradients         Y = i*(1 << subpicture_info.y_sample_bits)/snum;//snum=2;->(0),(1*(1<<1)/2)         U = 1 << (subpicture_info.u_sample_bits - 1);         V = 1 << (subpicture_info.v_sample_bits - 1);         for(j=0; j<seb; j++)            switch(subpicture.component_order[j]){               case 'U': palette[i*seb+j] = U; break;               case 'V': palette[i*seb+j] = V; break;               case 'Y':                default:                         palette[i*seb+j] = Y; break;         }      }      rez = XvMCSetSubpicturePalette(mDisplay, &subpicture, palette);      if(rez!=Success){         printf("vo_xvmc: Setting palette failed.\n");      }      free(palette);   }}static void clear_osd_subpic(int x0, int y0, int w, int h){int rez;   rez=XvMCClearSubpicture(mDisplay, &subpicture,                       x0, y0, w,h,                       subpicture_clear_color);   if(rez != Success)      printf("vo_xvmc: XvMCClearSubpicture failed!\n");}static void OSD_init(){unsigned short osd_height, osd_width;int rez;   if(subpicture_alloc){      if( mp_msg_test(MSGT_VO,MSGL_DBG4) )         printf("vo_xvmc: destroying subpicture\n");      XvMCDestroySubpicture(mDisplay,&subpicture);      deallocate_xvimage();      subpicture_alloc = 0;   }/*   if(surface_info.flags & XVMC_SUBPICTURE_INDEPENDENT_SCALING){      osd_width = vo_dwidth;      osd_height = vo_dheight;   }else*/   {      osd_width = image_width;      osd_height = image_height;   }   if(osd_width > surface_info.subpicture_max_width)      osd_width = surface_info.subpicture_max_width;   if(osd_height > surface_info.subpicture_max_height)      osd_height = surface_info.subpicture_max_height;   if(osd_width == 0 || osd_height == 0)       return;//if called before window size is known   if( mp_msg_test(MSGT_VO,MSGL_DBG4) )      printf("vo_xvmc: creating subpicture (%d,%d) format %X\n",              osd_width,osd_height,subpicture_info.id);   rez = XvMCCreateSubpicture(mDisplay,&ctx,&subpicture,                           osd_width,osd_height,subpicture_info.id);   if(rez != Success){      subpicture_mode = NO_SUBPICTURE;      printf("vo_xvmc: Create Subpicture failed, OSD disabled\n");      return;   }   if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){   int i;      printf("vo_xvmc: Created Subpicture:\n");      printf("         xvimage_id=0x%X\n",subpicture.xvimage_id);      printf("         width=%d\n",subpicture.width);      printf("         height=%d\n",subpicture.height);      printf("         num_palette_entries=0x%X\n",subpicture.num_palette_entries);      printf("         entry_bytes=0x%X\n",subpicture.entry_bytes);      printf("         component_order=\"");      for(i=0; i<4; i++)         if(subpicture.component_order[i] >= 32)            printf("%c", subpicture.component_order[i]);      printf("\"\n");   }      //call init for the surface type   init_osd_fnc();//init palete,clear color etc ...   if( mp_msg_test(MSGT_VO,MSGL_DBG4) )      printf("vo_xvmc: clearing subpicture\n");   clear_osd_fnc(0, 0, subpicture.width, subpicture.height);   allocate_xvimage(subpicture.width, subpicture.height, subpicture_info.id);   subpicture_alloc = 1;}static void draw_osd_IA44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){int ox,oy;int rez;   if( mp_msg_test(MSGT_VO,MSGL_DBG4) )      printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h);   for(ox=0; ox<w; ox++){      for(oy=0; oy<h; oy++){         xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]>>4) | ((0-srca[oy*stride+ox])&0xf0);      }   }   rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0,                           w,h,x0,y0);   if(rez != Success){      printf("vo_xvmc: composite subpicture failed\n");      assert(0);   }}static void draw_osd_AI44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){int ox,oy;int rez;   if(  mp_msg_test(MSGT_VO,MSGL_DBG4) )      printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h);   for(ox=0; ox<w; ox++){      for(oy=0; oy<h; oy++){         xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]&0xf0) | (((0-srca[oy*stride+ox])>>4)&0xf);      }   }   rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0,                           w,h,x0,y0);   if(rez != Success){      printf("vo_xvmc: composite subpicture failed\n");      assert(0);   }}static void draw_osd(void){xvmc_render_state_t * osd_rndr;int osd_has_changed;int have_osd_to_draw;int rez;   if( mp_msg_test(MSGT_VO,MSGL_DBG4) )      printf("vo_xvmc: draw_osd ,OSD_mode=%d, surface_to_show=%p\n",             subpicture_mode,p_render_surface_to_show);   if(subpicture_mode == BLEND_SUBPICTURE ||       subpicture_mode == BACKEND_SUBPICTURE ){      if(!subpicture_alloc) //allocate subpicture when dimensions are known         OSD_init();      if(!subpicture_alloc)          return;//dimensions still unknown.      osd_has_changed = vo_update_osd(subpicture.width, subpicture.height);      have_osd_to_draw = vo_osd_check_range_update(0, 0, subpicture.width,                                                          subpicture.height);       if(!have_osd_to_draw)         return;//nothing to draw,no subpic, no blend      if(osd_has_changed){         //vo_remove_text(subpicture.width, subpicture.height,clear_osd_fnc)         clear_osd_fnc(0,0,subpicture.width,subpicture.height);         vo_draw_text(subpicture.width, subpicture.height, draw_osd_fnc);      }      XvMCSyncSubpicture(mDisplay,&subpicture);//todo usleeep wait!      if(subpicture_mode == BLEND_SUBPICTURE){         osd_rndr = find_free_surface();         if(osd_rndr == NULL)             return;// no free surface to draw OSD in         rez = XvMCBlendSubpicture2(mDisplay,                       p_render_surface_to_show->p_surface, osd_rndr->p_surface,                       &subpicture,                       0, 0, subpicture.width, subpicture.height,                       0, 0, image_width, image_height);         if(rez!=Success){            printf("vo_xvmc: BlendSubpicture failed rez=%d\n",rez);            assert(0);            return;         }//       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->display_flags = p_render_surface_to_show->display_flags;//add more if needed    osd_rndr-> = p_render_surface_to_show->;         p_render_surface_to_show->state &= ~MP_XVMC_STATE_DISPLAY_PENDING;         p_render_surface_to_show->state |= MP_XVMC_STATE_OSD_SOURCE;         p_render_surface_to_show->p_osd_target_surface_render = osd_rndr;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?