Ticket #3486: 3486-v1.patch
File 3486-v1.patch, 11.9 KB (added by , 17 years ago) |
---|
-
libs/libmythtv/videoout_ivtv.h
1 1 #ifndef VIDEOOUT_IVTV_H_ 2 2 #define VIDEOOUT_IVTV_H_ 3 3 4 // Linux system headers 5 #include <linux/fb.h> 6 7 // Qt headers 4 8 #include <qstring.h> 5 9 #include <qmutex.h> 6 #include <cassert>7 10 11 // MythTV headers 8 12 #include "videooutbase.h" 9 13 14 #ifdef USING_IVTV_HEADER 15 #include <linux/ivtv.h> 16 #else 17 #include "ivtv_myth.h" 18 #endif 19 10 20 class NuppelVideoPlayer; 11 21 12 22 class VideoOutputIvtv: public VideoOutput … … 108 118 bool last_normal; 109 119 int last_mask; 110 120 eAlphaState alphaState; 121 122 bool old_ioctl; 123 struct fb_var_screeninfo ivtvfb_var; 124 struct fb_var_screeninfo ivtvfb_var_old; 125 #ifdef IVTVFB_IOCTL_GET_COLORKEY 126 struct ivtvfb_ioctl_colorkey ivtvfb_colorkey; 127 struct ivtvfb_ioctl_colorkey ivtvfb_colorkey_old; 128 #endif 111 129 }; 112 130 113 131 #endif -
libs/libmythtv/videoout_ivtv.cpp
73 73 74 74 last_normal(true), last_mask(0x2), 75 75 76 alphaState(kAlpha_Solid) 76 alphaState(kAlpha_Solid), old_ioctl(true) 77 77 { 78 78 } 79 79 … … 103 103 104 104 VERBOSE(VB_PLAYBACK, LOC + "ClearOSD"); 105 105 106 struct ivtv_osd_coords osdcoords; 107 bzero(&osdcoords, sizeof(osdcoords)); 106 bzero(osdbuf_aligned, osdbufsize); 108 107 109 if (ioctl(fbfd, IVTVFB_IOCTL_GET_ACTIVE_BUFFER, &osdcoords) < 0)110 {111 VERBOSE(VB_IMPORTANT, LOC_ERR +112 "Failed to get active buffer for ClearOSD()" + ENO);113 }114 108 struct ivtvfb_ioctl_dma_host_to_ivtv_args prep; 115 109 bzero(&prep, sizeof(prep)); 116 110 117 111 prep.source = osdbuf_aligned; 118 112 prep.dest_offset = 0; 119 prep.count = osdcoords.max_offset;120 113 121 bzero(osdbuf_aligned, osdbufsize); 114 if (old_ioctl == true) 115 { 116 struct ivtv_osd_coords osdcoords; 117 bzero(&osdcoords, sizeof(osdcoords)); 122 118 119 if (ioctl(fbfd, IVTVFB_IOCTL_GET_ACTIVE_BUFFER, &osdcoords) < 0) 120 { 121 VERBOSE(VB_IMPORTANT, LOC_ERR + 122 "Failed to get active buffer for ClearOSD()" + ENO); 123 } 124 prep.count = osdcoords.max_offset; 125 } 126 else 127 prep.count = ivtvfb_var.xres_virtual * ivtvfb_var.yres * (ivtvfb_var.bits_per_pixel / 8); 128 129 if (old_ioctl == false) 130 ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var); 131 123 132 if (ioctl(fbfd, IVTVFB_IOCTL_PREP_FRAME, &prep) < 0) 124 133 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to prepare frame" + ENO); 125 134 } … … 140 149 VERBOSE(VB_PLAYBACK, LOC + "SetAlpha(Embedded)"); 141 150 #endif 142 151 143 alphaState = newAlphaState;144 145 152 struct ivtvfb_ioctl_state_info fbstate; 146 153 bzero(&fbstate, sizeof(fbstate)); 147 154 if (ioctl(fbfd, IVTVFB_IOCTL_GET_STATE, &fbstate) < 0) 148 155 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to query alpha state" + ENO); 149 156 150 if ( alphaState == kAlpha_Local)157 if (newAlphaState == kAlpha_Local) 151 158 { 152 159 fbstate.status &= ~IVTVFB_STATUS_GLOBAL_ALPHA; 153 160 fbstate.status |= IVTVFB_STATUS_LOCAL_ALPHA; … … 158 165 fbstate.status &= ~IVTVFB_STATUS_LOCAL_ALPHA; 159 166 } 160 167 161 if ( alphaState == kAlpha_Solid)168 if (newAlphaState == kAlpha_Solid) 162 169 fbstate.alpha = 255; 163 else if ( alphaState == kAlpha_Clear)170 else if (newAlphaState == kAlpha_Clear) 164 171 fbstate.alpha = 0; 165 else if ( alphaState == kAlpha_Embedded)172 else if (newAlphaState == kAlpha_Embedded) 166 173 fbstate.alpha = gContext->GetNumSetting("PVR350EPGAlphaValue", 164); 167 174 175 // If using the new ioctl we need to check the fb mode 176 if (old_ioctl == false) 177 { 178 struct fb_var_screeninfo *tmpfb_var = NULL; 179 180 // If EPG switched on, select old fb mode 181 if (newAlphaState == kAlpha_Embedded) 182 tmpfb_var = &ivtvfb_var_old; 183 // If EPG switched off, select new fb mode 184 else if (newAlphaState != kAlpha_Embedded && alphaState == kAlpha_Embedded) 185 tmpfb_var = &ivtvfb_var; 186 187 // Change fb mode if required 188 if (tmpfb_var) 189 { 190 if ((ivtvfb_var_old.bits_per_pixel != 32) && 191 (ivtvfb_var_old.bits_per_pixel != 8)) 192 { 193 // Hide osd during mode change 194 #ifdef FB_BLANK_NORMAL 195 ioctl(fbfd, FBIOBLANK, FB_BLANK_NORMAL); 196 #else 197 ioctl(fbfd, FBIOBLANK, VESA_VSYNC_SUSPEND); 198 #endif 199 tmpfb_var->activate = FB_ACTIVATE_NOW; 200 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, tmpfb_var) < 0) 201 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to switch framebuffer settings for EPG" + ENO); 202 203 // Restore osd 204 #ifdef FB_BLANK_UNBLANK 205 ioctl(fbfd, FBIOBLANK, FB_BLANK_UNBLANK); 206 #else 207 ioctl(fbfd, FBIOBLANK, VESA_NO_BLANKING); 208 #endif 209 } 210 // Reset display pan 211 ivtvfb_var.xoffset = 0; 212 ivtvfb_var.yoffset = 0; 213 ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var); 214 } 215 } 216 168 217 if (ioctl(fbfd, IVTVFB_IOCTL_SET_STATE, &fbstate) < 0) 169 218 VERBOSE(VB_IMPORTANT, LOC_ERR + 170 219 "Failed to set ivtv alpha values." + ENO); 220 221 alphaState = newAlphaState; 171 222 } 172 223 173 224 void VideoOutputIvtv::InputChanged(int width, int height, float aspect, … … 244 295 bzero(&igfb, sizeof(igfb)); 245 296 246 297 if (ioctl(fbfd, IVTVFB_IOCTL_GET_FRAME_BUFFER, &igfb) < 0) 247 VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO); 298 { 299 if (errno == EINVAL) 300 { 301 struct fb_fix_screeninfo ivtvfb_fix; 302 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &ivtvfb_fix) < 0) 303 VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO); 304 else 305 { 306 old_ioctl = false; 307 ioctl(fbfd, FBIOGET_VSCREENINFO, &ivtvfb_var_old); 308 } 309 } 310 else 311 VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO); 312 } 248 313 249 stride = igfb.sizex * 4;250 251 314 long pagesize = sysconf(_SC_PAGE_SIZE); 252 315 long pagemask = ~(pagesize-1); 253 316 osdbuffer = new char[osdbufsize + pagesize]; … … 256 319 257 320 bzero(osdbuf_aligned, osdbufsize); 258 321 259 ClearOSD(); 322 if (old_ioctl == true) 323 { 324 struct ivtv_osd_coords osdcoords; 325 stride = igfb.sizex * 4; 326 bzero(&osdcoords, sizeof(osdcoords)); 327 osdcoords.lines = video_dim.height(); 328 osdcoords.offset = 0; 329 osdcoords.pixel_stride = video_dim.width() * 2; 330 if (ioctl(fbfd, IVTVFB_IOCTL_SET_ACTIVE_BUFFER, &osdcoords) < 0) 331 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting active buffer" + ENO); 332 } 333 else 334 { 335 bzero (&ivtvfb_var, sizeof(ivtvfb_var)); 260 336 261 struct ivtv_osd_coords osdcoords; 262 bzero(&osdcoords, sizeof(osdcoords)); 263 osdcoords.lines = video_dim.height(); 264 osdcoords.offset = 0; 265 osdcoords.pixel_stride = video_dim.width() * 2; 337 // Switch dimensions to match the framebuffer 338 video_dim = QSize(ivtvfb_var_old.xres, ivtvfb_var_old.yres); 266 339 267 if (ioctl(fbfd, IVTVFB_IOCTL_SET_ACTIVE_BUFFER, &osdcoords) < 0) 268 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting active buffer" + ENO); 340 memcpy(&ivtvfb_var,&ivtvfb_var_old,sizeof ivtvfb_var); 269 341 342 // The OSD only supports 32bpp, so only change mode if needed 343 if (ivtvfb_var_old.bits_per_pixel != 32) 344 { 345 ivtvfb_var.xres_virtual = ivtvfb_var.xres; 346 ivtvfb_var.yres_virtual = ivtvfb_var.yres; 347 ivtvfb_var.xoffset = 0; 348 ivtvfb_var.yoffset = 0; 349 ivtvfb_var.bits_per_pixel = 32; 350 ivtvfb_var.nonstd = 0; 351 ivtvfb_var.activate = FB_ACTIVATE_NOW; 352 353 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &ivtvfb_var) < 0) 354 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting frame buffer" + ENO); 355 } 356 else 357 { 358 ivtvfb_var.xoffset = 0; 359 ivtvfb_var.yoffset = 0; 360 ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var); 361 } 362 363 stride = ivtvfb_var.xres_virtual * 4; 364 } 365 366 #ifdef IVTVFB_IOCTL_GET_COLORKEY 367 // Setup color-key. This helps when X isn't running on the PVR350 368 ioctl(fbfd,IVTVFB_IOCTL_GET_COLORKEY, &ivtvfb_colorkey_old); 369 ivtvfb_colorkey.state = 1; 370 ivtvfb_colorkey.colorKey = 0x00010001; 371 ioctl(fbfd,IVTVFB_IOCTL_SET_COLORKEY, &ivtvfb_colorkey); 372 #endif 373 ClearOSD(); 374 270 375 SetAlpha(kAlpha_Clear); 271 376 } 272 377 … … 286 391 { 287 392 Stop(true /* hide */); 288 393 394 if (old_ioctl == false) 395 { 396 ivtvfb_var_old.activate = FB_ACTIVATE_NOW; 397 398 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &ivtvfb_var_old) < 0) 399 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to restore framebuffer settings" + ENO); 400 } 401 402 #ifdef IVTVFB_IOCTL_GET_COLORKEY 403 // Restore old colorkey 404 ioctl(fbfd,IVTVFB_IOCTL_SET_COLORKEY, &ivtvfb_colorkey_old); 405 #endif 289 406 close(videofd); 290 407 videofd = -1; 291 408 } … … 450 567 451 568 VideoFrame tmpframe; 452 569 init(&tmpframe, FMT_ARGB32, (unsigned char *)osdbuf_aligned, 453 stride, video_dim.height(), 32, 4 *stride * video_dim.height());570 stride, video_dim.height(), 32, stride * video_dim.height()); 454 571 455 572 OSDSurface *surface = NULL; 456 573 if (osd) … … 506 623 pipon = (bool) pipPlayer; 507 624 508 625 // If there is an OSD, make sure we draw OSD surface 509 lastcleared &= !osd ;626 lastcleared &= !osdon; 510 627 511 #if 0512 // These optimizations have been disabled until someone with a real PVR-350513 // setup can test them Feb 7th, 2006 -- dtk514 628 // If nothing on OSD surface, just set the alpha to zero 515 if ( lastcleared && drawanyway)629 if (!osdon && !pipon) 516 630 { 631 if (lastcleared == true) 632 return; 633 634 lastcleared = true; 517 635 SetAlpha(kAlpha_Clear); 518 return; 636 #ifdef IVTVFB_IOCTL_GET_COLORKEY 637 #ifdef WORDS_BIGENDIAN 638 wmemset((wchar_t *)osdbuf_aligned, 0x01000100, osdbufsize/4); 639 #else 640 wmemset((wchar_t *)osdbuf_aligned, 0x00010001, osdbufsize/4); 641 #endif 642 #endif 519 643 } 520 644 521 645 // If there has been no OSD change and no draw has been forced we're done 522 646 if (ret <= 0 && !drawanyway) 523 647 return; 524 #endif525 648 526 649 // The OSD surface needs to be updated... 527 650 struct ivtvfb_ioctl_dma_host_to_ivtv_args prep; … … 529 652 prep.source = osdbuf_aligned; 530 653 prep.count = video_dim.height() * stride; 531 654 655 // This shouldn't be here. OSD should be rendered correctly to start with 656 #ifdef WORDS_BIGENDIAN 657 int b_index, i_index; 658 unsigned int *osd_int = (unsigned int *)osdbuf_aligned; 659 if (lastcleared != true) 660 { 661 for (b_index = 0, i_index = 0; b_index < prep.count; b_index += 4, i_index ++) 662 { 663 if (osd_int[i_index]) 664 { 665 osd_int[i_index] = 666 ((unsigned char)osdbuf_aligned[b_index+0]) | 667 ((unsigned char)osdbuf_aligned[b_index+1] << 8) | 668 ((unsigned char)osdbuf_aligned[b_index+2] << 16) | 669 ((unsigned char)osdbuf_aligned[b_index+3] << 24); 670 } 671 } 672 } 673 #endif 674 675 if (old_ioctl == false) 676 ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var); 677 532 678 if (ioctl(fbfd, IVTVFB_IOCTL_PREP_FRAME, &prep) < 0) 533 679 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to process frame" + ENO); 534 680 535 SetAlpha(kAlpha_Local); 681 if (lastcleared != true) 682 SetAlpha(kAlpha_Local); 536 683 } 537 684 538 685 /** \fn VideoOutputIvtv::Start(int,int)