Mercurial > mplayer.hg
comparison libvo/vo_xvmc.c @ 28642:fd68de39e9f6
Cosmetics part 1. Reindent to 4 spaces.
Checked for equality with diff -b.
author | iive |
---|---|
date | Fri, 20 Feb 2009 22:13:31 +0000 |
parents | 531d876a808f |
children | fcc8d7b273d4 |
comparison
equal
deleted
inserted
replaced
28641:531d876a808f | 28642:fd68de39e9f6 |
---|---|
117 static void clear_osd_subpic(int x0,int y0, int w,int h); | 117 static void clear_osd_subpic(int x0,int y0, int w,int h); |
118 static void init_osd_yuv_pal(void); | 118 static void init_osd_yuv_pal(void); |
119 | 119 |
120 | 120 |
121 static const struct{ | 121 static const struct{ |
122 int id;//id as xvimages or as mplayer RGB|{8,15,16,24,32} | 122 int id;//id as xvimages or as mplayer RGB|{8,15,16,24,32} |
123 void (* init_func_ptr)(); | 123 void (* init_func_ptr)(); |
124 void (* draw_func_ptr)(); | 124 void (* draw_func_ptr)(); |
125 void (* clear_func_ptr)(); | 125 void (* clear_func_ptr)(); |
126 } osd_render[]={ | 126 } osd_render[]={ |
127 {0x34344149,init_osd_yuv_pal,draw_osd_AI44,clear_osd_subpic}, | 127 {0x34344149,init_osd_yuv_pal,draw_osd_AI44,clear_osd_subpic}, |
128 {0x34344941,init_osd_yuv_pal,draw_osd_IA44,clear_osd_subpic}, | 128 {0x34344941,init_osd_yuv_pal,draw_osd_IA44,clear_osd_subpic}, |
129 {0,NULL,NULL,NULL} | 129 {0,NULL,NULL,NULL} |
130 }; | 130 }; |
131 | 131 |
132 static void xvmc_free(void); | 132 static void xvmc_free(void); |
133 static void xvmc_clean_surfaces(void); | 133 static void xvmc_clean_surfaces(void); |
134 static int count_free_surfaces(void); | 134 static int count_free_surfaces(void); |
135 static struct xvmc_pix_fmt *find_free_surface(void); | 135 static struct xvmc_pix_fmt *find_free_surface(void); |
136 | 136 |
137 static const vo_info_t info = { | 137 static const vo_info_t info = { |
138 "XVideo Motion Compensation", | 138 "XVideo Motion Compensation", |
139 "xvmc", | 139 "xvmc", |
140 "Ivan Kalvachev <iive@users.sf.net>", | 140 "Ivan Kalvachev <iive@users.sf.net>", |
141 "" | 141 "" |
142 }; | 142 }; |
143 | 143 |
144 const LIBVO_EXTERN(xvmc); | 144 const LIBVO_EXTERN(xvmc); |
145 | 145 |
146 //shm stuff from vo_xv | 146 //shm stuff from vo_xv |
156 /* | 156 /* |
157 * allocate XvImages. FIXME: no error checking, without | 157 * allocate XvImages. FIXME: no error checking, without |
158 * mit-shm this will bomb... trzing to fix ::atmos | 158 * mit-shm this will bomb... trzing to fix ::atmos |
159 */ | 159 */ |
160 #ifdef HAVE_SHM | 160 #ifdef HAVE_SHM |
161 if ( mLocalDisplay && XShmQueryExtension( mDisplay ) ) Shmem_Flag = 1; | 161 if ( mLocalDisplay && XShmQueryExtension( mDisplay ) ) Shmem_Flag = 1; |
162 else | 162 else |
163 { | 163 { |
164 Shmem_Flag = 0; | 164 Shmem_Flag = 0; |
165 mp_msg(MSGT_VO,MSGL_INFO, "Shared memory not supported\nReverting to normal Xv\n" ); | 165 mp_msg(MSGT_VO,MSGL_INFO, "Shared memory not supported\nReverting to normal Xv\n" ); |
166 } | 166 } |
167 if ( Shmem_Flag ) | 167 if ( Shmem_Flag ) |
168 { | 168 { |
169 xvimage = (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format, | 169 xvimage = (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format, |
170 NULL, xvimage_width, xvimage_height, &Shminfo); | 170 NULL, xvimage_width, xvimage_height, &Shminfo); |
171 | 171 |
172 Shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size, IPC_CREAT | 0777); | 172 Shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size, IPC_CREAT | 0777); |
173 Shminfo.shmaddr = (char *) shmat(Shminfo.shmid, 0, 0); | 173 Shminfo.shmaddr = (char *) shmat(Shminfo.shmid, 0, 0); |
174 Shminfo.readOnly = False; | 174 Shminfo.readOnly = False; |
175 | 175 |
176 xvimage->data = Shminfo.shmaddr; | 176 xvimage->data = Shminfo.shmaddr; |
177 XShmAttach(mDisplay, &Shminfo); | 177 XShmAttach(mDisplay, &Shminfo); |
178 XSync(mDisplay, False); | 178 XSync(mDisplay, False); |
179 shmctl(Shminfo.shmid, IPC_RMID, 0); | 179 shmctl(Shminfo.shmid, IPC_RMID, 0); |
180 } | 180 } |
181 else | 181 else |
182 #endif | 182 #endif |
183 { | 183 { |
184 xvimage = (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL, xvimage_width, xvimage_height); | 184 xvimage = (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL, xvimage_width, xvimage_height); |
185 xvimage->data = malloc(xvimage->data_size); | 185 xvimage->data = malloc(xvimage->data_size); |
186 XSync(mDisplay,False); | 186 XSync(mDisplay,False); |
187 } | 187 } |
188 // memset(xvimage->data,128,xvimage->data_size); | 188 // memset(xvimage->data,128,xvimage->data_size); |
189 return; | 189 return; |
190 } | 190 } |
191 | 191 |
192 static void deallocate_xvimage(void) | 192 static void deallocate_xvimage(void) |
193 { | 193 { |
194 #ifdef HAVE_SHM | 194 #ifdef HAVE_SHM |
195 if ( Shmem_Flag ) | 195 if ( Shmem_Flag ) |
196 { | 196 { |
197 XShmDetach( mDisplay,&Shminfo ); | 197 XShmDetach( mDisplay,&Shminfo ); |
198 shmdt( Shminfo.shmaddr ); | 198 shmdt( Shminfo.shmaddr ); |
199 } | 199 } |
200 else | 200 else |
201 #endif | 201 #endif |
202 { | 202 { |
203 free(xvimage->data); | 203 free(xvimage->data); |
204 } | 204 } |
205 XFree(xvimage); | 205 XFree(xvimage); |
206 | 206 |
207 XSync(mDisplay, False); | 207 XSync(mDisplay, False); |
208 return; | 208 return; |
209 } | 209 } |
210 //end of vo_xv shm/xvimage code | 210 //end of vo_xv shm/xvimage code |
211 | 211 |
212 static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ | 212 static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ |
213 if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ | 213 if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ |
214 if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; | 214 if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; |
215 if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; | 215 if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; |
216 return 0; | 216 return 0; |
217 } | 217 } |
218 if ( format == IMGFMT_XVMC_MOCO_MPEG2 ){ | 218 if ( format == IMGFMT_XVMC_MOCO_MPEG2 ){ |
219 if(surf_info->mc_type != XVMC_MPEG_2) return -1; | 219 if(surf_info->mc_type != XVMC_MPEG_2) return -1; |
220 if(surf_info->chroma_format != XVMC_CHROMA_FORMAT_420) return -1; | 220 if(surf_info->chroma_format != XVMC_CHROMA_FORMAT_420) return -1; |
221 return 0; | 221 return 0; |
222 } | 222 } |
223 return -1;//fail | 223 return -1;//fail |
224 } | 224 } |
225 | 225 |
226 //print all info needed to add new format | 226 //print all info needed to add new format |
227 static void print_xvimage_format_values(XvImageFormatValues *xifv){ | 227 static void print_xvimage_format_values(XvImageFormatValues *xifv){ |
228 int i; | 228 int i; |
229 printf("Format_ID = 0x%X\n",xifv->id); | 229 printf("Format_ID = 0x%X\n",xifv->id); |
230 | 230 |
231 printf(" type = "); | 231 printf(" type = "); |
232 if(xifv->type == XvRGB) printf("RGB\n"); | 232 if(xifv->type == XvRGB) printf("RGB\n"); |
233 else if(xifv->type == XvYUV) printf("YUV\n"); | 233 else if(xifv->type == XvYUV) printf("YUV\n"); |
234 else printf("Unknown\n"); | 234 else printf("Unknown\n"); |
235 | 235 |
236 printf(" byte_order = "); | 236 printf(" byte_order = "); |
237 if(xifv->byte_order == LSBFirst) printf("LSB First\n"); | 237 if(xifv->byte_order == LSBFirst) printf("LSB First\n"); |
238 else if(xifv->type == MSBFirst) printf("MSB First\n"); | 238 else if(xifv->type == MSBFirst) printf("MSB First\n"); |
239 else printf("Unknown\n");//yes Linux support other types too | 239 else printf("Unknown\n");//yes Linux support other types too |
240 | 240 |
241 printf(" guid = "); | 241 printf(" guid = "); |
242 for(i=0;i<16;i++) | 242 for(i=0;i<16;i++) |
243 printf("%02X ",(unsigned char)xifv->guid[i]); | 243 printf("%02X ",(unsigned char)xifv->guid[i]); |
244 printf("\n"); | 244 printf("\n"); |
245 | 245 |
246 printf(" bits_per_pixel = %d\n",xifv->bits_per_pixel); | 246 printf(" bits_per_pixel = %d\n",xifv->bits_per_pixel); |
247 | 247 |
248 printf(" format = "); | 248 printf(" format = "); |
249 if(xifv->format == XvPacked) printf("XvPacked\n"); | 249 if(xifv->format == XvPacked) printf("XvPacked\n"); |
250 else if(xifv->format == XvPlanar) printf("XvPlanar\n"); | 250 else if(xifv->format == XvPlanar) printf("XvPlanar\n"); |
251 else printf("Unknown\n"); | 251 else printf("Unknown\n"); |
252 | 252 |
253 printf(" num_planes = %d\n",xifv->num_planes); | 253 printf(" num_planes = %d\n",xifv->num_planes); |
254 | 254 |
255 if(xifv->type == XvRGB){ | 255 if(xifv->type == XvRGB){ |
256 printf(" red_mask = %0X\n", xifv->red_mask); | 256 printf(" red_mask = %0X\n", xifv->red_mask); |
257 printf(" green_mask = %0X\n",xifv->green_mask); | 257 printf(" green_mask = %0X\n",xifv->green_mask); |
258 printf(" blue_mask = %0X\n", xifv->blue_mask); | 258 printf(" blue_mask = %0X\n", xifv->blue_mask); |
259 } | 259 } |
260 if(xifv->type == XvYUV){ | 260 if(xifv->type == XvYUV){ |
261 printf(" y_sample_bits = %d\n u_sample_bits = %d\n v_sample_bits = %d\n", | 261 printf(" y_sample_bits = %d\n u_sample_bits = %d\n v_sample_bits = %d\n", |
262 xifv->y_sample_bits,xifv->u_sample_bits,xifv->v_sample_bits); | 262 xifv->y_sample_bits,xifv->u_sample_bits,xifv->v_sample_bits); |
263 printf(" horz_y_period = %d\n horz_u_period = %d\n horz_v_period = %d\n", | 263 printf(" horz_y_period = %d\n horz_u_period = %d\n horz_v_period = %d\n", |
264 xifv->horz_y_period,xifv->horz_u_period,xifv->horz_v_period); | 264 xifv->horz_y_period,xifv->horz_u_period,xifv->horz_v_period); |
265 printf(" vert_y_period = %d\n vert_u_period = %d\n vert_v_period = %d\n", | 265 printf(" vert_y_period = %d\n vert_u_period = %d\n vert_v_period = %d\n", |
266 xifv->vert_y_period,xifv->vert_u_period,xifv->vert_v_period); | 266 xifv->vert_y_period,xifv->vert_u_period,xifv->vert_v_period); |
267 | 267 |
268 printf(" component_order = "); | 268 printf(" component_order = "); |
269 for(i=0;i<32;i++) | 269 for(i=0;i<32;i++) |
270 if(xifv->component_order[i]>=32) | 270 if(xifv->component_order[i]>=32) |
271 printf("%c",xifv->component_order[i]); | 271 printf("%c",xifv->component_order[i]); |
272 printf("\n"); | 272 printf("\n"); |
273 | 273 |
274 printf(" scanline = "); | 274 printf(" scanline = "); |
275 if(xifv->scanline_order == XvTopToBottom) printf("XvTopToBottom\n"); | 275 if(xifv->scanline_order == XvTopToBottom) printf("XvTopToBottom\n"); |
276 else if(xifv->scanline_order == XvBottomToTop) printf("XvBottomToTop\n"); | 276 else if(xifv->scanline_order == XvBottomToTop) printf("XvBottomToTop\n"); |
277 else printf("Unknown\n"); | 277 else printf("Unknown\n"); |
278 } | 278 } |
279 printf("\n"); | 279 printf("\n"); |
280 } | 280 } |
281 | 281 |
282 // WARNING This function may changes xv_port and surface_info! | 282 // WARNING This function may changes xv_port and surface_info! |
283 static int xvmc_find_surface_by_format(int format,int width,int height, | 283 static int xvmc_find_surface_by_format(int format,int width,int height, |
284 XvMCSurfaceInfo * surf_info,int query){ | 284 XvMCSurfaceInfo * surf_info,int query){ |
285 int rez; | 285 int rez; |
286 XvAdaptorInfo * ai; | 286 XvAdaptorInfo * ai; |
287 int num_adaptors,i; | 287 int num_adaptors,i; |
288 unsigned long p; | 288 unsigned long p; |
289 int s,mc_surf_num; | 289 int s,mc_surf_num; |
290 XvMCSurfaceInfo * mc_surf_list; | 290 XvMCSurfaceInfo * mc_surf_list; |
291 | 291 |
292 rez = XvQueryAdaptors(mDisplay,DefaultRootWindow(mDisplay),&num_adaptors,&ai); | 292 rez = XvQueryAdaptors(mDisplay,DefaultRootWindow(mDisplay),&num_adaptors,&ai); |
293 if( rez != Success ) return -1; | 293 if( rez != Success ) return -1; |
294 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | 294 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { |
295 printf("vo_xvmc: Querying %d adaptors\n",num_adaptors); } | 295 printf("vo_xvmc: Querying %d adaptors\n",num_adaptors); } |
296 for(i=0; i<num_adaptors; i++) | 296 for(i=0; i<num_adaptors; i++) |
297 { | 297 { |
298 /* check if adaptor number has been specified */ | 298 /* check if adaptor number has been specified */ |
299 if (xv_adaptor != -1 && xv_adaptor != i) | 299 if (xv_adaptor != -1 && xv_adaptor != i) |
300 continue; | 300 continue; |
301 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | 301 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { |
302 printf("vo_xvmc: Quering adaptor #%d\n",i); } | 302 printf("vo_xvmc: Quering adaptor #%d\n",i); } |
303 if( ai[i].type == 0 ) continue;// we need at least dummy type! | 303 if( ai[i].type == 0 ) continue;// we need at least dummy type! |
304 //probing ports | 304 //probing ports |
305 for(p=ai[i].base_id; p<ai[i].base_id+ai[i].num_ports; p++) | 305 for(p=ai[i].base_id; p<ai[i].base_id+ai[i].num_ports; p++) |
306 { | 306 { |
307 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | |
308 printf("vo_xvmc: probing port #%ld\n",p); } | |
309 mc_surf_list = XvMCListSurfaceTypes(mDisplay,p,&mc_surf_num); | |
310 if( mc_surf_list == NULL || mc_surf_num == 0){ | |
311 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | 307 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { |
312 printf("vo_xvmc: No XvMC supported. \n"); } | 308 printf("vo_xvmc: probing port #%ld\n",p); } |
313 continue; | 309 mc_surf_list = XvMCListSurfaceTypes(mDisplay,p,&mc_surf_num); |
314 } | 310 if( mc_surf_list == NULL || mc_surf_num == 0){ |
315 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | 311 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { |
316 printf("vo_xvmc: XvMC list have %d surfaces\n",mc_surf_num); } | 312 printf("vo_xvmc: No XvMC supported. \n"); } |
313 continue; | |
314 } | |
315 if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | |
316 printf("vo_xvmc: XvMC list have %d surfaces\n",mc_surf_num); } | |
317 //we have XvMC list! | 317 //we have XvMC list! |
318 for(s=0; s<mc_surf_num; s++) | 318 for(s=0; s<mc_surf_num; s++) |
319 { | 319 { |
320 if( width > mc_surf_list[s].max_width ) continue; | 320 if( width > mc_surf_list[s].max_width ) continue; |
321 if( height > mc_surf_list[s].max_height ) continue; | 321 if( height > mc_surf_list[s].max_height ) continue; |
322 if( xvmc_check_surface_format(format,&mc_surf_list[s])<0 ) continue; | 322 if( xvmc_check_surface_format(format,&mc_surf_list[s])<0 ) continue; |
323 //we have match! | 323 //we have match! |
324 /* respect the users wish */ | 324 /* respect the users wish */ |
325 if ( xv_port_request != 0 && xv_port_request != p ) | 325 if ( xv_port_request != 0 && xv_port_request != p ) |
326 { | 326 { |
327 continue; | 327 continue; |
328 } | 328 } |
329 | 329 |
330 if(!query){ | 330 if(!query){ |
331 rez = XvGrabPort(mDisplay,p,CurrentTime); | 331 rez = XvGrabPort(mDisplay,p,CurrentTime); |
332 if(rez != Success){ | 332 if(rez != Success){ |
333 if ( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { | 333 if ( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { |
334 printf("vo_xvmc: Fail to grab port %ld\n",p); } | 334 printf("vo_xvmc: Fail to grab port %ld\n",p); } |
335 continue; | 335 continue; |
336 } | 336 } |
337 printf("vo_xvmc: Using Xv Adaptor #%d (%s)\n", i, ai[i].name); | 337 printf("vo_xvmc: Using Xv Adaptor #%d (%s)\n", i, ai[i].name); |
338 printf("vo_xvmc: Port %ld grabed\n",p); | 338 printf("vo_xvmc: Port %ld grabed\n",p); |
339 xv_port = p; | 339 xv_port = p; |
340 } | 340 } |
341 goto surface_found; | 341 goto surface_found; |
342 }//for mc surf | 342 }//for mc surf |
343 XFree(mc_surf_list);//if mc_surf_num==0 is list==NULL ? | 343 XFree(mc_surf_list);//if mc_surf_num==0 is list==NULL ? |
344 }//for ports | 344 }//for ports |
345 }//for adaptors | 345 }//for adaptors |
346 XvFreeAdaptorInfo(ai); | 346 XvFreeAdaptorInfo(ai); |
347 | 347 |
348 if(!query) printf("vo_xvmc: Could not find free matching surface. Sorry.\n"); | 348 if(!query) printf("vo_xvmc: Could not find free matching surface. Sorry.\n"); |
349 return 0; | 349 return 0; |
350 | 350 |
351 // somebody know cleaner way to escape from 3 internal loops? | 351 // somebody know cleaner way to escape from 3 internal loops? |
352 surface_found: | 352 surface_found: |
353 XvFreeAdaptorInfo(ai); | 353 XvFreeAdaptorInfo(ai); |
354 | 354 |
355 memcpy(surf_info,&mc_surf_list[s],sizeof(XvMCSurfaceInfo)); | 355 memcpy(surf_info,&mc_surf_list[s],sizeof(XvMCSurfaceInfo)); |
356 if( mp_msg_test(MSGT_VO,MSGL_DBG3) || !query) | 356 if( mp_msg_test(MSGT_VO,MSGL_DBG3) || !query) |
357 printf("vo_xvmc: Found matching surface with id=%X on %ld port at %d adapter\n", | 357 printf("vo_xvmc: Found matching surface with id=%X on %ld port at %d adapter\n", |
358 mc_surf_list[s].surface_type_id,p,i); | 358 mc_surf_list[s].surface_type_id,p,i); |
359 return mc_surf_list[s].surface_type_id; | 359 return mc_surf_list[s].surface_type_id; |
360 } | 360 } |
361 | 361 |
362 static uint32_t xvmc_draw_image(mp_image_t *mpi){ | 362 static uint32_t xvmc_draw_image(mp_image_t *mpi){ |
363 struct xvmc_pix_fmt *rndr; | 363 struct xvmc_pix_fmt *rndr; |
364 | 364 |
365 assert(mpi!=NULL); | 365 assert(mpi!=NULL); |
366 assert(mpi->flags &MP_IMGFLAG_DIRECT); | 366 assert(mpi->flags &MP_IMGFLAG_DIRECT); |
367 // assert(mpi->flags &MP_IMGFLAGS_DRAWBACK); | 367 // assert(mpi->flags &MP_IMGFLAGS_DRAWBACK); |
368 | 368 |
369 rndr = (struct xvmc_pix_fmt*)mpi->priv; //there is copy in plane[2] | 369 rndr = (struct xvmc_pix_fmt*)mpi->priv; //there is copy in plane[2] |
370 assert( rndr != NULL ); | 370 assert( rndr != NULL ); |
371 assert( rndr->xvmc_id == AV_XVMC_ID ); | 371 assert( rndr->xvmc_id == AV_XVMC_ID ); |
372 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 372 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
373 printf("vo_xvmc: draw_image(show rndr=%p)\n",rndr); | 373 printf("vo_xvmc: draw_image(show rndr=%p)\n",rndr); |
374 // the surface have passed vf system without been skiped, it will be displayed | 374 // the surface have passed vf system without been skiped, it will be displayed |
375 rndr->state |= AV_XVMC_STATE_DISPLAY_PENDING; | 375 rndr->state |= AV_XVMC_STATE_DISPLAY_PENDING; |
376 p_render_surface_to_show = rndr; | 376 p_render_surface_to_show = rndr; |
377 top_field_first = mpi->fields & MP_IMGFIELD_TOP_FIRST; | 377 top_field_first = mpi->fields & MP_IMGFIELD_TOP_FIRST; |
378 return VO_TRUE; | 378 return VO_TRUE; |
379 } | 379 } |
380 | 380 |
381 static int preinit(const char *arg){ | 381 static int preinit(const char *arg){ |
382 int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; | 382 int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; |
383 int mc_eventBase,mc_errorBase; | 383 int mc_eventBase,mc_errorBase; |
384 int mc_ver,mc_rev; | 384 int mc_ver,mc_rev; |
385 strarg_t ck_src_arg = { 0, NULL }; | 385 strarg_t ck_src_arg = { 0, NULL }; |
386 strarg_t ck_method_arg = { 0, NULL }; | 386 strarg_t ck_method_arg = { 0, NULL }; |
387 opt_t subopts [] = | 387 opt_t subopts [] = |
388 { | 388 { |
389 /* name arg type arg var test */ | 389 /* name arg type arg var test */ |
390 { "port", OPT_ARG_INT, &xv_port_request, (opt_test_f)int_pos }, | 390 { "port", OPT_ARG_INT, &xv_port_request, (opt_test_f)int_pos }, |
391 { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg }, | 391 { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg }, |
392 { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, | 392 { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, |
393 { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, | 393 { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, |
394 { "benchmark", OPT_ARG_BOOL, &benchmark, NULL }, | 394 { "benchmark", OPT_ARG_BOOL, &benchmark, NULL }, |
395 { "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, | 395 { "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, |
396 { "queue", OPT_ARG_BOOL, &use_queue, NULL }, | 396 { "queue", OPT_ARG_BOOL, &use_queue, NULL }, |
397 { "bobdeint", OPT_ARG_BOOL, &bob_deinterlace, NULL }, | 397 { "bobdeint", OPT_ARG_BOOL, &bob_deinterlace, NULL }, |
398 { NULL } | 398 { NULL } |
399 }; | 399 }; |
400 | 400 |
401 //Obtain display handler | 401 //Obtain display handler |
402 if (!vo_init()) return -1;//vo_xv | 402 if (!vo_init()) return -1;//vo_xv |
403 | 403 |
404 //XvMC is subdivision of XVideo | 404 //XvMC is subdivision of XVideo |
405 if (Success != XvQueryExtension(mDisplay,&xv_version,&xv_release,&xv_request_base, | 405 if (Success != XvQueryExtension(mDisplay,&xv_version,&xv_release,&xv_request_base, |
406 &xv_event_base,&xv_error_base) ){ | 406 &xv_event_base,&xv_error_base) ){ |
407 mp_msg(MSGT_VO,MSGL_ERR,"Sorry, Xv(MC) not supported by this X11 version/driver\n"); | 407 mp_msg(MSGT_VO,MSGL_ERR,"Sorry, Xv(MC) not supported by this X11 version/driver\n"); |
408 mp_msg(MSGT_VO,MSGL_ERR,"********** Try with -vo x11 or -vo sdl ***********\n"); | 408 mp_msg(MSGT_VO,MSGL_ERR,"********** Try with -vo x11 or -vo sdl ***********\n"); |
409 return -1; | 409 return -1; |
410 } | 410 } |
411 printf("vo_xvmc: X-Video extension %d.%d\n",xv_version,xv_release); | 411 printf("vo_xvmc: X-Video extension %d.%d\n",xv_version,xv_release); |
412 | 412 |
413 if( True != XvMCQueryExtension(mDisplay,&mc_eventBase,&mc_errorBase) ){ | 413 if( True != XvMCQueryExtension(mDisplay,&mc_eventBase,&mc_errorBase) ){ |
414 printf("vo_xvmc: No X-Video MotionCompensation Extension on %s\n", | 414 printf("vo_xvmc: No X-Video MotionCompensation Extension on %s\n", |
415 XDisplayName(NULL)); | 415 XDisplayName(NULL)); |
416 return -1; | 416 return -1; |
417 } | 417 } |
418 | 418 |
419 if(Success == XvMCQueryVersion(mDisplay, &mc_ver, &mc_rev) ){ | 419 if(Success == XvMCQueryVersion(mDisplay, &mc_ver, &mc_rev) ){ |
420 printf("vo_xvmc: X-Video MotionCompensation Extension version %i.%i\n", | 420 printf("vo_xvmc: X-Video MotionCompensation Extension version %i.%i\n", |
421 mc_ver,mc_rev); | 421 mc_ver,mc_rev); |
422 } | 422 } |
423 else{ | 423 else{ |
424 printf("vo_xvmc: Error querying version info!\n"); | 424 printf("vo_xvmc: Error querying version info!\n"); |
425 return -1; | 425 return -1; |
426 } | 426 } |
427 surface_render = NULL; | 427 surface_render = NULL; |
428 xv_port = 0; | 428 xv_port = 0; |
429 number_of_surfaces = 0; | 429 number_of_surfaces = 0; |
430 subpicture_alloc = 0; | 430 subpicture_alloc = 0; |
431 | 431 |
432 benchmark = 0; //disable PutImageto allow faster display than screen refresh | 432 benchmark = 0; //disable PutImageto allow faster display than screen refresh |
433 use_sleep = 0; | 433 use_sleep = 0; |
434 use_queue = 0; | 434 use_queue = 0; |
435 bob_deinterlace = 0; | 435 bob_deinterlace = 0; |
436 | 436 |
437 /* parse suboptions */ | 437 /* parse suboptions */ |
438 if ( subopt_parse( arg, subopts ) != 0 ) | 438 if ( subopt_parse( arg, subopts ) != 0 ) |
439 { | 439 { |
440 return -1; | 440 return -1; |
441 } | 441 } |
442 | 442 |
443 xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); | 443 xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); |
444 | 444 |
445 return 0; | 445 return 0; |
446 } | 446 } |
447 | 447 |
448 static int config(uint32_t width, uint32_t height, | 448 static int config(uint32_t width, uint32_t height, |
449 uint32_t d_width, uint32_t d_height, | 449 uint32_t d_width, uint32_t d_height, |
450 uint32_t flags, char *title, uint32_t format){ | 450 uint32_t flags, char *title, uint32_t format){ |
460 #ifdef CONFIG_XF86VM | 460 #ifdef CONFIG_XF86VM |
461 int vm = flags & VOFLAG_MODESWITCHING; | 461 int vm = flags & VOFLAG_MODESWITCHING; |
462 #endif | 462 #endif |
463 //end of vo_xv | 463 //end of vo_xv |
464 | 464 |
465 if( !IMGFMT_IS_XVMC(format) ) | 465 if( !IMGFMT_IS_XVMC(format) ) |
466 { | 466 { |
467 assert(0);//should never happen, abort on debug or | 467 assert(0);//should never happen, abort on debug or |
468 return 1;//return error on relese | 468 return 1;//return error on relese |
469 } | 469 } |
470 | 470 |
471 // Find free port that supports MC, by querying adaptors | 471 // Find free port that supports MC, by querying adaptors |
472 if( xv_port != 0 || number_of_surfaces != 0 ){ | 472 if( xv_port != 0 || number_of_surfaces != 0 ){ |
473 if( height==image_height && width==image_width && image_format==format){ | 473 if( height==image_height && width==image_width && image_format==format){ |
474 xvmc_clean_surfaces(); | 474 xvmc_clean_surfaces(); |
475 goto skip_surface_allocation; | 475 goto skip_surface_allocation; |
476 } | 476 } |
477 xvmc_free(); | 477 xvmc_free(); |
478 }; | 478 }; |
479 numblocks=((width+15)/16)*((height+15)/16); | 479 numblocks=((width+15)/16)*((height+15)/16); |
480 // Find Supported Surface Type | 480 // Find Supported Surface Type |
481 mode_id = xvmc_find_surface_by_format(format,width,height,&surface_info,0);//false=1 to grab port, not query | 481 mode_id = xvmc_find_surface_by_format(format,width,height,&surface_info,0);//false=1 to grab port, not query |
482 if ( mode_id == 0 ) | 482 if ( mode_id == 0 ) |
483 { | 483 { |
484 return -1; | 484 return -1; |
485 } | 485 } |
486 | 486 |
487 rez = XvMCCreateContext(mDisplay, xv_port,mode_id,width,height,XVMC_DIRECT,&ctx); | 487 rez = XvMCCreateContext(mDisplay, xv_port,mode_id,width,height,XVMC_DIRECT,&ctx); |
488 if( rez != Success ){ | 488 if( rez != Success ){ |
489 printf("vo_xvmc: XvMCCreateContext failed with error %d\n",rez); | 489 printf("vo_xvmc: XvMCCreateContext failed with error %d\n",rez); |
490 return -1; | 490 return -1; |
491 } | 491 } |
492 if( ctx.flags & XVMC_DIRECT ){ | 492 if( ctx.flags & XVMC_DIRECT ){ |
493 printf("vo_xvmc: Allocated Direct Context\n"); | 493 printf("vo_xvmc: Allocated Direct Context\n"); |
494 }else{ | 494 }else{ |
495 printf("vo_xvmc: Allocated Indirect Context!\n"); | 495 printf("vo_xvmc: Allocated Indirect Context!\n"); |
496 } | 496 } |
497 | 497 |
498 | 498 |
499 blocks_per_macroblock = 6; | 499 blocks_per_macroblock = 6; |
500 if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_422) | 500 if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_422) |
501 blocks_per_macroblock = 8; | 501 blocks_per_macroblock = 8; |
502 if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444) | 502 if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444) |
503 blocks_per_macroblock = 12; | 503 blocks_per_macroblock = 12; |
504 | 504 |
505 rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks); | 505 rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks); |
506 if( rez != Success ){ | 506 if( rez != Success ){ |
507 XvMCDestroyContext(mDisplay,&ctx); | 507 XvMCDestroyContext(mDisplay,&ctx); |
508 return -1; | 508 return -1; |
509 } | 509 } |
510 printf("vo_xvmc: data_blocks allocated\n"); | 510 printf("vo_xvmc: data_blocks allocated\n"); |
511 | 511 |
512 rez = XvMCCreateMacroBlocks(mDisplay,&ctx,numblocks,&mv_blocks); | 512 rez = XvMCCreateMacroBlocks(mDisplay,&ctx,numblocks,&mv_blocks); |
513 if( rez != Success ){ | 513 if( rez != Success ){ |
514 XvMCDestroyBlocks(mDisplay,&data_blocks); | 514 XvMCDestroyBlocks(mDisplay,&data_blocks); |
515 XvMCDestroyContext(mDisplay,&ctx); | 515 XvMCDestroyContext(mDisplay,&ctx); |
516 return -1; | 516 return -1; |
517 } | 517 } |
518 printf("vo_xvmc: mv_blocks allocated\n"); | 518 printf("vo_xvmc: mv_blocks allocated\n"); |
519 | 519 |
520 if(surface_render==NULL) | 520 if(surface_render==NULL) |
521 surface_render = malloc(MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //easy mem debug | 521 surface_render = malloc(MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //easy mem debug |
522 memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); | 522 memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); |
523 | 523 |
524 for(i=0; i<MAX_SURFACES; i++){ | 524 for(i=0; i<MAX_SURFACES; i++){ |
525 rez=XvMCCreateSurface(mDisplay,&ctx,&surface_array[i]); | 525 rez=XvMCCreateSurface(mDisplay,&ctx,&surface_array[i]); |
526 if( rez != Success ) | 526 if( rez != Success ) |
527 break; | 527 break; |
528 surface_render[i].xvmc_id = AV_XVMC_ID; | 528 surface_render[i].xvmc_id = AV_XVMC_ID; |
529 surface_render[i].data_blocks = data_blocks.blocks; | 529 surface_render[i].data_blocks = data_blocks.blocks; |
530 surface_render[i].mv_blocks = mv_blocks.macro_blocks; | 530 surface_render[i].mv_blocks = mv_blocks.macro_blocks; |
531 surface_render[i].allocated_mv_blocks = numblocks; | 531 surface_render[i].allocated_mv_blocks = numblocks; |
532 surface_render[i].allocated_data_blocks = numblocks*blocks_per_macroblock; | 532 surface_render[i].allocated_data_blocks = numblocks*blocks_per_macroblock; |
533 surface_render[i].idct = (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT; | 533 surface_render[i].idct = (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT; |
534 surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; | 534 surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; |
535 surface_render[i].p_surface = &surface_array[i]; | 535 surface_render[i].p_surface = &surface_array[i]; |
536 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 536 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
537 printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]); | 537 printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]); |
538 } | 538 } |
539 number_of_surfaces = i; | 539 number_of_surfaces = i; |
540 if( number_of_surfaces < 4 ){// +2 I or P and +2 for B (to avoid visible motion drawing) | 540 if( number_of_surfaces < 4 ){// +2 I or P and +2 for B (to avoid visible motion drawing) |
541 printf("vo_xvmc: Unable to allocate at least 4 Surfaces\n"); | 541 printf("vo_xvmc: Unable to allocate at least 4 Surfaces\n"); |
542 uninit(); | 542 uninit(); |
543 return -1; | 543 return -1; |
544 } | 544 } |
545 printf("vo_xvmc: Motion Compensation context allocated - %d surfaces\n", | 545 printf("vo_xvmc: Motion Compensation context allocated - %d surfaces\n", |
546 number_of_surfaces); | 546 number_of_surfaces); |
547 | 547 |
548 //debug | 548 //debug |
549 printf("vo_xvmc: idct=%d unsigned_intra=%d\n", | 549 printf("vo_xvmc: idct=%d unsigned_intra=%d\n", |
550 (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT, | 550 (surface_info.mc_type & XVMC_IDCT) == XVMC_IDCT, |
551 (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED); | 551 (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED); |
552 | 552 |
553 // Find way to display OSD & subtitle | 553 // Find way to display OSD & subtitle |
554 printf("vo_xvmc: looking for OSD support\n"); | 554 printf("vo_xvmc: looking for OSD support\n"); |
555 subpicture_mode = NO_SUBPICTURE; | 555 subpicture_mode = NO_SUBPICTURE; |
556 if(surface_info.flags & XVMC_OVERLAID_SURFACE) | 556 if(surface_info.flags & XVMC_OVERLAID_SURFACE) |
557 subpicture_mode = OVERLAY_SUBPICTURE; | 557 subpicture_mode = OVERLAY_SUBPICTURE; |
558 | 558 |
559 if(surface_info.subpicture_max_width != 0 && | 559 if(surface_info.subpicture_max_width != 0 && |
560 surface_info.subpicture_max_height != 0 ){ | 560 surface_info.subpicture_max_height != 0 ){ |
561 int s,k,num_subpic; | 561 int s,k,num_subpic; |
562 | 562 |
563 XvImageFormatValues * xvfmv; | 563 XvImageFormatValues * xvfmv; |
564 xvfmv = XvMCListSubpictureTypes(mDisplay, xv_port, | 564 xvfmv = XvMCListSubpictureTypes(mDisplay, xv_port, |
565 surface_info.surface_type_id, &num_subpic); | 565 surface_info.surface_type_id, &num_subpic); |
566 | 566 |
567 if(num_subpic != 0 && xvfmv != NULL){ | 567 if(num_subpic != 0 && xvfmv != NULL){ |
568 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){//Print all subpicture types for debug | 568 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){//Print all subpicture types for debug |
569 for(s=0;s<num_subpic;s++) | 569 for(s=0;s<num_subpic;s++) |
570 print_xvimage_format_values(&xvfmv[s]); | 570 print_xvimage_format_values(&xvfmv[s]); |
571 } | |
572 | |
573 for(s=0;s<num_subpic;s++){ | |
574 for(k=0;osd_render[k].draw_func_ptr!=NULL;k++){ | |
575 if(xvfmv[s].id == osd_render[k].id) | |
576 { | |
577 init_osd_fnc = osd_render[k].init_func_ptr; | |
578 draw_osd_fnc = osd_render[k].draw_func_ptr; | |
579 clear_osd_fnc = osd_render[k].clear_func_ptr; | |
580 | |
581 subpicture_mode = BLEND_SUBPICTURE; | |
582 subpicture_info = xvfmv[s]; | |
583 printf(" Subpicture id 0x%08X\n",subpicture_info.id); | |
584 goto found_subpic; | |
585 } | |
586 } | 571 } |
587 } | 572 |
573 for(s=0;s<num_subpic;s++){ | |
574 for(k=0;osd_render[k].draw_func_ptr!=NULL;k++){ | |
575 if(xvfmv[s].id == osd_render[k].id) | |
576 { | |
577 init_osd_fnc = osd_render[k].init_func_ptr; | |
578 draw_osd_fnc = osd_render[k].draw_func_ptr; | |
579 clear_osd_fnc = osd_render[k].clear_func_ptr; | |
580 | |
581 subpicture_mode = BLEND_SUBPICTURE; | |
582 subpicture_info = xvfmv[s]; | |
583 printf(" Subpicture id 0x%08X\n",subpicture_info.id); | |
584 goto found_subpic; | |
585 } | |
586 } | |
587 } | |
588 found_subpic: | 588 found_subpic: |
589 XFree(xvfmv); | 589 XFree(xvfmv); |
590 } | 590 } |
591 //Blend2 supicture is always possible, blend1 only at backend | 591 //Blend2 supicture is always possible, blend1 only at backend |
592 if( (subpicture_mode == BLEND_SUBPICTURE) && | 592 if( (subpicture_mode == BLEND_SUBPICTURE) && |
593 (surface_info.flags & XVMC_BACKEND_SUBPICTURE) ) | 593 (surface_info.flags & XVMC_BACKEND_SUBPICTURE) ) |
594 { | 594 { |
595 subpicture_mode = BACKEND_SUBPICTURE; | 595 subpicture_mode = BACKEND_SUBPICTURE; |
596 } | 596 } |
597 | 597 |
598 } | 598 } |
599 | 599 |
600 switch(subpicture_mode){ | 600 switch(subpicture_mode){ |
601 case NO_SUBPICTURE: | 601 case NO_SUBPICTURE: |
602 printf("vo_xvmc: No OSD support for this mode\n"); | 602 printf("vo_xvmc: No OSD support for this mode\n"); |
603 break; | 603 break; |
604 case OVERLAY_SUBPICTURE: | 604 case OVERLAY_SUBPICTURE: |
605 printf("vo_xvmc: OSD support via color key tricks\n"); | 605 printf("vo_xvmc: OSD support via color key tricks\n"); |
606 printf("vo_xvmc: not yet implemented:(\n"); | 606 printf("vo_xvmc: not yet implemented:(\n"); |
607 break; | 607 break; |
608 case BLEND_SUBPICTURE: | 608 case BLEND_SUBPICTURE: |
609 printf("vo_xvmc: OSD support by additional frontend rendering\n"); | 609 printf("vo_xvmc: OSD support by additional frontend rendering\n"); |
610 break; | 610 break; |
611 case BACKEND_SUBPICTURE: | 611 case BACKEND_SUBPICTURE: |
612 printf("vo_xvmc: OSD support by backend rendering (fast)\n"); | 612 printf("vo_xvmc: OSD support by backend rendering (fast)\n"); |
613 printf("vo_xvmc: Please send feedback to confirm that it works,otherwise send bugreport!\n"); | 613 printf("vo_xvmc: Please send feedback to confirm that it works,otherwise send bugreport!\n"); |
614 break; | 614 break; |
615 } | 615 } |
616 | 616 |
617 //take keycolor value and choose method for handling it | 617 //take keycolor value and choose method for handling it |
618 if ( !vo_xv_init_colorkey() ) | 618 if ( !vo_xv_init_colorkey() ) |
619 { | 619 { |
620 return -1; // bail out, colorkey setup failed | 620 return -1; // bail out, colorkey setup failed |
621 } | 621 } |
622 | 622 |
623 vo_xv_enable_vsync();//it won't break anything | 623 vo_xv_enable_vsync();//it won't break anything |
624 | 624 |
625 //taken from vo_xv | 625 //taken from vo_xv |
626 image_height = height; | 626 image_height = height; |
627 image_width = width; | 627 image_width = width; |
628 | 628 |
629 skip_surface_allocation: | 629 skip_surface_allocation: |
630 | 630 |
631 #ifdef CONFIG_GUI | 631 #ifdef CONFIG_GUI |
632 if(use_gui) | 632 if(use_gui) |
633 guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window | 633 guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window |
634 else | 634 else |
635 #endif | 635 #endif |
636 { | 636 { |
637 #ifdef CONFIG_XF86VM | 637 #ifdef CONFIG_XF86VM |
638 if ( vm ) | 638 if ( vm ) |
639 { | 639 { |
640 vo_vm_switch(); | 640 vo_vm_switch(); |
641 } | 641 } |
642 // else | 642 // else |
643 #endif | 643 #endif |
644 XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); | 644 XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); |
645 depth=attribs.depth; | 645 depth=attribs.depth; |
646 if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; | 646 if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; |
647 XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); | 647 XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); |
648 | 648 |
649 xswa.background_pixel = 0; | 649 xswa.background_pixel = 0; |
650 if (xv_ck_info.method == CK_METHOD_BACKGROUND) | 650 if (xv_ck_info.method == CK_METHOD_BACKGROUND) |
651 xswa.background_pixel = xv_colorkey; | 651 xswa.background_pixel = xv_colorkey; |
652 xswa.border_pixel = 0; | 652 xswa.border_pixel = 0; |
653 xswamask = CWBackPixel | CWBorderPixel; | 653 xswamask = CWBackPixel | CWBorderPixel; |
654 | 654 |
655 vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, flags, | 655 vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, flags, |
656 CopyFromParent, "xvmc", title); | 656 CopyFromParent, "xvmc", title); |
657 XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); | 657 XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); |
658 | 658 |
659 #ifdef CONFIG_XF86VM | 659 #ifdef CONFIG_XF86VM |
660 if ( vm ) | 660 if ( vm ) |
661 { | 661 { |
662 /* Grab the mouse pointer in our window */ | 662 /* Grab the mouse pointer in our window */ |
663 if(vo_grabpointer) | 663 if(vo_grabpointer) |
664 XGrabPointer(mDisplay, vo_window, True, 0, | 664 XGrabPointer(mDisplay, vo_window, True, 0, |
665 GrabModeAsync, GrabModeAsync, | 665 GrabModeAsync, GrabModeAsync, |
666 vo_window, None, CurrentTime ); | 666 vo_window, None, CurrentTime ); |
667 XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); | 667 XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); |
668 } | 668 } |
669 #endif | 669 #endif |
670 } | 670 } |
671 | 671 |
672 if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1; | 672 if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1; |
673 | 673 |
674 //end vo_xv | 674 //end vo_xv |
675 | 675 |
676 /* store image dimesions for displaying */ | 676 /* store image dimesions for displaying */ |
677 p_render_surface_visible = NULL; | 677 p_render_surface_visible = NULL; |
678 p_render_surface_to_show = NULL; | 678 p_render_surface_to_show = NULL; |
679 | 679 |
680 free_element = 0; | 680 free_element = 0; |
681 first_frame = 1; | 681 first_frame = 1; |
682 | 682 |
683 image_format=format; | 683 image_format=format; |
684 return 0; | 684 return 0; |
685 } | 685 } |
686 | 686 |
687 static int draw_frame(uint8_t *srcp[]){ | 687 static int draw_frame(uint8_t *srcp[]){ |
688 UNUSED(srcp); | 688 UNUSED(srcp); |
689 assert(0); | 689 assert(0); |
690 } | 690 } |
691 | 691 |
692 static void init_osd_yuv_pal(void) { | 692 static void init_osd_yuv_pal(void) { |
693 char * palette; | 693 char * palette; |
694 int rez; | 694 int rez; |
695 int i,j; | 695 int i,j; |
696 int snum,seb; | 696 int snum,seb; |
697 int Y,U,V; | 697 int Y,U,V; |
698 | 698 |
699 subpicture_clear_color = 0; | 699 subpicture_clear_color = 0; |
700 | 700 |
701 if(subpicture.num_palette_entries > 0){ | 701 if(subpicture.num_palette_entries > 0){ |
702 | 702 |
703 snum = subpicture.num_palette_entries; | 703 snum = subpicture.num_palette_entries; |
704 seb = subpicture.entry_bytes; | 704 seb = subpicture.entry_bytes; |
705 palette = malloc(snum*seb);//check fail | 705 palette = malloc(snum*seb);//check fail |
706 if(palette == NULL) return; | 706 if(palette == NULL) return; |
707 for(i=0; i<snum; i++){ | 707 for(i=0; i<snum; i++){ |
708 // 0-black max-white the other are gradients | 708 // 0-black max-white the other are gradients |
709 Y = i*(1 << subpicture_info.y_sample_bits)/snum;//snum=2;->(0),(1*(1<<1)/2) | 709 Y = i*(1 << subpicture_info.y_sample_bits)/snum;//snum=2;->(0),(1*(1<<1)/2) |
710 U = 1 << (subpicture_info.u_sample_bits - 1); | 710 U = 1 << (subpicture_info.u_sample_bits - 1); |
711 V = 1 << (subpicture_info.v_sample_bits - 1); | 711 V = 1 << (subpicture_info.v_sample_bits - 1); |
712 for(j=0; j<seb; j++) | 712 for(j=0; j<seb; j++) |
713 switch(subpicture.component_order[j]){ | 713 switch(subpicture.component_order[j]){ |
714 case 'U': palette[i*seb+j] = U; break; | 714 case 'U': palette[i*seb+j] = U; break; |
715 case 'V': palette[i*seb+j] = V; break; | 715 case 'V': palette[i*seb+j] = V; break; |
716 case 'Y': | 716 case 'Y': |
717 default: | 717 default: |
718 palette[i*seb+j] = Y; break; | 718 palette[i*seb+j] = Y; break; |
719 } | 719 } |
720 } | 720 } |
721 rez = XvMCSetSubpicturePalette(mDisplay, &subpicture, palette); | 721 rez = XvMCSetSubpicturePalette(mDisplay, &subpicture, palette); |
722 if(rez!=Success){ | 722 if(rez!=Success){ |
723 printf("vo_xvmc: Setting palette failed.\n"); | 723 printf("vo_xvmc: Setting palette failed.\n"); |
724 } | 724 } |
725 free(palette); | 725 free(palette); |
726 } | 726 } |
727 } | 727 } |
728 | 728 |
729 static void clear_osd_subpic(int x0, int y0, int w, int h){ | 729 static void clear_osd_subpic(int x0, int y0, int w, int h){ |
730 int rez; | 730 int rez; |
731 rez=XvMCClearSubpicture(mDisplay, &subpicture, | 731 rez=XvMCClearSubpicture(mDisplay, &subpicture, |
732 x0, y0, w,h, | 732 x0, y0, w,h, |
733 subpicture_clear_color); | 733 subpicture_clear_color); |
734 if(rez != Success) | 734 if(rez != Success) |
735 printf("vo_xvmc: XvMCClearSubpicture failed!\n"); | 735 printf("vo_xvmc: XvMCClearSubpicture failed!\n"); |
736 } | 736 } |
737 | 737 |
738 static void OSD_init(void) { | 738 static void OSD_init(void) { |
739 unsigned short osd_height, osd_width; | 739 unsigned short osd_height, osd_width; |
740 int rez; | 740 int rez; |
741 | 741 |
742 if(subpicture_alloc){ | 742 if(subpicture_alloc){ |
743 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 743 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
744 printf("vo_xvmc: destroying subpicture\n"); | 744 printf("vo_xvmc: destroying subpicture\n"); |
745 XvMCDestroySubpicture(mDisplay,&subpicture); | 745 XvMCDestroySubpicture(mDisplay,&subpicture); |
746 deallocate_xvimage(); | 746 deallocate_xvimage(); |
747 subpicture_alloc = 0; | 747 subpicture_alloc = 0; |
748 } | 748 } |
749 | 749 |
750 /* if(surface_info.flags & XVMC_SUBPICTURE_INDEPENDENT_SCALING){ | 750 /* if(surface_info.flags & XVMC_SUBPICTURE_INDEPENDENT_SCALING){ |
751 osd_width = vo_dwidth; | 751 osd_width = vo_dwidth; |
752 osd_height = vo_dheight; | 752 osd_height = vo_dheight; |
753 }else*/ | 753 }else*/ |
754 { | 754 { |
755 osd_width = image_width; | 755 osd_width = image_width; |
756 osd_height = image_height; | 756 osd_height = image_height; |
757 } | 757 } |
758 | 758 |
759 if(osd_width > surface_info.subpicture_max_width) | 759 if(osd_width > surface_info.subpicture_max_width) |
760 osd_width = surface_info.subpicture_max_width; | 760 osd_width = surface_info.subpicture_max_width; |
761 if(osd_height > surface_info.subpicture_max_height) | 761 if(osd_height > surface_info.subpicture_max_height) |
762 osd_height = surface_info.subpicture_max_height; | 762 osd_height = surface_info.subpicture_max_height; |
763 if(osd_width == 0 || osd_height == 0) | 763 if(osd_width == 0 || osd_height == 0) |
764 return;//if called before window size is known | 764 return;//if called before window size is known |
765 | 765 |
766 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 766 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
767 printf("vo_xvmc: creating subpicture (%d,%d) format %X\n", | 767 printf("vo_xvmc: creating subpicture (%d,%d) format %X\n", |
768 osd_width,osd_height,subpicture_info.id); | 768 osd_width,osd_height,subpicture_info.id); |
769 | 769 |
770 rez = XvMCCreateSubpicture(mDisplay,&ctx,&subpicture, | 770 rez = XvMCCreateSubpicture(mDisplay,&ctx,&subpicture, |
771 osd_width,osd_height,subpicture_info.id); | 771 osd_width,osd_height,subpicture_info.id); |
772 if(rez != Success){ | 772 if(rez != Success){ |
773 subpicture_mode = NO_SUBPICTURE; | 773 subpicture_mode = NO_SUBPICTURE; |
774 printf("vo_xvmc: Create Subpicture failed, OSD disabled\n"); | 774 printf("vo_xvmc: Create Subpicture failed, OSD disabled\n"); |
775 return; | 775 return; |
776 } | 776 } |
777 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){ | 777 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ){ |
778 int i; | 778 int i; |
779 printf("vo_xvmc: Created Subpicture:\n"); | 779 printf("vo_xvmc: Created Subpicture:\n"); |
780 printf(" xvimage_id=0x%X\n",subpicture.xvimage_id); | 780 printf(" xvimage_id=0x%X\n",subpicture.xvimage_id); |
781 printf(" width=%d\n",subpicture.width); | 781 printf(" width=%d\n",subpicture.width); |
782 printf(" height=%d\n",subpicture.height); | 782 printf(" height=%d\n",subpicture.height); |
783 printf(" num_palette_entries=0x%X\n",subpicture.num_palette_entries); | 783 printf(" num_palette_entries=0x%X\n",subpicture.num_palette_entries); |
784 printf(" entry_bytes=0x%X\n",subpicture.entry_bytes); | 784 printf(" entry_bytes=0x%X\n",subpicture.entry_bytes); |
785 | 785 |
786 printf(" component_order=\""); | 786 printf(" component_order=\""); |
787 for(i=0; i<4; i++) | 787 for(i=0; i<4; i++) |
788 if(subpicture.component_order[i] >= 32) | 788 if(subpicture.component_order[i] >= 32) |
789 printf("%c", subpicture.component_order[i]); | 789 printf("%c", subpicture.component_order[i]); |
790 printf("\"\n"); | 790 printf("\"\n"); |
791 } | 791 } |
792 | 792 |
793 //call init for the surface type | 793 //call init for the surface type |
794 init_osd_fnc();//init palete,clear color etc ... | 794 init_osd_fnc();//init palete,clear color etc ... |
795 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 795 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
796 printf("vo_xvmc: clearing subpicture\n"); | 796 printf("vo_xvmc: clearing subpicture\n"); |
797 clear_osd_fnc(0, 0, subpicture.width, subpicture.height); | 797 clear_osd_fnc(0, 0, subpicture.width, subpicture.height); |
798 | 798 |
799 allocate_xvimage(subpicture.width, subpicture.height, subpicture_info.id); | 799 allocate_xvimage(subpicture.width, subpicture.height, subpicture_info.id); |
800 subpicture_alloc = 1; | 800 subpicture_alloc = 1; |
801 } | 801 } |
802 | 802 |
803 static void draw_osd_IA44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ | 803 static void draw_osd_IA44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ |
804 int ox,oy; | 804 int ox,oy; |
805 int rez; | 805 int rez; |
806 | 806 |
807 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 807 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
808 printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h); | 808 printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h); |
809 | 809 |
810 for(ox=0; ox<w; ox++){ | 810 for(ox=0; ox<w; ox++){ |
811 for(oy=0; oy<h; oy++){ | 811 for(oy=0; oy<h; oy++){ |
812 xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]>>4) | ((0-srca[oy*stride+ox])&0xf0); | 812 xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]>>4) | ((0-srca[oy*stride+ox])&0xf0); |
813 } | 813 } |
814 } | 814 } |
815 rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0, | 815 rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0, |
816 w,h,x0,y0); | 816 w,h,x0,y0); |
817 if(rez != Success){ | 817 if(rez != Success){ |
818 printf("vo_xvmc: composite subpicture failed\n"); | 818 printf("vo_xvmc: composite subpicture failed\n"); |
819 assert(0); | 819 assert(0); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 static void draw_osd_AI44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ | 823 static void draw_osd_AI44(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ |
824 int ox,oy; | 824 int ox,oy; |
825 int rez; | 825 int rez; |
826 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 826 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
827 printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h); | 827 printf("vo_xvmc:composite AI44 subpicture (%d,%d - %d,%d)\n",x0,y0,w,h); |
828 | 828 |
829 for(ox=0; ox<w; ox++){ | 829 for(ox=0; ox<w; ox++){ |
830 for(oy=0; oy<h; oy++){ | 830 for(oy=0; oy<h; oy++){ |
831 xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]&0xf0) | (((0-srca[oy*stride+ox])>>4)&0xf); | 831 xvimage->data[oy*xvimage->width+ox] = (src[oy*stride+ox]&0xf0) | (((0-srca[oy*stride+ox])>>4)&0xf); |
832 } | 832 } |
833 } | 833 } |
834 rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0, | 834 rez = XvMCCompositeSubpicture(mDisplay, &subpicture, xvimage, 0, 0, |
835 w,h,x0,y0); | 835 w,h,x0,y0); |
836 if(rez != Success){ | 836 if(rez != Success){ |
837 printf("vo_xvmc: composite subpicture failed\n"); | 837 printf("vo_xvmc: composite subpicture failed\n"); |
838 assert(0); | 838 assert(0); |
839 } | 839 } |
840 } | 840 } |
841 | 841 |
842 static void draw_osd(void){ | 842 static void draw_osd(void){ |
843 struct xvmc_pix_fmt *osd_rndr; | 843 struct xvmc_pix_fmt *osd_rndr; |
844 int osd_has_changed; | 844 int osd_has_changed; |
845 int have_osd_to_draw; | 845 int have_osd_to_draw; |
846 int rez; | 846 int rez; |
847 | 847 |
848 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 848 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
849 printf("vo_xvmc: draw_osd ,OSD_mode=%d, surface_to_show=%p\n", | 849 printf("vo_xvmc: draw_osd ,OSD_mode=%d, surface_to_show=%p\n", |
850 subpicture_mode,p_render_surface_to_show); | 850 subpicture_mode,p_render_surface_to_show); |
851 | 851 |
852 if(subpicture_mode == BLEND_SUBPICTURE || | 852 if(subpicture_mode == BLEND_SUBPICTURE || |
853 subpicture_mode == BACKEND_SUBPICTURE ){ | 853 subpicture_mode == BACKEND_SUBPICTURE ){ |
854 | 854 |
855 if(!subpicture_alloc) //allocate subpicture when dimensions are known | 855 if(!subpicture_alloc) //allocate subpicture when dimensions are known |
856 OSD_init(); | 856 OSD_init(); |
857 if(!subpicture_alloc) | 857 if(!subpicture_alloc) |
858 return;//dimensions still unknown. | 858 return;//dimensions still unknown. |
859 | 859 |
860 osd_has_changed = vo_update_osd(subpicture.width, subpicture.height); | 860 osd_has_changed = vo_update_osd(subpicture.width, subpicture.height); |
861 have_osd_to_draw = vo_osd_check_range_update(0, 0, subpicture.width, | 861 have_osd_to_draw = vo_osd_check_range_update(0, 0, subpicture.width, |
862 subpicture.height); | 862 subpicture.height); |
863 | 863 |
864 if(!have_osd_to_draw) | 864 if(!have_osd_to_draw) |
865 return;//nothing to draw,no subpic, no blend | 865 return;//nothing to draw,no subpic, no blend |
866 | 866 |
867 if(osd_has_changed){ | 867 if(osd_has_changed){ |
868 //vo_remove_text(subpicture.width, subpicture.height,clear_osd_fnc) | 868 //vo_remove_text(subpicture.width, subpicture.height,clear_osd_fnc) |
869 clear_osd_fnc(0,0,subpicture.width,subpicture.height); | 869 clear_osd_fnc(0,0,subpicture.width,subpicture.height); |
870 vo_draw_text(subpicture.width, subpicture.height, draw_osd_fnc); | 870 vo_draw_text(subpicture.width, subpicture.height, draw_osd_fnc); |
871 } | 871 } |
872 XvMCSyncSubpicture(mDisplay,&subpicture);//todo usleeep wait! | 872 XvMCSyncSubpicture(mDisplay,&subpicture);//todo usleeep wait! |
873 | 873 |
874 if(subpicture_mode == BLEND_SUBPICTURE){ | 874 if(subpicture_mode == BLEND_SUBPICTURE){ |
875 osd_rndr = find_free_surface(); | 875 osd_rndr = find_free_surface(); |
876 if(osd_rndr == NULL) | 876 if(osd_rndr == NULL) |
877 return;// no free surface to draw OSD in | 877 return;// no free surface to draw OSD in |
878 | 878 |
879 rez = XvMCBlendSubpicture2(mDisplay, | 879 rez = XvMCBlendSubpicture2(mDisplay, |
880 p_render_surface_to_show->p_surface, osd_rndr->p_surface, | 880 p_render_surface_to_show->p_surface, osd_rndr->p_surface, |
881 &subpicture, | 881 &subpicture, |
882 0, 0, subpicture.width, subpicture.height, | 882 0, 0, subpicture.width, subpicture.height, |
883 0, 0, image_width, image_height); | 883 0, 0, image_width, image_height); |
884 if(rez!=Success){ | 884 if(rez!=Success){ |
885 printf("vo_xvmc: BlendSubpicture failed rez=%d\n",rez); | 885 printf("vo_xvmc: BlendSubpicture failed rez=%d\n",rez); |
886 assert(0); | 886 assert(0); |
887 return; | 887 return; |
888 } | 888 } |
889 // XvMCFlushSurface(mDisplay,osd_rndr->p_surface);//fixme- should I? | 889 // XvMCFlushSurface(mDisplay,osd_rndr->p_surface);//fixme- should I? |
890 | 890 |
891 //When replaceing the surface with osd one, save the flags too! | 891 //When replaceing the surface with osd one, save the flags too! |
892 osd_rndr->picture_structure = p_render_surface_to_show->picture_structure; | 892 osd_rndr->picture_structure = p_render_surface_to_show->picture_structure; |
893 //add more if needed osd_rndr-> = p_render_surface_to_show->; | 893 //add more if needed osd_rndr-> = p_render_surface_to_show->; |
894 | 894 |
895 p_render_surface_to_show->state &= ~AV_XVMC_STATE_DISPLAY_PENDING; | 895 p_render_surface_to_show->state &= ~AV_XVMC_STATE_DISPLAY_PENDING; |
896 p_render_surface_to_show->state |= AV_XVMC_STATE_OSD_SOURCE; | 896 p_render_surface_to_show->state |= AV_XVMC_STATE_OSD_SOURCE; |
897 p_render_surface_to_show->p_osd_target_surface_render = osd_rndr; | 897 p_render_surface_to_show->p_osd_target_surface_render = osd_rndr; |
898 | 898 |
899 p_render_surface_to_show = osd_rndr; | 899 p_render_surface_to_show = osd_rndr; |
900 p_render_surface_to_show->state = AV_XVMC_STATE_DISPLAY_PENDING; | 900 p_render_surface_to_show->state = AV_XVMC_STATE_DISPLAY_PENDING; |
901 | 901 |
902 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 902 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
903 printf("vo_xvmc:draw_osd: surface_to_show changed to %p\n",osd_rndr); | 903 printf("vo_xvmc:draw_osd: surface_to_show changed to %p\n",osd_rndr); |
904 }//endof if(BLEND) | 904 }//endof if(BLEND) |
905 if(subpicture_mode == BACKEND_SUBPICTURE){ | 905 if(subpicture_mode == BACKEND_SUBPICTURE){ |
906 rez = XvMCBlendSubpicture(mDisplay, | 906 rez = XvMCBlendSubpicture(mDisplay, |
907 p_render_surface_to_show->p_surface, | 907 p_render_surface_to_show->p_surface, |
908 &subpicture, | 908 &subpicture, |
909 0, 0, subpicture.width, subpicture.height, | 909 0, 0, subpicture.width, subpicture.height, |
910 0, 0, image_width, image_height); | 910 0, 0, image_width, image_height); |
911 | 911 |
912 } | 912 } |
913 | 913 |
914 }//if(BLEND||BACKEND) | 914 }//if(BLEND||BACKEND) |
915 } | 915 } |
916 | 916 |
917 static void xvmc_sync_surface(XvMCSurface * srf){ | 917 static void xvmc_sync_surface(XvMCSurface * srf){ |
918 int status,rez; | 918 int status,rez; |
919 rez = XvMCGetSurfaceStatus(mDisplay,srf,&status); | 919 rez = XvMCGetSurfaceStatus(mDisplay,srf,&status); |
920 assert(rez==Success); | 920 assert(rez==Success); |
921 if((status & XVMC_RENDERING) == 0) | 921 if((status & XVMC_RENDERING) == 0) |
922 return;//surface is already complete | 922 return;//surface is already complete |
923 if(use_sleep){ | 923 if(use_sleep){ |
924 rez = XvMCFlushSurface(mDisplay, srf); | 924 rez = XvMCFlushSurface(mDisplay, srf); |
925 assert(rez==Success); | 925 assert(rez==Success); |
926 | 926 |
927 do{ | 927 do{ |
928 usec_sleep(1000);//1ms (may be 20ms on linux) | 928 usec_sleep(1000);//1ms (may be 20ms on linux) |
929 XvMCGetSurfaceStatus(mDisplay,srf,&status); | 929 XvMCGetSurfaceStatus(mDisplay,srf,&status); |
930 } while (status & XVMC_RENDERING); | 930 } while (status & XVMC_RENDERING); |
931 return;//done | 931 return;//done |
932 } | 932 } |
933 | 933 |
934 XvMCSyncSurface(mDisplay, srf); | 934 XvMCSyncSurface(mDisplay, srf); |
935 } | 935 } |
936 | 936 |
937 static void put_xvmc_image(struct xvmc_pix_fmt *p_render_surface, | 937 static void put_xvmc_image(struct xvmc_pix_fmt *p_render_surface, |
938 int draw_ck){ | 938 int draw_ck){ |
939 int rez; | 939 int rez; |
940 struct vo_rect src_rect, dst_rect; | 940 struct vo_rect src_rect, dst_rect; |
941 int i; | 941 int i; |
942 | 942 |
943 if(p_render_surface == NULL) | 943 if(p_render_surface == NULL) |
944 return; | 944 return; |
945 | 945 |
946 calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL, NULL); | 946 calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL, NULL); |
947 | 947 |
948 if(draw_ck) | 948 if(draw_ck) |
949 vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); | 949 vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); |
950 | 950 |
951 if(benchmark) | 951 if(benchmark) |
952 return; | 952 return; |
953 | 953 |
954 for (i = 1; i <= bob_deinterlace + 1; i++) { | 954 for (i = 1; i <= bob_deinterlace + 1; i++) { |
955 int field = top_field_first ? i : i ^ 3; | 955 int field = top_field_first ? i : i ^ 3; |
956 rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, | 956 rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, |
957 vo_window, | 957 vo_window, |
958 src_rect.left, src_rect.top, src_rect.width, src_rect.height, | 958 src_rect.left, src_rect.top, src_rect.width, src_rect.height, |
959 dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height, | 959 dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height, |
960 bob_deinterlace ? field : 3); | 960 bob_deinterlace ? field : 3); |
961 if(rez != Success){ | 961 if(rez != Success){ |
962 printf("vo_xvmc: PutSurface failer, critical error %d!\n",rez); | 962 printf("vo_xvmc: PutSurface failer, critical error %d!\n",rez); |
963 assert(0); | 963 assert(0); |
964 } | 964 } |
965 } | 965 } |
966 XFlush(mDisplay); | 966 XFlush(mDisplay); |
967 } | 967 } |
968 | 968 |
969 static void flip_page(void){ | 969 static void flip_page(void){ |
970 int i,cfs; | 970 int i,cfs; |
971 | 971 |
972 | 972 |
973 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 973 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
974 printf("vo_xvmc: flip_page show(rndr=%p)\n\n",p_render_surface_to_show); | 974 printf("vo_xvmc: flip_page show(rndr=%p)\n\n",p_render_surface_to_show); |
975 | 975 |
976 if(p_render_surface_to_show == NULL) return; | 976 if(p_render_surface_to_show == NULL) return; |
977 assert( p_render_surface_to_show->xvmc_id == AV_XVMC_ID ); | 977 assert( p_render_surface_to_show->xvmc_id == AV_XVMC_ID ); |
978 //fixme assert( p_render_surface_to_show != p_render_surface_visible); | 978 //fixme assert( p_render_surface_to_show != p_render_surface_visible); |
979 | 979 |
980 if(use_queue){ | 980 if(use_queue){ |
981 // fill the queue until only n free surfaces remain | 981 // fill the queue until only n free surfaces remain |
982 // after that start displaying | 982 // after that start displaying |
983 cfs = count_free_surfaces(); | 983 cfs = count_free_surfaces(); |
984 show_queue[free_element++] = p_render_surface_to_show; | 984 show_queue[free_element++] = p_render_surface_to_show; |
985 if(cfs > 3){//well have 3 free surfaces after add queue | 985 if(cfs > 3){//well have 3 free surfaces after add queue |
986 if(free_element > 1)//a little voodoo magic | 986 if(free_element > 1)//a little voodoo magic |
987 xvmc_sync_surface(show_queue[0]->p_surface); | 987 xvmc_sync_surface(show_queue[0]->p_surface); |
988 return; | 988 return; |
989 } | 989 } |
990 p_render_surface_to_show=show_queue[0]; | 990 p_render_surface_to_show=show_queue[0]; |
991 if( mp_msg_test(MSGT_VO,MSGL_DBG5) ) | 991 if( mp_msg_test(MSGT_VO,MSGL_DBG5) ) |
992 printf("vo_xvmc: flip_queue free_element=%d\n",free_element); | 992 printf("vo_xvmc: flip_queue free_element=%d\n",free_element); |
993 free_element--; | 993 free_element--; |
994 for(i=0; i<free_element; i++){ | 994 for(i=0; i<free_element; i++){ |
995 show_queue[i] = show_queue[i+1]; | 995 show_queue[i] = show_queue[i+1]; |
996 } | 996 } |
997 show_queue[free_element] = NULL; | 997 show_queue[free_element] = NULL; |
998 } | 998 } |
999 | 999 |
1000 // make sure the rendering is done | 1000 // make sure the rendering is done |
1001 xvmc_sync_surface(p_render_surface_to_show->p_surface); | 1001 xvmc_sync_surface(p_render_surface_to_show->p_surface); |
1002 | 1002 |
1003 //the visible surface won't be displayed anymore, mark it as free | 1003 //the visible surface won't be displayed anymore, mark it as free |
1004 if(p_render_surface_visible != NULL) | 1004 if(p_render_surface_visible != NULL) |
1005 p_render_surface_visible->state &= ~AV_XVMC_STATE_DISPLAY_PENDING; | 1005 p_render_surface_visible->state &= ~AV_XVMC_STATE_DISPLAY_PENDING; |
1006 | 1006 |
1007 //!!fixme assert(p_render_surface_to_show->state & AV_XVMC_STATE_DISPLAY_PENDING); | 1007 //!!fixme assert(p_render_surface_to_show->state & AV_XVMC_STATE_DISPLAY_PENDING); |
1008 | 1008 |
1009 //show it, displaying is always vsynced, so skip it for benchmark | 1009 //show it, displaying is always vsynced, so skip it for benchmark |
1010 put_xvmc_image(p_render_surface_to_show,first_frame); | 1010 put_xvmc_image(p_render_surface_to_show,first_frame); |
1011 first_frame=0;//make sure we won't draw it anymore | 1011 first_frame=0;//make sure we won't draw it anymore |
1012 | 1012 |
1013 p_render_surface_visible = p_render_surface_to_show; | 1013 p_render_surface_visible = p_render_surface_to_show; |
1014 p_render_surface_to_show = NULL; | 1014 p_render_surface_to_show = NULL; |
1015 } | 1015 } |
1016 | 1016 |
1017 static void check_events(void){ | 1017 static void check_events(void){ |
1018 int e=vo_x11_check_events(mDisplay); | 1018 int e=vo_x11_check_events(mDisplay); |
1019 if(e&VO_EVENT_RESIZE) | 1019 if(e&VO_EVENT_RESIZE) |
1020 { | 1020 { |
1021 e |= VO_EVENT_EXPOSE; | 1021 e |= VO_EVENT_EXPOSE; |
1022 } | 1022 } |
1023 if ( e & VO_EVENT_EXPOSE ) | 1023 if ( e & VO_EVENT_EXPOSE ) |
1024 { | 1024 { |
1025 put_xvmc_image(p_render_surface_visible,1); | 1025 put_xvmc_image(p_render_surface_visible,1); |
1026 } | 1026 } |
1027 } | 1027 } |
1028 | 1028 |
1029 static void xvmc_free(void){ | 1029 static void xvmc_free(void){ |
1030 int i; | 1030 int i; |
1031 if( subpicture_alloc ){ | 1031 if( subpicture_alloc ){ |
1032 | 1032 |
1033 XvMCDestroySubpicture(mDisplay,&subpicture); | 1033 XvMCDestroySubpicture(mDisplay,&subpicture); |
1034 deallocate_xvimage(); | 1034 deallocate_xvimage(); |
1035 | 1035 |
1036 subpicture_alloc = 0; | 1036 subpicture_alloc = 0; |
1037 | 1037 |
1038 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 1038 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
1039 printf("vo_xvmc: subpicture destroyed\n"); | 1039 printf("vo_xvmc: subpicture destroyed\n"); |
1040 } | 1040 } |
1041 | 1041 |
1042 if( number_of_surfaces ){ | 1042 if( number_of_surfaces ){ |
1043 | 1043 |
1044 XvMCDestroyMacroBlocks(mDisplay,&mv_blocks); | 1044 XvMCDestroyMacroBlocks(mDisplay,&mv_blocks); |
1045 XvMCDestroyBlocks(mDisplay,&data_blocks); | 1045 XvMCDestroyBlocks(mDisplay,&data_blocks); |
1046 | 1046 |
1047 for(i=0; i<number_of_surfaces; i++) | 1047 for(i=0; i<number_of_surfaces; i++) |
1048 { | 1048 { |
1049 XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope | 1049 XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope |
1050 XvMCDestroySurface(mDisplay,&surface_array[i]); | 1050 XvMCDestroySurface(mDisplay,&surface_array[i]); |
1051 | 1051 |
1052 if( (surface_render[i].state != 0) && | 1052 if( (surface_render[i].state != 0) && |
1053 (p_render_surface_visible != &surface_render[i]) ) | 1053 (p_render_surface_visible != &surface_render[i]) ) |
1054 printf("vo_xvmc::uninit surface_render[%d].status=%d\n",i, | 1054 printf("vo_xvmc::uninit surface_render[%d].status=%d\n",i, |
1055 surface_render[i].state); | 1055 surface_render[i].state); |
1056 } | 1056 } |
1057 | 1057 |
1058 memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //for debugging | 1058 memset(surface_render, 0, MAX_SURFACES * sizeof(struct xvmc_pix_fmt)); //for debugging |
1059 free(surface_render);surface_render=NULL; | 1059 free(surface_render);surface_render=NULL; |
1060 | 1060 |
1061 XvMCDestroyContext(mDisplay,&ctx); | 1061 XvMCDestroyContext(mDisplay,&ctx); |
1062 number_of_surfaces = 0; | 1062 number_of_surfaces = 0; |
1063 | 1063 |
1064 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { | 1064 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { |
1065 printf("vo_xvmc: Context sucessfuly freed\n"); } | 1065 printf("vo_xvmc: Context sucessfuly freed\n"); } |
1066 } | 1066 } |
1067 | 1067 |
1068 | 1068 |
1069 if( xv_port !=0 ){ | 1069 if( xv_port !=0 ){ |
1070 XvUngrabPort(mDisplay,xv_port,CurrentTime); | 1070 XvUngrabPort(mDisplay,xv_port,CurrentTime); |
1071 xv_port = 0; | 1071 xv_port = 0; |
1072 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { | 1072 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { |
1073 printf("vo_xvmc: xv_port sucessfuly ungrabed\n"); } | 1073 printf("vo_xvmc: xv_port sucessfuly ungrabed\n"); } |
1074 } | 1074 } |
1075 } | 1075 } |
1076 | 1076 |
1077 static void uninit(void){ | 1077 static void uninit(void){ |
1078 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { | 1078 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) { |
1079 printf("vo_xvmc: uninit called\n"); } | 1079 printf("vo_xvmc: uninit called\n"); } |
1080 xvmc_free(); | 1080 xvmc_free(); |
1081 //from vo_xv | 1081 //from vo_xv |
1082 #ifdef CONFIG_XF86VM | 1082 #ifdef CONFIG_XF86VM |
1083 vo_vm_close(); | 1083 vo_vm_close(); |
1084 #endif | 1084 #endif |
1085 vo_x11_uninit(); | 1085 vo_x11_uninit(); |
1086 } | 1086 } |
1087 | 1087 |
1088 static int query_format(uint32_t format){ | 1088 static int query_format(uint32_t format){ |
1089 uint32_t flags; | 1089 uint32_t flags; |
1090 XvMCSurfaceInfo qsurface_info; | 1090 XvMCSurfaceInfo qsurface_info; |
1091 int mode_id; | 1091 int mode_id; |
1092 | 1092 |
1093 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 1093 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
1094 printf("vo_xvmc: query_format=%X\n",format); | 1094 printf("vo_xvmc: query_format=%X\n",format); |
1095 | 1095 |
1096 if(!IMGFMT_IS_XVMC(format)) return 0;// no caps supported | 1096 if(!IMGFMT_IS_XVMC(format)) return 0;// no caps supported |
1097 mode_id = xvmc_find_surface_by_format(format, 16, 16, &qsurface_info, 1);//true=1 - quering | 1097 mode_id = xvmc_find_surface_by_format(format, 16, 16, &qsurface_info, 1);//true=1 - quering |
1098 | 1098 |
1099 if( mode_id == 0 ) return 0; | 1099 if( mode_id == 0 ) return 0; |
1100 | 1100 |
1101 flags = VFCAP_CSP_SUPPORTED | | 1101 flags = VFCAP_CSP_SUPPORTED | |
1102 VFCAP_CSP_SUPPORTED_BY_HW | | 1102 VFCAP_CSP_SUPPORTED_BY_HW | |
1103 VFCAP_ACCEPT_STRIDE; | 1103 VFCAP_ACCEPT_STRIDE; |
1104 | 1104 |
1105 if( (qsurface_info.subpicture_max_width != 0) && | 1105 if( (qsurface_info.subpicture_max_width != 0) && |
1106 (qsurface_info.subpicture_max_height != 0) ) | 1106 (qsurface_info.subpicture_max_height != 0) ) |
1107 flags|=VFCAP_OSD; | 1107 flags|=VFCAP_OSD; |
1108 return flags; | 1108 return flags; |
1109 } | 1109 } |
1110 | 1110 |
1111 | 1111 |
1112 static int draw_slice(uint8_t *image[], int stride[], | 1112 static int draw_slice(uint8_t *image[], int stride[], |
1113 int w, int h, int x, int y){ | 1113 int w, int h, int x, int y){ |
1114 struct xvmc_pix_fmt *rndr; | 1114 struct xvmc_pix_fmt *rndr; |
1115 int rez; | 1115 int rez; |
1116 | 1116 |
1117 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 1117 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
1118 printf("vo_xvmc: draw_slice y=%d\n",y); | 1118 printf("vo_xvmc: draw_slice y=%d\n",y); |
1119 | 1119 |
1120 rndr = (struct xvmc_pix_fmt*)image[2]; //this is copy of priv-ate | 1120 rndr = (struct xvmc_pix_fmt*)image[2]; //this is copy of priv-ate |
1121 assert( rndr != NULL ); | 1121 assert( rndr != NULL ); |
1122 assert( rndr->xvmc_id == AV_XVMC_ID ); | 1122 assert( rndr->xvmc_id == AV_XVMC_ID ); |
1123 | 1123 |
1124 rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, | 1124 rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, |
1125 rndr->p_surface, | 1125 rndr->p_surface, |
1126 rndr->p_past_surface, | 1126 rndr->p_past_surface, |
1127 rndr->p_future_surface, | 1127 rndr->p_future_surface, |
1128 rndr->flags, | 1128 rndr->flags, |
1129 rndr->filled_mv_blocks_num,rndr->start_mv_blocks_num, | 1129 rndr->filled_mv_blocks_num,rndr->start_mv_blocks_num, |
1130 &mv_blocks,&data_blocks); | 1130 &mv_blocks,&data_blocks); |
1131 #if 1 | 1131 #if 1 |
1132 if(rez != Success) | 1132 if(rez != Success) |
1133 { | 1133 { |
1134 int i; | 1134 int i; |
1135 printf("vo_xvmc::slice: RenderSirface returned %d\n",rez); | 1135 printf("vo_xvmc::slice: RenderSirface returned %d\n",rez); |
1136 | 1136 |
1137 printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", | 1137 printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", |
1138 rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, | 1138 rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, |
1139 rndr->filled_mv_blocks_num); | 1139 rndr->filled_mv_blocks_num); |
1140 printf("vo_xvmc::slice: this_surf=%p, past_surf=%p, future_surf=%p\n", | 1140 printf("vo_xvmc::slice: this_surf=%p, past_surf=%p, future_surf=%p\n", |
1141 rndr->p_surface,rndr->p_past_surface,rndr->p_future_surface); | 1141 rndr->p_surface,rndr->p_past_surface,rndr->p_future_surface); |
1142 | 1142 |
1143 for(i=0; i<rndr->filled_mv_blocks_num; i++){ | 1143 for(i=0; i<rndr->filled_mv_blocks_num; i++){ |
1144 XvMCMacroBlock* testblock; | 1144 XvMCMacroBlock* testblock; |
1145 testblock = &mv_blocks.macro_blocks[i]; | 1145 testblock = &mv_blocks.macro_blocks[i]; |
1146 | 1146 |
1147 printf("vo_xvmc::slice: mv_block - x=%d,y=%d,mb_type=0x%x,mv_type=0x%x,mv_field_select=%d\n", | 1147 printf("vo_xvmc::slice: mv_block - x=%d,y=%d,mb_type=0x%x,mv_type=0x%x,mv_field_select=%d\n", |
1148 testblock->x,testblock->y,testblock->macroblock_type, | 1148 testblock->x,testblock->y,testblock->macroblock_type, |
1149 testblock->motion_type,testblock->motion_vertical_field_select); | 1149 testblock->motion_type,testblock->motion_vertical_field_select); |
1150 printf("vo_xvmc::slice: dct_type=%d,data_index=0x%x,cbp=%d,pad0=%d\n", | 1150 printf("vo_xvmc::slice: dct_type=%d,data_index=0x%x,cbp=%d,pad0=%d\n", |
1151 testblock->dct_type,testblock->index,testblock->coded_block_pattern, | 1151 testblock->dct_type,testblock->index,testblock->coded_block_pattern, |
1152 testblock->pad0); | 1152 testblock->pad0); |
1153 printf("vo_xvmc::slice: PMV[0][0][0/1]=(%d,%d)\n", | 1153 printf("vo_xvmc::slice: PMV[0][0][0/1]=(%d,%d)\n", |
1154 testblock->PMV[0][0][0],testblock->PMV[0][0][1]); | 1154 testblock->PMV[0][0][0],testblock->PMV[0][0][1]); |
1155 } | 1155 } |
1156 } | 1156 } |
1157 #endif | 1157 #endif |
1158 assert(rez==Success); | 1158 assert(rez==Success); |
1159 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) printf("vo_xvmc: flush surface\n"); | 1159 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) printf("vo_xvmc: flush surface\n"); |
1160 rez = XvMCFlushSurface(mDisplay, rndr->p_surface); | 1160 rez = XvMCFlushSurface(mDisplay, rndr->p_surface); |
1161 assert(rez==Success); | 1161 assert(rez==Success); |
1162 | 1162 |
1163 // rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num; | 1163 // rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num; |
1164 rndr->start_mv_blocks_num = 0; | 1164 rndr->start_mv_blocks_num = 0; |
1165 rndr->filled_mv_blocks_num = 0; | 1165 rndr->filled_mv_blocks_num = 0; |
1166 | 1166 |
1167 rndr->next_free_data_block_num = 0; | 1167 rndr->next_free_data_block_num = 0; |
1168 | 1168 |
1169 return VO_TRUE; | 1169 return VO_TRUE; |
1170 } | 1170 } |
1171 | 1171 |
1172 //XvMCHide hides the surface on next retrace, so | 1172 //XvMCHide hides the surface on next retrace, so |
1173 //check if the surface is not still displaying | 1173 //check if the surface is not still displaying |
1174 static void check_osd_source(struct xvmc_pix_fmt *src_rndr) { | 1174 static void check_osd_source(struct xvmc_pix_fmt *src_rndr) { |
1175 struct xvmc_pix_fmt *osd_rndr; | 1175 struct xvmc_pix_fmt *osd_rndr; |
1176 int stat; | 1176 int stat; |
1177 //If this is source surface, check does the OSD rendering is compleate | 1177 //If this is source surface, check does the OSD rendering is compleate |
1178 if(src_rndr->state & AV_XVMC_STATE_OSD_SOURCE){ | 1178 if(src_rndr->state & AV_XVMC_STATE_OSD_SOURCE){ |
1179 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 1179 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
1180 printf("vo_xvmc: OSD surface=%p quering\n",src_rndr); | 1180 printf("vo_xvmc: OSD surface=%p quering\n",src_rndr); |
1181 osd_rndr = src_rndr->p_osd_target_surface_render; | 1181 osd_rndr = src_rndr->p_osd_target_surface_render; |
1182 XvMCGetSurfaceStatus(mDisplay, osd_rndr->p_surface, &stat); | 1182 XvMCGetSurfaceStatus(mDisplay, osd_rndr->p_surface, &stat); |
1183 if(!(stat & XVMC_RENDERING)) | 1183 if(!(stat & XVMC_RENDERING)) |
1184 src_rndr->state &= ~AV_XVMC_STATE_OSD_SOURCE; | 1184 src_rndr->state &= ~AV_XVMC_STATE_OSD_SOURCE; |
1185 } | 1185 } |
1186 } | 1186 } |
1187 static int count_free_surfaces(void) { | 1187 static int count_free_surfaces(void) { |
1188 int i,num; | 1188 int i,num; |
1189 num=0; | 1189 num=0; |
1190 for(i=0; i<number_of_surfaces; i++){ | 1190 for(i=0; i<number_of_surfaces; i++){ |
1191 check_osd_source(&surface_render[i]); | 1191 check_osd_source(&surface_render[i]); |
1192 if(surface_render[i].state == 0) | 1192 if(surface_render[i].state == 0) |
1193 num++; | 1193 num++; |
1194 } | 1194 } |
1195 return num; | 1195 return num; |
1196 } | 1196 } |
1197 | 1197 |
1198 static struct xvmc_pix_fmt *find_free_surface(void) { | 1198 static struct xvmc_pix_fmt *find_free_surface(void) { |
1199 int i,t; | 1199 int i,t; |
1200 int stat; | 1200 int stat; |
1201 struct xvmc_pix_fmt *visible_rndr; | 1201 struct xvmc_pix_fmt *visible_rndr; |
1202 | 1202 |
1203 visible_rndr = NULL; | 1203 visible_rndr = NULL; |
1204 for(i=0; i<number_of_surfaces; i++){ | 1204 for(i=0; i<number_of_surfaces; i++){ |
1205 | 1205 |
1206 check_osd_source(&surface_render[i]); | 1206 check_osd_source(&surface_render[i]); |
1207 if( surface_render[i].state == 0){ | 1207 if( surface_render[i].state == 0){ |
1208 XvMCGetSurfaceStatus(mDisplay, surface_render[i].p_surface,&stat); | 1208 XvMCGetSurfaceStatus(mDisplay, surface_render[i].p_surface,&stat); |
1209 if( (stat & XVMC_DISPLAYING) == 0 ) | 1209 if( (stat & XVMC_DISPLAYING) == 0 ) |
1210 return &surface_render[i]; | 1210 return &surface_render[i]; |
1211 visible_rndr = &surface_render[i];// remember it, use as last resort | 1211 visible_rndr = &surface_render[i];// remember it, use as last resort |
1212 } | 1212 } |
1213 } | 1213 } |
1214 | 1214 |
1215 //all surfaces are busy, but there is one that will be free | 1215 //all surfaces are busy, but there is one that will be free |
1216 //on next monitor retrace, we just have to wait | 1216 //on next monitor retrace, we just have to wait |
1217 if(visible_rndr != NULL){ | 1217 if(visible_rndr != NULL){ |
1218 printf("vo_xvmc: waiting retrace\n"); | 1218 printf("vo_xvmc: waiting retrace\n"); |
1219 for(t=0;t<1000;t++){ | 1219 for(t=0;t<1000;t++){ |
1220 usec_sleep(1000);//1ms | 1220 usec_sleep(1000);//1ms |
1221 XvMCGetSurfaceStatus(mDisplay, visible_rndr->p_surface,&stat); | 1221 XvMCGetSurfaceStatus(mDisplay, visible_rndr->p_surface,&stat); |
1222 if( (stat & XVMC_DISPLAYING) == 0 ) | 1222 if( (stat & XVMC_DISPLAYING) == 0 ) |
1223 return visible_rndr; | 1223 return visible_rndr; |
1224 } | 1224 } |
1225 } | 1225 } |
1226 //todo remove when stable | 1226 //todo remove when stable |
1227 printf("vo_xvmc: no free surfaces, this should not happen in g1\n"); | 1227 printf("vo_xvmc: no free surfaces, this should not happen in g1\n"); |
1228 for(i=0;i<number_of_surfaces;i++) | 1228 for(i=0;i<number_of_surfaces;i++) |
1229 printf("vo_xvmc: surface[%d].state=%d\n",i,surface_render[i].state); | 1229 printf("vo_xvmc: surface[%d].state=%d\n",i,surface_render[i].state); |
1230 return NULL; | 1230 return NULL; |
1231 } | 1231 } |
1232 | 1232 |
1233 static void xvmc_clean_surfaces(void){ | 1233 static void xvmc_clean_surfaces(void){ |
1234 int i; | 1234 int i; |
1235 | 1235 |
1236 for(i=0; i<number_of_surfaces; i++){ | 1236 for(i=0; i<number_of_surfaces; i++){ |
1237 | 1237 |
1238 surface_render[i].state&=!( AV_XVMC_STATE_DISPLAY_PENDING | | 1238 surface_render[i].state&=!( AV_XVMC_STATE_DISPLAY_PENDING | |
1239 AV_XVMC_STATE_OSD_SOURCE | | 1239 AV_XVMC_STATE_OSD_SOURCE | |
1240 0); | 1240 0); |
1241 surface_render[i].p_osd_target_surface_render=NULL; | 1241 surface_render[i].p_osd_target_surface_render=NULL; |
1242 if(surface_render[i].state != 0){ | 1242 if(surface_render[i].state != 0){ |
1243 mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n", | 1243 mp_msg(MSGT_VO,MSGL_WARN,"vo_xvmc: surface[%d].state=%d\n", |
1244 i,surface_render[i].state); | 1244 i,surface_render[i].state); |
1245 } | 1245 } |
1246 } | 1246 } |
1247 free_element=0;//clean up the queue | 1247 free_element=0;//clean up the queue |
1248 } | 1248 } |
1249 | 1249 |
1250 static uint32_t get_image(mp_image_t *mpi){ | 1250 static uint32_t get_image(mp_image_t *mpi){ |
1251 struct xvmc_pix_fmt *rndr; | 1251 struct xvmc_pix_fmt *rndr; |
1252 | 1252 |
1253 rndr = find_free_surface(); | 1253 rndr = find_free_surface(); |
1254 | 1254 |
1255 if(rndr == NULL){ | 1255 if(rndr == NULL){ |
1256 printf("vo_xvmc: get_image failed\n"); | 1256 printf("vo_xvmc: get_image failed\n"); |
1257 return VO_FALSE; | 1257 return VO_FALSE; |
1258 } | 1258 } |
1259 | 1259 |
1260 assert(rndr->start_mv_blocks_num == 0); | 1260 assert(rndr->start_mv_blocks_num == 0); |
1261 assert(rndr->filled_mv_blocks_num == 0); | 1261 assert(rndr->filled_mv_blocks_num == 0); |
1262 assert(rndr->next_free_data_block_num == 0); | 1262 assert(rndr->next_free_data_block_num == 0); |
1263 | 1263 |
1264 mpi->flags |= MP_IMGFLAG_DIRECT; | 1264 mpi->flags |= MP_IMGFLAG_DIRECT; |
1265 //keep strides 0 to avoid field manipulations | 1265 //keep strides 0 to avoid field manipulations |
1266 mpi->stride[0] = 0; | 1266 mpi->stride[0] = 0; |
1267 mpi->stride[1] = 0; | 1267 mpi->stride[1] = 0; |
1268 mpi->stride[2] = 0; | 1268 mpi->stride[2] = 0; |
1269 | 1269 |
1270 // these are shared!! so watch out | 1270 // these are shared!! so watch out |
1271 // do call RenderSurface before overwriting | 1271 // do call RenderSurface before overwriting |
1272 mpi->planes[0] = (char*)data_blocks.blocks; | 1272 mpi->planes[0] = (char*)data_blocks.blocks; |
1273 mpi->planes[1] = (char*)mv_blocks.macro_blocks; | 1273 mpi->planes[1] = (char*)mv_blocks.macro_blocks; |
1274 mpi->priv = | 1274 mpi->priv = |
1275 mpi->planes[2] = (char*)rndr; | 1275 mpi->planes[2] = (char*)rndr; |
1276 | 1276 |
1277 rndr->picture_structure = 0; | 1277 rndr->picture_structure = 0; |
1278 rndr->flags = 0; | 1278 rndr->flags = 0; |
1279 rndr->state = 0; | 1279 rndr->state = 0; |
1280 rndr->start_mv_blocks_num = 0; | 1280 rndr->start_mv_blocks_num = 0; |
1281 rndr->filled_mv_blocks_num = 0; | 1281 rndr->filled_mv_blocks_num = 0; |
1282 rndr->next_free_data_block_num = 0; | 1282 rndr->next_free_data_block_num = 0; |
1283 | 1283 |
1284 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) | 1284 if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
1285 printf("vo_xvmc: get_image: rndr=%p (surface=%p) \n", | 1285 printf("vo_xvmc: get_image: rndr=%p (surface=%p) \n", |
1286 rndr,rndr->p_surface); | 1286 rndr,rndr->p_surface); |
1287 return VO_TRUE; | 1287 return VO_TRUE; |
1288 } | 1288 } |
1289 | 1289 |
1290 static int control(uint32_t request, void *data, ... ) | 1290 static int control(uint32_t request, void *data, ... ) |
1291 { | 1291 { |
1292 switch (request){ | 1292 switch (request){ |
1293 case VOCTRL_GET_DEINTERLACE: | 1293 case VOCTRL_GET_DEINTERLACE: |
1294 *(int*)data = bob_deinterlace; | 1294 *(int*)data = bob_deinterlace; |
1295 return VO_TRUE; | 1295 return VO_TRUE; |
1296 case VOCTRL_SET_DEINTERLACE: | 1296 case VOCTRL_SET_DEINTERLACE: |
1297 bob_deinterlace = *(int*)data; | 1297 bob_deinterlace = *(int*)data; |
1298 return VO_TRUE; | 1298 return VO_TRUE; |
1299 case VOCTRL_QUERY_FORMAT: | 1299 case VOCTRL_QUERY_FORMAT: |
1300 return query_format(*((uint32_t*)data)); | 1300 return query_format(*((uint32_t*)data)); |
1301 case VOCTRL_DRAW_IMAGE: | 1301 case VOCTRL_DRAW_IMAGE: |
1302 return xvmc_draw_image((mp_image_t *)data); | 1302 return xvmc_draw_image((mp_image_t *)data); |
1303 case VOCTRL_GET_IMAGE: | 1303 case VOCTRL_GET_IMAGE: |
1304 return get_image((mp_image_t *)data); | 1304 return get_image((mp_image_t *)data); |
1305 //vo_xv | 1305 //vo_xv |
1306 case VOCTRL_GUISUPPORT: | 1306 case VOCTRL_GUISUPPORT: |
1307 return VO_TRUE; | 1307 return VO_TRUE; |
1308 case VOCTRL_ONTOP: | 1308 case VOCTRL_ONTOP: |
1309 vo_x11_ontop(); | 1309 vo_x11_ontop(); |
1310 return VO_TRUE; | 1310 return VO_TRUE; |
1311 case VOCTRL_FULLSCREEN: | 1311 case VOCTRL_FULLSCREEN: |
1312 vo_x11_fullscreen(); | 1312 vo_x11_fullscreen(); |
1313 // indended, fallthrough to update panscan on fullscreen/windowed switch | 1313 // indended, fallthrough to update panscan on fullscreen/windowed switch |
1314 case VOCTRL_SET_PANSCAN: | 1314 case VOCTRL_SET_PANSCAN: |
1315 if ( ( vo_fs && ( vo_panscan != vo_panscan_amount ) ) || ( !vo_fs && vo_panscan_amount ) ) | 1315 if ( ( vo_fs && ( vo_panscan != vo_panscan_amount ) ) || ( !vo_fs && vo_panscan_amount ) ) |
1316 { | |
1317 int old_y = vo_panscan_y; | |
1318 panscan_calc(); | |
1319 | |
1320 if(old_y != vo_panscan_y) | |
1321 { | 1316 { |
1322 //this also draws the colorkey | 1317 int old_y = vo_panscan_y; |
1323 put_xvmc_image(p_render_surface_visible,1); | 1318 panscan_calc(); |
1319 | |
1320 if(old_y != vo_panscan_y) | |
1321 { | |
1322 //this also draws the colorkey | |
1323 put_xvmc_image(p_render_surface_visible,1); | |
1324 } | |
1324 } | 1325 } |
1325 } | 1326 return VO_TRUE; |
1326 return VO_TRUE; | 1327 case VOCTRL_GET_PANSCAN: |
1327 case VOCTRL_GET_PANSCAN: | 1328 if ( !vo_config_count || !vo_fs ) return VO_FALSE; |
1328 if ( !vo_config_count || !vo_fs ) return VO_FALSE; | 1329 return VO_TRUE; |
1329 return VO_TRUE; | 1330 case VOCTRL_SET_EQUALIZER: |
1330 case VOCTRL_SET_EQUALIZER: | 1331 { |
1331 { | 1332 va_list ap; |
1332 va_list ap; | 1333 int value; |
1333 int value; | 1334 |
1334 | 1335 va_start(ap, data); |
1335 va_start(ap, data); | 1336 value = va_arg(ap, int); |
1336 value = va_arg(ap, int); | 1337 va_end(ap); |
1337 va_end(ap); | 1338 |
1338 | 1339 return vo_xv_set_eq(xv_port, data, value); |
1339 return vo_xv_set_eq(xv_port, data, value); | 1340 } |
1340 } | 1341 |
1341 | 1342 case VOCTRL_GET_EQUALIZER: |
1342 case VOCTRL_GET_EQUALIZER: | 1343 { |
1343 { | 1344 va_list ap; |
1344 va_list ap; | 1345 int *value; |
1345 int *value; | 1346 |
1346 | 1347 va_start(ap, data); |
1347 va_start(ap, data); | 1348 value = va_arg(ap, int*); |
1348 value = va_arg(ap, int*); | 1349 va_end(ap); |
1349 va_end(ap); | 1350 |
1350 | 1351 return vo_xv_get_eq(xv_port, data, value); |
1351 return vo_xv_get_eq(xv_port, data, value); | 1352 } |
1352 } | 1353 case VOCTRL_UPDATE_SCREENINFO: |
1353 case VOCTRL_UPDATE_SCREENINFO: | 1354 update_xinerama_info(); |
1354 update_xinerama_info(); | 1355 return VO_TRUE; |
1355 return VO_TRUE; | 1356 } |
1356 } | |
1357 return VO_NOTIMPL; | 1357 return VO_NOTIMPL; |
1358 } | 1358 } |