Ticket #8593: vaapi_v5.diff
File vaapi_v5.diff, 50.4 KB (added by , 15 years ago) |
---|
-
configure
128 128 --enable-xvmc-vld enable XvMC VLD accel. for the Unichrome (Pro) chipset 129 129 --xvmc-lib=LIB XvMC library override (for crosscompiling) 130 130 --enable-vdpau enable NVidia VDPAU hardware acceleration. 131 --enable-vaapi enable VAAPI hardware acceleration 131 132 --disable-opengl-video disable OpenGL based video display 132 133 --enable-mac-accel enable Mac OS X MPEG acceleration 133 134 --disable-opengl-vsync disable OpenGL vsync method … … 1336 1337 dvdv 1337 1338 opengl 1338 1339 vdpau 1340 vaapi 1339 1341 ' 1340 1342 1341 1343 CMDLINE_SELECT=" … … 1678 1680 xvmc_deps="xv X11_extensions_XvMClib_h" 1679 1681 xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h" 1680 1682 xvmcw_deps="xvmc" 1683 vaapi_deps="x11 opengl_video" 1681 1684 1682 1685 # default parameters 1683 1686 pre_logfile="config.ep" … … 3396 3399 check_header termios.h 3397 3400 check_header vdpau/vdpau.h 3398 3401 check_header vdpau/vdpau_x11.h 3402 check_header va/va.h 3403 check_header va/va_glx.h 3399 3404 check_header X11/extensions/XvMClib.h 3400 3405 3401 3406 check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex … … 3664 3669 disable vdpau; } 3665 3670 fi 3666 3671 3672 if enabled vaapi; then 3673 enabled va_va_h && enabled va_va_glx_h || disable vaapi 3674 if enabled vaapi; then 3675 # for XvBA/VDPAU backends we need splitted desktop 0.31.0 but 3676 # for upstream GLX support we need 0.31.1 ??? 3677 check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" || 3678 { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; } 3679 fi 3680 else 3681 disable vaapi 3682 fi 3683 3667 3684 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" 3668 3685 enabled debug && add_cxxflags -g"$debuglevel" 3669 3686 … … 4221 4238 echo "XvMC libs $VENDOR_XVMC_LIBS" 4222 4239 fi 4223 4240 echo "VDPAU support ${vdpau-no}" 4241 echo "VAAPI support ${vaapi-no}" 4224 4242 fi 4225 4243 echo "OpenGL video ${opengl_video-no}" 4226 4244 if test x"$target_os" = x"darwin" ; then -
libs/libmythtv/videoout_openglvaapi.h
1 #ifndef VIDEOOUTPUTOPENGLVAAPI_H 2 #define VIDEOOUTPUTOPENGLVAAPI_H 3 4 #include "videoout_opengl.h" 5 #include "vaapicontext.h" 6 7 class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL 8 { 9 public: 10 static void GetRenderOptions(render_opts &opts); 11 12 VideoOutputOpenGLVAAPI(MythCodecID codec_id); 13 ~VideoOutputOpenGLVAAPI(); 14 15 bool Init(int width, int height, float aspect, WId winid, 16 int winx, int winy, int winw, int winh, WId embedid = 0); 17 bool CreateVAAPIContext(QSize size); 18 void DeleteVAAPIContext(void); 19 bool CreateBuffers(void); 20 void* GetVAAPIContext(void); 21 uint8_t* GetSurfaceIDPointer(void* buf); 22 void SetProfile(void); 23 void TearDown(void); 24 bool InputChanged(const QSize &input_size, float aspect, 25 MythCodecID av_codec_id, void *codec_private, 26 bool &aspect_only); 27 void ProcessFrame(VideoFrame *frame, OSD *osd, 28 FilterChain *filterList, 29 const PIPMap &pipPlayers, 30 FrameScanType scan); 31 bool ApproveDeintFilter(const QString& filtername) const; 32 bool SetDeinterlacingEnabled(bool); 33 bool SetupDeinterlace(bool i, const QString& ovrf=""); 34 35 static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, 36 const QSize &video_dim); 37 static MythCodecID GetBestSupportedCodec(uint width, uint height, 38 uint stream_type, 39 bool no_acceleration, 40 PixelFormat &pix_fmt); 41 42 private: 43 VAAPIContext *m_ctx; 44 }; 45 46 #endif // VIDEOOUTPUTOPENGLVAAPI_H 47 -
libs/libmythtv/videoout_opengl.cpp
8 8 #include "NuppelVideoPlayer.h" 9 9 #include "mythuihelper.h" 10 10 11 #define LOC QString("VidOut OGL: ")12 #define LOC_ERR QString("VidOut OGL: ")11 #define LOC QString("VidOutGL: ") 12 #define LOC_ERR QString("VidOutGL Error: ") 13 13 14 14 void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 15 15 QStringList &cpudeints) … … 37 37 opts.priorities->insert("opengl", 65); 38 38 } 39 39 40 VideoOutputOpenGL::VideoOutputOpenGL( void)40 VideoOutputOpenGL::VideoOutputOpenGL(MythCodecID codec_id) 41 41 : VideoOutput(), 42 gl_co ntext_lock(QMutex::Recursive),42 gl_codec_id(codec_id), gl_context_lock(QMutex::Recursive), 43 43 gl_context(NULL), gl_videochain(NULL), gl_pipchain_active(NULL), 44 44 gl_parent_win(0), gl_embed_win(0), gl_painter(NULL) 45 45 { … … 123 123 winid, winx, winy, winw, winh, 124 124 embedid); 125 125 126 if (db_vdisp_profile) 127 db_vdisp_profile->SetVideoRenderer("opengl"); 126 SetProfile(); 128 127 129 128 success &= SetupContext(); 130 129 InitDisplayMeasurements(width, height, false); 131 130 success &= CreateBuffers(); 131 success &= CreatePauseFrame(); 132 132 success &= SetupOpenGL(); 133 133 134 134 InitOSD(); … … 144 144 return success; 145 145 } 146 146 147 void VideoOutputOpenGL::SetProfile(void) 148 { 149 if (db_vdisp_profile) 150 db_vdisp_profile->SetVideoRenderer("opengl"); 151 } 152 147 153 bool VideoOutputOpenGL::InputChanged(const QSize &input_size, 148 154 float aspect, 149 155 MythCodecID av_codec_id, 150 156 void *codec_private, 151 157 bool &aspect_only) 152 158 { 153 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4 ")159 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5") 154 160 .arg(input_size.width()).arg(input_size.height()).arg(aspect) 155 .arg(toString( av_codec_id)));161 .arg(toString(gl_codec_id)).arg(toString(av_codec_id))); 156 162 157 163 QMutexLocker locker(&gl_context_lock); 158 159 if (!codec_is_std( av_codec_id))164 gl_codec_id = av_codec_id; 165 if (!codec_is_std(gl_codec_id)) 160 166 { 161 167 VERBOSE(VB_IMPORTANT, LOC_ERR + 162 168 QString("New video codec is not supported.")); … … 242 248 windows[0].GetVideoDim(), dvr, 243 249 windows[0].GetDisplayVideoRect(), 244 250 windows[0].GetVideoRect(), true, 245 GetFilters(), db_letterbox_colour); 251 GetFilters(), !codec_is_std(gl_codec_id), 252 db_letterbox_colour); 246 253 if (success) 247 254 { 248 255 bool temp_deinterlacing = m_deinterlacing; … … 276 283 bool VideoOutputOpenGL::CreateBuffers(void) 277 284 { 278 285 QMutexLocker locker(&gl_context_lock); 279 280 bool success = true;281 286 vbuffers.Init(31, true, 1, 12, 4, 2, false); 282 success &= vbuffers.CreateBuffers(windows[0].GetVideoDim().width(), 283 windows[0].GetVideoDim().height()); 287 return vbuffers.CreateBuffers(windows[0].GetVideoDim().width(), 288 windows[0].GetVideoDim().height()); 289 } 284 290 291 bool VideoOutputOpenGL::CreatePauseFrame(void) 292 { 285 293 av_pause_frame.height = vbuffers.GetScratchFrame()->height; 286 294 av_pause_frame.width = vbuffers.GetScratchFrame()->width; 287 295 av_pause_frame.bpp = vbuffers.GetScratchFrame()->bpp; … … 290 298 av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber; 291 299 292 300 if (!av_pause_frame.buf) 293 { 294 success = false; 295 } 296 else 297 { 298 int size = av_pause_frame.width * av_pause_frame.height; 299 memset(av_pause_frame.buf, 0, size); 300 memset(av_pause_frame.buf + size, 127, size / 2); 301 } 301 return false; 302 302 303 return success; 303 int size = av_pause_frame.width * av_pause_frame.height; 304 memset(av_pause_frame.buf, 0, size); 305 memset(av_pause_frame.buf + size, 127, size / 2); 306 return true; 304 307 } 305 308 306 309 void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd, … … 312 315 if (!gl_videochain || !gl_context) 313 316 return; 314 317 318 bool sw_frame = codec_is_std(gl_codec_id); 315 319 bool deint_proc = m_deinterlacing && (m_deintFilter != NULL); 316 320 OpenGLLocker ctx_lock(gl_context); 317 321 … … 323 327 pauseframe = true; 324 328 } 325 329 326 if (filterList )330 if (filterList && sw_frame) 327 331 filterList->ProcessFrame(frame); 328 332 329 333 bool safepauseframe = pauseframe && !IsBobDeint(); 330 if ( deint_proc && m_deinterlaceBeforeOSD &&334 if (sw_frame && deint_proc && m_deinterlaceBeforeOSD && 331 335 (!pauseframe || safepauseframe)) 332 336 { 333 337 m_deintFilter->ProcessFrame(frame, scan); … … 339 343 ShowPIPs(frame, pipPlayers); 340 344 } 341 345 342 if ( (!pauseframe || safepauseframe) &&346 if (sw_frame && (!pauseframe || safepauseframe) && 343 347 deint_proc && !m_deinterlaceBeforeOSD) 344 348 { 345 349 m_deintFilter->ProcessFrame(frame, scan); … … 347 351 348 352 bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint"); 349 353 350 if (gl_videochain )354 if (gl_videochain && sw_frame) 351 355 gl_videochain->UpdateInputFrame(frame, soft_bob); 352 356 } 353 357 … … 371 375 framesPlayed = buffer->frameNumber + 1; 372 376 gl_context_lock.unlock(); 373 377 374 if (buffer->codec != FMT_YV12)375 return;376 377 378 gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect : 378 379 windows[0].GetDisplayVideoRect(), 379 380 windows[0].GetVideoRect()); … … 653 654 QSize(pipVideoWidth, pipVideoHeight), 654 655 dvr, position, 655 656 QRect(0, 0, pipVideoWidth, pipVideoHeight), 656 false, GetFilters() );657 false, GetFilters(), false); 657 658 gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort()); 658 659 if (!success) 659 660 { … … 674 675 QSize(pipVideoWidth, pipVideoHeight), 675 676 dvr, position, 676 677 QRect(0, 0, pipVideoWidth, pipVideoHeight), 677 false, GetFilters() );678 false, GetFilters(), false); 678 679 679 680 gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort()); 680 681 if (!success) -
libs/libmythtv/avformatdecoder.cpp
49 49 } 50 50 #endif // USING_VDPAU 51 51 52 #ifdef USING_VAAPI 53 #include "videoout_openglvaapi.h" 54 #endif // USING_VAAPI 55 52 56 extern "C" { 53 57 #include "avutil.h" 54 58 #include "ac3_parser.h" … … 92 96 void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src, 93 97 int offset[4], int y, int type, int height); 94 98 99 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic); 100 95 101 static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id) 96 102 { 97 103 AVCodec *codec = c; … … 461 467 opts.decoders->append("vdpau"); 462 468 (*opts.equiv_decoders)["vdpau"].append("dummy"); 463 469 #endif 470 471 #ifdef USING_VAAPI 472 opts.decoders->append("vaapi"); 473 (*opts.equiv_decoders)["vaapi"].append("dummy"); 474 #endif 464 475 } 465 476 466 477 AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, … … 1356 1367 return fmt[i]; 1357 1368 } 1358 1369 1370 static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt) 1371 { 1372 return fmt == PIX_FMT_VAAPI_MOCO || 1373 fmt == PIX_FMT_VAAPI_IDCT || 1374 fmt == PIX_FMT_VAAPI_VLD; 1375 } 1376 1377 static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1378 const enum PixelFormat *fmt) 1379 { 1380 if (!fmt) 1381 return PIX_FMT_NONE; 1382 int i = 0; 1383 for (; fmt[i] != PIX_FMT_NONE ; i++) 1384 if (IS_VAAPI_PIX_FMT(fmt[i])) 1385 break; 1386 return fmt[i]; 1387 } 1388 1359 1389 static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt) 1360 1390 { 1361 1391 switch (fmt) … … 1426 1456 { 1427 1457 directrendering = true; 1428 1458 if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) && 1429 !CODEC_IS_HWACCEL(codec ))1459 !CODEC_IS_HWACCEL(codec, enc)) 1430 1460 { 1431 1461 SetLowBuffers(false); 1432 1462 } … … 1460 1490 enc->draw_horiz_band = render_slice_vdpau; 1461 1491 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1462 1492 } 1493 else if (CODEC_IS_VAAPI(codec, enc)) 1494 { 1495 enc->get_buffer = get_avf_buffer_vaapi; 1496 enc->get_format = get_format_vaapi; 1497 enc->release_buffer = release_avf_buffer; 1498 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1499 } 1463 1500 else if (codec && codec->capabilities & CODEC_CAP_DR1) 1464 1501 { 1465 1502 enc->flags |= CODEC_FLAG_EMU_EDGE; … … 1942 1979 handled = true; 1943 1980 } 1944 1981 #endif // USING_VDPAU 1982 #ifdef USING_VAAPI 1983 MythCodecID vaapi_mcid; 1984 PixelFormat pix_fmt = PIX_FMT_YUV420P; 1985 vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 1986 width, height, mpeg_version(enc->codec_id), 1987 no_hardware_decoders, pix_fmt); 1988 1989 if (vaapi_mcid >= video_codec_id) 1990 { 1991 enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid); 1992 video_codec_id = vaapi_mcid; 1993 handled = true; 1994 if (!no_hardware_decoders && 1995 codec_is_vaapi(video_codec_id)) 1996 { 1997 enc->pix_fmt = pix_fmt; 1998 } 1999 } 2000 #endif // USING_VAAPI 1945 2001 #ifdef USING_XVMC 1946 2002 1947 2003 bool force_xv = no_hardware_decoders; … … 2660 2716 } 2661 2717 } 2662 2718 2719 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic) 2720 { 2721 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 2722 VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(false); 2723 2724 pic->data[0] = frame->buf; 2725 pic->data[1] = NULL; 2726 pic->data[2] = NULL; 2727 pic->data[3] = NULL; 2728 pic->linesize[0] = 0; 2729 pic->linesize[1] = 0; 2730 pic->linesize[2] = 0; 2731 pic->linesize[3] = 0; 2732 pic->opaque = frame; 2733 pic->type = FF_BUFFER_TYPE_USER; 2734 pic->age = 256 * 256 * 256 * 64; 2735 frame->pix_fmt = c->pix_fmt; 2736 2737 #ifdef USING_VAAPI 2738 if (nd->GetNVP()->getVideoOutput()) 2739 { 2740 VideoOutputOpenGLVAAPI *vo = 2741 dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetNVP()->getVideoOutput()); 2742 c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext(); 2743 pic->data[3] = vo->GetSurfaceIDPointer(frame->buf); 2744 } 2745 #endif 2746 2747 return 0; 2748 } 2749 2663 2750 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len) 2664 2751 { 2665 2752 if (!len) -
libs/libmythtv/videoout_openglvaapi.cpp
1 #include "videoout_openglvaapi.h" 2 3 #define LOC QString("VidOutGLVAAPI: ") 4 #define LOC_ERR QString("VidOutGLVAAPI Error: ") 5 6 void VideoOutputOpenGLVAAPI::GetRenderOptions(render_opts &opts) 7 { 8 opts.renderers->append("openglvaapi"); 9 (*opts.deints)["openglvaapi"].append("vaapionefield"); 10 (*opts.deints)["openglvaapi"].append("vaapibobdeint"); 11 (*opts.deints)["openglvaapi"].append("none"); 12 (*opts.osds)["openglvaapi"].append("opengl2"); 13 14 if (opts.decoders->contains("vaapi")) 15 (*opts.safe_renderers)["vaapi"].append("openglvaapi"); 16 if (opts.decoders->contains("ffmpeg")) 17 (*opts.safe_renderers)["ffmpeg"].append("openglvaapi"); 18 if (opts.decoders->contains("libmpeg2")) 19 (*opts.safe_renderers)["libmpeg2"].append("openglvaapi"); 20 (*opts.safe_renderers)["dummy"].append("openglvaapi"); 21 (*opts.safe_renderers)["nuppel"].append("openglvaapi"); 22 23 opts.priorities->insert("openglvaapi", 110); 24 } 25 26 VideoOutputOpenGLVAAPI::VideoOutputOpenGLVAAPI(MythCodecID codec_id) 27 : VideoOutputOpenGL(codec_id), m_ctx(NULL) 28 { 29 if (gCoreContext->GetNumSetting("UseVideoModes", 0)) 30 display_res = DisplayRes::GetDisplayRes(true); 31 } 32 33 VideoOutputOpenGLVAAPI::~VideoOutputOpenGLVAAPI() 34 { 35 TearDown(); 36 } 37 38 void VideoOutputOpenGLVAAPI::TearDown(void) 39 { 40 DeleteVAAPIContext(); 41 } 42 43 bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &input_size, float aspect, 44 MythCodecID av_codec_id, void *codec_private, 45 bool &aspect_only) 46 { 47 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5") 48 .arg(input_size.width()).arg(input_size.height()).arg(aspect) 49 .arg(toString(gl_codec_id)).arg(toString(av_codec_id))); 50 51 if (!codec_is_vaapi(av_codec_id)) 52 return VideoOutputOpenGL::InputChanged(input_size, aspect, av_codec_id, 53 codec_private, aspect_only); 54 55 QMutexLocker locker(&gl_context_lock); 56 bool cid_changed = (gl_codec_id != av_codec_id); 57 bool res_changed = input_size != windows[0].GetVideoDim(); 58 bool asp_changed = aspect != windows[0].GetVideoAspect(); 59 gl_codec_id = av_codec_id; 60 61 if (!res_changed && !cid_changed) 62 { 63 if (asp_changed) 64 { 65 aspect_only = true; 66 VideoAspectRatioChanged(aspect); 67 MoveResize(); 68 } 69 return true; 70 } 71 72 TearDown(); 73 QRect disp = windows[0].GetDisplayVisibleRect(); 74 if (Init(input_size.width(), input_size.height(), 75 aspect, gl_parent_win, disp.left(), disp.top(), 76 disp.width(), disp.height(), gl_embed_win)) 77 { 78 BestDeint(); 79 return true; 80 } 81 82 VERBOSE(VB_IMPORTANT, LOC_ERR + 83 QString("Failed to re-initialise video output.")); 84 errorState = kError_Unknown; 85 86 return false; 87 } 88 89 bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect, 90 WId winid, int winx, int winy, int winw, 91 int winh, WId embedid) 92 { 93 VERBOSE(VB_PLAYBACK, LOC + "Init"); 94 if (codec_is_vaapi(gl_codec_id)) 95 if (!CreateVAAPIContext(QSize(width, height))) 96 return false; 97 98 return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy, 99 winw, winh, embedid); 100 } 101 102 bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size) 103 { 104 if (m_ctx) 105 DeleteVAAPIContext(); 106 m_ctx = new VAAPIContext(gl_codec_id); 107 if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers()) 108 return true; 109 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to create VAAPI context.")); 110 errorState = kError_Unknown; 111 return false; 112 } 113 114 void VideoOutputOpenGLVAAPI::DeleteVAAPIContext(void) 115 { 116 delete m_ctx; 117 m_ctx = NULL; 118 } 119 120 bool VideoOutputOpenGLVAAPI::CreateBuffers(void) 121 { 122 if ((!codec_is_vaapi(gl_codec_id)) || !m_ctx) 123 return VideoOutputOpenGL::CreateBuffers(); 124 125 QMutexLocker locker(&gl_context_lock); 126 int num_buffers = m_ctx->GetNumBuffers(); 127 const QSize video_dim = windows[0].GetVideoDim(); 128 vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame 129 130 bool ok = true; 131 for (int i = 0; i < num_buffers; i++) 132 { 133 ok &= vbuffers.CreateBuffer(video_dim.width(), 134 video_dim.height(), i, 135 m_ctx->GetVideoSurface(i), FMT_VAAPI); 136 } 137 return ok; 138 } 139 140 void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void) 141 { 142 if (m_ctx) 143 return &m_ctx->m_ctx; 144 return NULL; 145 } 146 147 uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf) 148 { 149 if (m_ctx) 150 return m_ctx->GetSurfaceIDPointer(buf); 151 return NULL; 152 } 153 154 void VideoOutputOpenGLVAAPI::SetProfile(void) 155 { 156 if (db_vdisp_profile) 157 db_vdisp_profile->SetVideoRenderer("openglvaapi"); 158 } 159 160 bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const 161 { 162 return filtername.contains("vaapi"); 163 } 164 165 bool VideoOutputOpenGLVAAPI::SetDeinterlacingEnabled(bool) 166 { 167 return true; 168 } 169 170 bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf) 171 { 172 return true; 173 } 174 175 void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd, 176 FilterChain *filterList, 177 const PIPMap &pipPlayers, 178 FrameScanType scan) 179 { 180 VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan); 181 182 if (codec_is_vaapi(gl_codec_id) && m_ctx && gl_videochain && frame) 183 { 184 gl_context->makeCurrent(); 185 uint tex = gl_videochain->GetInputTexture(); 186 gl_context->EnableTextures(tex); 187 if (m_ctx->CopySurfaceToTexture(frame->buf, tex, 188 gl_videochain->GetTextureType())) 189 { 190 gl_videochain->SetInputUpdated(); 191 } 192 gl_context->doneCurrent(); 193 } 194 } 195 196 QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers( 197 MythCodecID myth_codec_id, const QSize &video_dim) 198 { 199 (void) video_dim; 200 QStringList list; 201 if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) && 202 !getenv("NO_VAAPI")) 203 { 204 list += "openglvaapi"; 205 } 206 return list; 207 } 208 209 MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 210 uint width, uint height, 211 uint stream_type, bool no_acceleration, 212 PixelFormat &pix_fmt) 213 { 214 QSize size(width, height); 215 bool use_cpu = no_acceleration; 216 VideoDisplayProfile vdp; 217 vdp.SetInput(size); 218 QString dec = vdp.GetDecoder(); 219 220 MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1)); 221 use_cpu |= !codec_is_vaapi(test_cid); 222 use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt); 223 if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu) 224 return (MythCodecID)(kCodec_MPEG1 + (stream_type-1)); 225 226 return test_cid; 227 } -
libs/libmythtv/libmythtv.pro
344 344 345 345 using_glx_proc_addr_arb:DEFINES += USING_GLX_PROC_ADDR_ARB 346 346 347 using_vaapi: DEFINES += USING_VAAPI 348 using_vaapi: DEFINES += videoout_openglvaapi.h vaapicontext.h 349 using_vaapi: SOURCES += videoout_openglvaapi.cpp vaapicontext.cpp 350 using_vaapi: LIBS += -lva -lva-glx 351 347 352 # Misc. frontend 348 353 HEADERS += DetectLetterbox.h 349 354 SOURCES += DetectLetterbox.cpp -
libs/libmythtv/vaapicontext.cpp
1 #include <QHash> 2 3 #include "mythverbose.h" 4 #include "mythxdisplay.h" 5 #include "mythcodecid.h" 6 #include "vaapicontext.h" 7 8 #define LOC QString("VAAPI: ") 9 #define LOC_ERR QString("VAAPI Error: ") 10 #define NUM_VAAPI_BUFFERS 40 11 12 #define INIT_ST \ 13 VAStatus va_status; \ 14 bool ok = true; 15 16 #define CHECK_ST \ 17 ok &= (va_status == VA_STATUS_SUCCESS); \ 18 if (!ok) { \ 19 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Error at %1:%2 (#%3, %4)") \ 20 .arg(__FILE__).arg( __LINE__).arg(va_status) \ 21 .arg(vaErrorStr(va_status))); \ 22 } 23 24 #define CREATE_CHECK(arg1, arg2) \ 25 if (ok) \ 26 { \ 27 ok = arg1; \ 28 if (!ok) \ 29 VERBOSE(VB_IMPORTANT, LOC_ERR + arg2); \ 30 } 31 32 QString profileToString(VAProfile profile) 33 { 34 if (VAProfileMPEG2Simple == profile) return "MPEG2Simple"; 35 if (VAProfileMPEG2Main == profile) return "MPEG2Main"; 36 if (VAProfileMPEG4Simple == profile) return "MPEG4Simple"; 37 if (VAProfileMPEG4AdvancedSimple == profile) return "MPEG4AdvSimple"; 38 if (VAProfileMPEG4Main == profile) return "MPEG4Main"; 39 if (VAProfileH264Baseline == profile) return "H264Base"; 40 if (VAProfileH264Main == profile) return "H264Main"; 41 if (VAProfileH264High == profile) return "H264High"; 42 if (VAProfileVC1Simple == profile) return "VC1Simple"; 43 if (VAProfileVC1Main == profile) return "VC1Main"; 44 if (VAProfileVC1Advanced == profile) return "VC1Advanced"; 45 if (VAProfileH263Baseline == profile) return "H263Base"; 46 return "Unknown"; 47 } 48 49 QString entryToString(VAEntrypoint entry) 50 { 51 if (VAEntrypointVLD == entry) return "VLD "; 52 if (VAEntrypointIZZ == entry) return "IZZ (UNSUPPORTED) "; 53 if (VAEntrypointIDCT == entry) return "IDCT (UNSUPPORTED) "; 54 if (VAEntrypointMoComp == entry) return "MC (UNSUPPORTED) "; 55 if (VAEntrypointDeblocking == entry) return "Deblock (UNSUPPORTED) "; 56 if (VAEntrypointEncSlice == entry) return "EncSlice (UNSUPPORTED) "; 57 return "Unknown"; 58 } 59 60 VAProfile preferredProfile(MythCodecID codec) 61 { 62 // FIXME handle unsupported codecs properly 63 if (kCodec_H263_VAAPI == codec) return VAProfileMPEG4AdvancedSimple; 64 if (kCodec_MPEG4_VAAPI == codec) return VAProfileMPEG4AdvancedSimple; 65 if (kCodec_H264_VAAPI == codec) return VAProfileH264High; 66 if (kCodec_VC1_VAAPI == codec) return VAProfileVC1Advanced; 67 if (kCodec_WMV3_VAAPI == codec) return VAProfileVC1Main; 68 return VAProfileMPEG2Main; 69 } 70 71 class VAAPIDisplay 72 { 73 public: 74 VAAPIDisplay() : m_va_disp(NULL), m_x_disp(NULL), m_ref_count(0) { } 75 ~VAAPIDisplay() 76 { 77 if (m_va_disp) 78 { 79 INIT_ST 80 XLOCK(m_x_disp, va_status = vaTerminate(m_va_disp)); 81 CHECK_ST 82 } 83 if (m_x_disp) 84 { 85 m_x_disp->Sync(true); 86 delete m_x_disp; 87 } 88 } 89 90 bool Create(void) 91 { 92 m_x_disp = OpenMythXDisplay(); 93 if (!m_x_disp) 94 return false; 95 96 MythXLocker locker(m_x_disp); 97 int major_ver, minor_ver; 98 m_va_disp = vaGetDisplayGLX(m_x_disp->GetDisplay()); 99 INIT_ST 100 va_status = vaInitialize(m_va_disp, &major_ver, &minor_ver); 101 CHECK_ST 102 103 static bool debugged = false; 104 if (ok && !debugged) 105 { 106 debugged = true; 107 VERBOSE(VB_IMPORTANT, LOC + QString("Version: %1.%2") 108 .arg(major_ver).arg(minor_ver)); 109 VERBOSE(VB_IMPORTANT, LOC + QString("Vendor : %1") 110 .arg(vaQueryVendorString(m_va_disp))); 111 } 112 if (ok) 113 UpRef(); 114 return ok; 115 } 116 117 void UpRef(void) 118 { 119 XLOCK(m_x_disp, m_ref_count++) 120 } 121 122 void DownRef(void) 123 { 124 m_x_disp->Lock(); 125 m_ref_count--; 126 if (m_ref_count <= 0) 127 { 128 if (gVAAPIDisplay == this) 129 gVAAPIDisplay = NULL; 130 m_x_disp->Unlock(); 131 delete this; 132 return; 133 } 134 m_x_disp->Unlock(); 135 } 136 137 static VAAPIDisplay* GetDisplay(void) 138 { 139 if (gVAAPIDisplay) 140 { 141 gVAAPIDisplay->UpRef(); 142 return gVAAPIDisplay; 143 } 144 145 gVAAPIDisplay = new VAAPIDisplay(); 146 if (gVAAPIDisplay && gVAAPIDisplay->Create()) 147 return gVAAPIDisplay; 148 149 delete gVAAPIDisplay; 150 gVAAPIDisplay = NULL; 151 return NULL; 152 } 153 154 static VAAPIDisplay *gVAAPIDisplay; 155 void *m_va_disp; 156 MythXDisplay *m_x_disp; 157 int m_ref_count; 158 }; 159 160 VAAPIDisplay* VAAPIDisplay::gVAAPIDisplay = NULL; 161 162 bool VAAPIContext::IsFormatAccelerated(QSize size, MythCodecID codec, 163 PixelFormat &pix_fmt) 164 { 165 bool result = false; 166 VAAPIContext *ctx = new VAAPIContext(codec); 167 if (ctx) 168 { 169 result = ctx->CreateDisplay(size); 170 pix_fmt = ctx->GetPixelFormat(); 171 } 172 delete ctx; 173 return result; 174 } 175 176 VAAPIContext::VAAPIContext(MythCodecID codec) 177 : m_codec(codec), 178 m_vaProfile(VAProfileMPEG2Main)/* ?? */, 179 m_vaEntrypoint(VAEntrypointEncSlice), 180 m_pix_fmt(PIX_FMT_YUV420P), m_numSurfaces(NUM_VAAPI_BUFFERS), 181 m_surfaces(NULL), m_surfaceData(NULL) 182 { 183 memset(&m_ctx, 0, sizeof(vaapi_context)); 184 } 185 186 VAAPIContext::~VAAPIContext() 187 { 188 ClearGLXSurfaces(); 189 190 if (m_display) 191 m_display->m_x_disp->Lock(); 192 193 INIT_ST 194 if (m_ctx.context_id) 195 { 196 va_status = vaDestroyContext(m_ctx.display, m_ctx.context_id); 197 CHECK_ST 198 } 199 if (m_ctx.config_id) 200 { 201 va_status = vaDestroyConfig(m_ctx.display, m_ctx.config_id); 202 CHECK_ST 203 } 204 if (m_surfaces) 205 { 206 va_status = vaDestroySurfaces(m_ctx.display, m_surfaces, m_numSurfaces); 207 CHECK_ST 208 } 209 210 if (m_surfaces) 211 delete [] m_surfaces; 212 if (m_surfaceData) 213 delete [] m_surfaceData; 214 215 if (m_display) 216 { 217 m_display->m_x_disp->Unlock(); 218 m_display->DownRef(); 219 } 220 221 VERBOSE(VB_PLAYBACK, LOC + "Deleted context"); 222 } 223 224 bool VAAPIContext::CreateDisplay(QSize size)\ 225 { 226 m_size = size; 227 bool ok = true; 228 m_display = VAAPIDisplay::GetDisplay(); 229 CREATE_CHECK(!m_size.isEmpty(), "Invalid size") 230 CREATE_CHECK(m_display != NULL, "Invalid display") 231 CREATE_CHECK(InitDisplay(), "Invalid VADisplay") 232 CREATE_CHECK(InitProfiles(), "No supported profiles") 233 if (ok) 234 VERBOSE(VB_PLAYBACK, LOC + QString("Created ctx display (%1x%2->%3x%4)") 235 .arg(size.width()).arg(size.height()) 236 .arg(m_size.width()).arg(m_size.height())); 237 return ok; 238 } 239 240 bool VAAPIContext::CreateBuffers(void) 241 { 242 bool ok = true; 243 CREATE_CHECK(!m_size.isEmpty(), "Invalid size") 244 CREATE_CHECK(InitBuffers(), "Failed to create buffers.") 245 CREATE_CHECK(InitContext(), "Failed to create context") 246 if (ok) 247 VERBOSE(VB_PLAYBACK, LOC + "Created buffers"); 248 return ok; 249 } 250 251 bool VAAPIContext::InitDisplay(void) 252 { 253 if (!m_display) 254 return false; 255 m_ctx.display = m_display->m_va_disp; 256 return m_ctx.display; 257 } 258 259 bool VAAPIContext::InitProfiles(void) 260 { 261 if (!(codec_is_vaapi(m_codec)) || !m_ctx.display) 262 return false; 263 264 MythXLocker locker(m_display->m_x_disp); 265 int max_profiles, max_entrypoints; 266 VAProfile profile_wanted = preferredProfile(m_codec); 267 VAProfile profile_found = VAProfileMPEG2Main; // FIXME 268 VAEntrypoint entry_found = VAEntrypointEncSlice; // unsupported value 269 270 max_profiles = vaMaxNumProfiles(m_ctx.display); 271 max_entrypoints = vaMaxNumEntrypoints(m_ctx.display); 272 VAProfile *profiles = new VAProfile[max_profiles]; 273 VAEntrypoint *entries = new VAEntrypoint[max_entrypoints]; 274 275 static bool debugged = false; 276 if (profiles && entries) 277 { 278 INIT_ST 279 int act_profiles, act_entries; 280 va_status = vaQueryConfigProfiles(m_ctx.display, 281 profiles, 282 &act_profiles); 283 CHECK_ST 284 if (ok && act_profiles > 0) 285 { 286 for (int i = 0; i < act_profiles; i++) 287 { 288 va_status = vaQueryConfigEntrypoints(m_ctx.display, 289 profiles[i], 290 entries, 291 &act_entries); 292 if (va_status == VA_STATUS_SUCCESS && act_entries > 0) 293 { 294 if (profiles[i] == profile_wanted) 295 { 296 profile_found = profile_wanted; 297 for (int j = 0; j < act_entries; j++) 298 if (entries[j] < entry_found) 299 entry_found = entries[j]; 300 } 301 302 if (!debugged) 303 { 304 QString entrylist = "Entrypoints: "; 305 for (int j = 0; j < act_entries; j++) 306 entrylist += entryToString(entries[j]); 307 VERBOSE(VB_IMPORTANT, LOC + QString("Profile: %1 %2") 308 .arg(profileToString(profiles[i])).arg(entrylist)); 309 } 310 } 311 } 312 } 313 debugged = true; 314 } 315 delete profiles; 316 delete entries; 317 318 VERBOSE(VB_PLAYBACK, LOC + QString("Desired profile for '%1': %2") 319 .arg(toString(m_codec)).arg(profileToString(profile_wanted))); 320 VERBOSE(VB_PLAYBACK, LOC + QString("Found profile %1 with entry %2") 321 .arg(profileToString(profile_found)).arg(entryToString(entry_found))); 322 323 if (profile_wanted != profile_found) 324 { 325 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find supported profile."); 326 return false; 327 } 328 329 if (entry_found > VAEntrypointVLD) 330 { 331 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find suitable entry point."); 332 return false; 333 } 334 335 m_vaProfile = profile_wanted; 336 m_vaEntrypoint = entry_found; 337 if (VAEntrypointVLD == m_vaEntrypoint) 338 m_pix_fmt = PIX_FMT_VAAPI_VLD; 339 return true; 340 } 341 342 bool VAAPIContext::InitBuffers(void) 343 { 344 if (!m_ctx.display) 345 return false; 346 347 MythXLocker locker(m_display->m_x_disp); 348 m_surfaces = new VASurfaceID[m_numSurfaces]; 349 m_surfaceData = new vaapi_surface[m_numSurfaces]; 350 351 if (!m_surfaces || !m_surfaceData) 352 return false; 353 354 INIT_ST 355 va_status = vaCreateSurfaces(m_ctx.display, m_size.width(), m_size.height(), 356 VA_RT_FORMAT_YUV420, m_numSurfaces, 357 m_surfaces); 358 CHECK_ST 359 360 for (int i = 0; i < m_numSurfaces; i++) 361 m_surfaceData[i].m_id = m_surfaces[i]; 362 return ok; 363 } 364 365 bool VAAPIContext::InitContext(void) 366 { 367 if (!m_ctx.display || m_vaEntrypoint > VAEntrypointVLD) 368 return false; 369 370 MythXLocker locker(m_display->m_x_disp); 371 VAConfigAttrib attrib; 372 attrib.type = VAConfigAttribRTFormat; 373 INIT_ST 374 va_status = vaGetConfigAttributes(m_ctx.display, m_vaProfile, 375 m_vaEntrypoint, &attrib, 1); 376 CHECK_ST 377 378 if (!ok || !(attrib.value & VA_RT_FORMAT_YUV420)) 379 { 380 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to confirm YUV420 chroma"); 381 return false; 382 } 383 384 va_status = vaCreateConfig(m_ctx.display, m_vaProfile, m_vaEntrypoint, 385 &attrib, 1, &m_ctx.config_id); 386 CHECK_ST 387 if (!ok) 388 { 389 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder config."); 390 return false; 391 } 392 393 va_status = vaCreateContext(m_ctx.display, m_ctx.config_id, 394 m_size.width(), m_size.height(), VA_PROGRESSIVE, 395 m_surfaces, m_numSurfaces, 396 &m_ctx.context_id); 397 CHECK_ST 398 if (!ok) 399 { 400 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder context."); 401 return false; 402 } 403 return true; 404 } 405 406 void* VAAPIContext::GetVideoSurface(int i) 407 { 408 if (i < 0 || i >= m_numSurfaces) 409 return NULL; 410 return &m_surfaceData[i]; 411 } 412 413 uint8_t* VAAPIContext::GetSurfaceIDPointer(void* buf) 414 { 415 if (!buf) 416 return NULL; 417 const vaapi_surface *surf = (vaapi_surface*)buf; 418 // VASurfaceStatus status; 419 // INIT_ST 420 // va_status = vaQuerySurfaceStatus(m_ctx.display, surf->m_id, &status); 421 // CHECK_ST 422 // VERBOSE(VB_IMPORTANT, LOC + QString("Returning VASurfaceID: %1 status %2").arg(surf->m_id).arg(status)); 423 // va_status = vaSyncSurface(m_ctx.display, surf->m_id); 424 // CHECK_ST 425 return (uint8_t*)(uintptr_t)surf->m_id; 426 } 427 428 bool VAAPIContext::CopySurfaceToTexture(const void* buf, uint texture, 429 uint texture_type) 430 { 431 if (!buf || !texture) 432 return false; 433 void* glx_surface = GetGLXSurface(texture, texture_type); 434 if (!glx_surface) 435 return false; 436 const vaapi_surface *surf = (vaapi_surface*)buf; 437 INIT_ST 438 XLOCK(m_display->m_x_disp, 439 va_status = vaCopySurfaceGLX(m_ctx.display, glx_surface, 440 surf->m_id, 0)); 441 CHECK_ST 442 return ok; 443 } 444 445 void* VAAPIContext::GetGLXSurface(uint texture, uint texture_type) 446 { 447 if (m_glxSurfaces.contains(texture)) 448 return m_glxSurfaces.value(texture); 449 450 void *glx_surface = NULL; 451 INIT_ST 452 XLOCK(m_display->m_x_disp, 453 va_status = vaCreateSurfaceGLX(m_ctx.display, texture_type, 454 texture, &glx_surface)); 455 CHECK_ST 456 m_glxSurfaces.insert(texture, glx_surface); 457 458 VERBOSE(VB_PLAYBACK, QString("Number of VAAPI GLX surfaces: %1") 459 .arg(m_glxSurfaces.size())); 460 return glx_surface; 461 } 462 463 void VAAPIContext::ClearGLXSurfaces(void) 464 { 465 if (!m_display) 466 return; 467 468 m_display->m_x_disp->Lock(); 469 INIT_ST 470 foreach (void* surface, m_glxSurfaces) 471 { 472 va_status = vaDestroySurfaceGLX(m_ctx.display, surface); 473 CHECK_ST 474 } 475 m_glxSurfaces.clear(); 476 m_display->m_x_disp->Unlock(); 477 } -
libs/libmythtv/videoout_opengl.h
10 10 { 11 11 public: 12 12 static void GetRenderOptions(render_opts &opts, QStringList &cpudeints); 13 VideoOutputOpenGL( );14 ~VideoOutputOpenGL();13 VideoOutputOpenGL(MythCodecID codec_id); 14 virtual ~VideoOutputOpenGL(); 15 15 16 bool Init(int width, int height, float aspect, WId winid, 17 int winx, int winy, int winw, int winh, WId embedid = 0); 18 void TearDown(void); 16 virtual bool Init(int width, int height, float aspect, WId winid, 17 int winx, int winy, int winw, int winh, WId embedid = 0); 18 virtual void SetProfile(void); 19 virtual void TearDown(void); 19 20 20 21 void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd); 21 v oid ProcessFrame(VideoFrame *frame, OSD *osd,22 FilterChain *filterList,23 const PIPMap &pipPlayers,24 FrameScanType scan);25 v oid Show(FrameScanType );26 bool InputChanged(const QSize &input_size, float aspect,27 MythCodecID av_codec_id, void *codec_private,28 bool &aspect_only);22 virtual void ProcessFrame(VideoFrame *frame, OSD *osd, 23 FilterChain *filterList, 24 const PIPMap &pipPlayers, 25 FrameScanType scan); 26 virtual void Show(FrameScanType ); 27 virtual bool InputChanged(const QSize &input_size, float aspect, 28 MythCodecID av_codec_id, void *codec_private, 29 bool &aspect_only); 29 30 DisplayInfo GetDisplayInfo(void); 30 31 void UpdatePauseFrame(void); 31 32 void DrawUnusedRects(bool) { } … … 37 38 const QSize &video_dim); 38 39 void EmbedInWidget(int x, int y, int w, int h); 39 40 void StopEmbedding(void); 40 bool SetDeinterlacingEnabled(bool);41 bool SetupDeinterlace(bool i, const QString& ovrf="");41 virtual bool SetDeinterlacingEnabled(bool); 42 virtual bool SetupDeinterlace(bool i, const QString& ovrf=""); 42 43 void ShowPIP(VideoFrame *frame, 43 44 NuppelVideoPlayer *pipplayer, 44 45 PIPLocation loc); … … 51 52 virtual bool ApproveDeintFilter(const QString& filtername) const; 52 53 virtual MythPainter *GetOSDPainter(void) { return (MythPainter*)gl_painter; } 53 54 54 private: 55 bool CreateBuffers(void); 55 protected: 56 virtual bool CreateBuffers(void); 57 bool CreatePauseFrame(void); 56 58 bool SetupContext(void); 57 59 bool SetupOpenGL(void); 58 60 void InitOSD(void); 59 61 62 MythCodecID gl_codec_id; 60 63 QMutex gl_context_lock; 61 64 MythRenderOpenGL *gl_context; 62 65 OpenGLVideo *gl_videochain; -
libs/libmythtv/openglvideo.h
44 44 QSize videoDim, QRect displayVisibleRect, 45 45 QRect displayVideoRect, QRect videoRect, 46 46 bool viewport_control, QString options, 47 bool hwaccel, 47 48 LetterBoxColour letterbox_colour = kLetterBoxColour_Black); 48 49 50 uint GetInputTexture(void); 51 uint GetTextureType(void); 52 void SetInputUpdated(void); 49 53 void UpdateInputFrame(const VideoFrame *frame, bool soft_bob = false); 50 54 51 55 /// \brief Public interface to AddFilter(OpenGLFilterType filter) … … 124 128 OpenGLFilterType defaultUpsize; 125 129 uint gl_features; 126 130 bool using_ycbcrtex; 131 bool using_hardwaretex; 127 132 LetterBoxColour gl_letterbox_colour; 128 133 }; 129 134 #endif // _OPENGL_VIDEO_H__ -
libs/libmythtv/openglvideo.cpp
84 84 textureRects(false), textureType(GL_TEXTURE_2D), 85 85 helperTexture(0), defaultUpsize(kGLFilterResize), 86 86 gl_features(0), using_ycbcrtex(false), 87 using_hardwaretex(false), 87 88 gl_letterbox_colour(kLetterBoxColour_Black) 88 89 { 89 90 } … … 139 140 QSize videoDim, QRect displayVisibleRect, 140 141 QRect displayVideoRect, QRect videoRect, 141 142 bool viewport_control, QString options, 143 bool hw_accel, 142 144 LetterBoxColour letterbox_colour) 143 145 { 144 146 gl_context = glcontext; … … 175 177 176 178 SetViewPort(display_visible_rect.size()); 177 179 178 bool use_pbo = gl_features & kGLExtPBufObj; 180 using_hardwaretex = hw_accel; 181 bool use_pbo = !using_hardwaretex && (gl_features & kGLExtPBufObj); 179 182 bool basic_features = gl_features & kGLExtFragProg; 180 183 bool full_features = basic_features && (gl_features & kGLExtFBufObj); 181 using_ycbcrtex = ! full_features && (gl_features & kGLYCbCrTex);184 using_ycbcrtex = !using_hardwaretex && !full_features && (gl_features & kGLYCbCrTex); 182 185 183 186 if (using_ycbcrtex) 184 187 basic_features = false; … … 192 195 QString("No OpenGL feature support for Bicubic filter.")); 193 196 } 194 197 195 if ((defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect)) 198 if (!using_hardwaretex && 199 (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect)) 196 200 textureType = gl_context->GetTextureType(textureRects); 197 201 198 202 GLuint tex = 0; 199 203 bool ok = false; 200 204 201 if (basic_features )205 if (basic_features && !using_hardwaretex) 202 206 { 203 207 tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo); 204 208 ok = tex && AddFilter(kGLFilterYUV2RGB); 205 209 } 206 else if (using_ycbcrtex )210 else if (using_ycbcrtex || using_hardwaretex) 207 211 { 208 212 tex = CreateVideoTexture(actual_video_dim, 209 213 inputTextureSize, use_pbo); 210 214 ok = tex && AddFilter(kGLFilterResize); 211 if (ok )215 if (ok && using_ycbcrtex) 212 216 VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for" 213 217 " colorspace conversion.")); 218 else if (ok && using_hardwaretex) 219 VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel.")); 214 220 else 221 { 215 222 using_ycbcrtex = false; 223 using_hardwaretex = false; 224 } 216 225 } 217 226 218 227 if (ok) … … 707 716 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType, 708 717 GL_UNSIGNED_SHORT_8_8_MESA, 709 718 GL_YCBCR_MESA, GL_YCBCR_MESA); 719 else if (using_hardwaretex) 720 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType, 721 GL_UNSIGNED_BYTE, GL_RGBA, 722 GL_RGBA, GL_LINEAR, 723 GL_CLAMP_TO_EDGE); 710 724 else 711 725 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType); 712 726 tex_size = gl_context->GetTextureSize(textureType, size); … … 737 751 return QSize(w, h); 738 752 } 739 753 754 uint OpenGLVideo::GetInputTexture(void) 755 { 756 return inputTextures[0]; 757 } 758 759 uint OpenGLVideo::GetTextureType(void) 760 { 761 return textureType; 762 } 763 764 void OpenGLVideo::SetInputUpdated(void) 765 { 766 inputUpdated = true; 767 } 768 740 769 /** 741 770 * \fn OpenGLVideo::UpdateInputFrame(const VideoFrame *frame, bool soft_bob) 742 771 * Update the current input texture using the data from the given YV12 video -
libs/libmythtv/mythcodecid.h
129 129 #define CODEC_IS_DVDV(codec) (codec && (codec->id == CODEC_ID_MPEG2VIDEO_DVDV)) 130 130 #define CODEC_IS_VDPAU(codec) (codec &&\ 131 131 codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) 132 #define CODEC_IS_HWACCEL(codec) (CODEC_IS_XVMC(codec) ||\ 133 CODEC_IS_VDPAU(codec) ||\ 134 CODEC_IS_DVDV(codec)) 132 #define CODEC_IS_VAAPI(codec, enc) (codec && IS_VAAPI_PIX_FMT(enc->pix_fmt)) 133 #define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_XVMC(codec) ||\ 134 CODEC_IS_VDPAU(codec) ||\ 135 CODEC_IS_DVDV(codec) ||\ 136 CODEC_IS_VAAPI(codec, enc)) 135 137 136 138 #endif // _MYTH_CODEC_ID_H_ -
libs/libmythtv/videooutbase.cpp
40 40 #include "videoout_vdpau.h" 41 41 #endif 42 42 43 #ifdef USING_VAAPI 44 #include "videoout_openglvaapi.h" 45 #endif 46 43 47 #include "videoout_null.h" 44 48 #include "dithertable.h" 45 49 … … 96 100 #ifdef USING_VDPAU 97 101 VideoOutputVDPAU::GetRenderOptions(opts); 98 102 #endif // USING_VDPAU 103 104 #ifdef USING_VAAPI 105 VideoOutputOpenGLVAAPI::GetRenderOptions(opts); 106 #endif // USING_VAAPI 99 107 } 100 108 101 109 /** … … 143 151 renderers += VideoOutputVDPAU::GetAllowedRenderers(codec_id, video_dim); 144 152 #endif // USING_VDPAU 145 153 154 #ifdef USING_VAAPI 155 renderers += VideoOutputOpenGLVAAPI::GetAllowedRenderers(codec_id, video_dim); 156 #endif // USING_VAAPI 157 146 158 VERBOSE(VB_PLAYBACK, LOC + "Allowed renderers: " + 147 159 to_comma_list(renderers)); 148 160 … … 197 209 198 210 #ifdef USING_OPENGL_VIDEO 199 211 if (renderer == "opengl") 200 vo = new VideoOutputOpenGL( );212 vo = new VideoOutputOpenGL(codec_id); 201 213 #endif // USING_OPENGL_VIDEO 202 214 203 215 #ifdef USING_VDPAU … … 205 217 vo = new VideoOutputVDPAU(codec_id); 206 218 #endif // USING_VDPAU 207 219 220 #ifdef USING_VAAPI 221 if (renderer == "openglvaapi") 222 vo = new VideoOutputOpenGLVAAPI(codec_id); 223 #endif // USING_VAAPI 224 208 225 #ifdef USING_XV 209 226 if (xvlist.contains(renderer)) 210 227 vo = new VideoOutputXv(codec_id); … … 378 395 */ 379 396 VideoOutput::~VideoOutput() 380 397 { 398 VERBOSE(VB_IMPORTANT, LOC + "dtor start"); 381 399 if (osd_image) 382 400 osd_image->DownRef(); 383 401 if (osd_painter) … … 397 415 ResizeForGui(); 398 416 if (display_res) 399 417 display_res->Unlock(); 418 VERBOSE(VB_IMPORTANT, LOC + "dtor end"); 400 419 } 401 420 402 421 /** -
libs/libmythtv/vaapicontext.h
1 #ifndef VAAPICONTEXT_H 2 #define VAAPICONTEXT_H 3 4 extern "C" { 5 #include "libavcodec/vaapi.h" 6 } 7 #include "va/va.h" 8 #include "va/va_glx.h" 9 #include <QHash> 10 11 struct vaapi_surface 12 { 13 VASurfaceID m_id; 14 }; 15 class VAAPIDisplay; 16 17 class VAAPIContext 18 { 19 public: 20 static bool IsFormatAccelerated(QSize size, MythCodecID codec, 21 PixelFormat &pix_fmt); 22 VAAPIContext(MythCodecID codec); 23 ~VAAPIContext(); 24 25 bool CreateDisplay(QSize size); 26 bool CreateBuffers(void); 27 void* GetVideoSurface(int i); 28 uint8_t* GetSurfaceIDPointer(void* buf); 29 30 int GetNumBuffers(void) { return m_numSurfaces; } 31 PixelFormat GetPixelFormat(void) { return m_pix_fmt; } 32 33 bool CopySurfaceToTexture(const void* buf, uint texture, uint texture_type); 34 void* GetGLXSurface(uint texture, uint texture_type); 35 void ClearGLXSurfaces(void); 36 37 bool InitDisplay(void); 38 bool InitProfiles(void); 39 bool InitBuffers(void); 40 bool InitContext(void); 41 42 vaapi_context m_ctx; 43 MythCodecID m_codec; 44 QSize m_size; 45 VAAPIDisplay *m_display; 46 VAProfile m_vaProfile; 47 VAEntrypoint m_vaEntrypoint; 48 PixelFormat m_pix_fmt; 49 int m_numSurfaces; 50 VASurfaceID *m_surfaces; 51 vaapi_surface *m_surfaceData; 52 QHash<uint, void*> m_glxSurfaces; 53 }; 54 55 #endif // VAAPICONTEXT_H -
libs/libavutil/internal.h
242 242 #define log2f(x) log2(x) 243 243 #endif /* HAVE_LOG2F */ 244 244 245 #if !HAVE_LRINT246 static av_always_inline av_const long int lrint(double x)247 {248 return rint(x);249 }250 #endif /* HAVE_LRINT */251 252 245 #if !HAVE_LRINTF 253 246 static av_always_inline av_const long int lrintf(float x) 254 247 { … … 256 249 } 257 250 #endif /* HAVE_LRINTF */ 258 251 259 #if !HAVE_ROUND260 static av_always_inline av_const double round(double x)261 {262 return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);263 }264 #endif /* HAVE_ROUND */265 266 252 #if !HAVE_ROUNDF 267 253 static av_always_inline av_const float roundf(float x) 268 254 {