Ticket #8593: vaapi_v118_aka_sticking_needles_in_your_eyes.diff
| File vaapi_v118_aka_sticking_needles_in_your_eyes.diff, 51.7 KB (added by markk, 21 months ago) |
|---|
-
home/mark/trunk/mythtv/configure
125 125 --enable-xvmc-vld enable XvMC VLD accel. for the Unichrome (Pro) chipset 126 126 --xvmc-lib=LIB XvMC library override (for crosscompiling) 127 127 --enable-vdpau enable NVidia VDPAU hardware acceleration. 128 --enable-vaapi enable VAAPI hardware acceleration 128 129 --enable-crystalhd enable Broadcom CrystalHD hardware decoder support 129 130 --disable-opengl-video disable OpenGL based video display 130 131 --disable-quartz-video disable Mac OS X CoreVideo based video display … … 1358 1359 mythtranscode 1359 1360 opengl 1360 1361 vdpau 1362 vaapi 1361 1363 ' 1362 1364 1363 1365 CMDLINE_SELECT=" … … 1720 1722 xvmc_deps="xv X11_extensions_XvMClib_h" 1721 1723 xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h" 1722 1724 xvmcw_deps="xvmc" 1725 vaapi_deps="x11 opengl" 1723 1726 1724 1727 <<BLOCKQUOTE 1725 1728 # tests … … 3566 3569 check_header termios.h 3567 3570 check_header vdpau/vdpau.h 3568 3571 check_header vdpau/vdpau_x11.h 3572 check_header va/va.h 3573 check_header va/va_x11.h 3574 check_header va/va_glx.h 3569 3575 check_header X11/extensions/XvMClib.h 3570 3576 3571 3577 check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex … … 3844 3850 disable crystalhd; 3845 3851 fi 3846 3852 3853 if enabled vaapi; then 3854 enabled va_va_h && enabled va_va_glx_h && enabled va_va_x11_h || disable vaapi 3855 if enabled vaapi; then 3856 # TODO check for SDS versions 3857 check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" || 3858 { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; } 3859 fi 3860 else 3861 disable vaapi 3862 fi 3863 3847 3864 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" 3848 3865 enabled debug && add_cxxflags -g"$debuglevel" 3849 3866 … … 4405 4422 echo "XvMC libs $VENDOR_XVMC_LIBS" 4406 4423 fi 4407 4424 echo "VDPAU support ${vdpau-no}" 4425 echo "VAAPI support ${vaapi-no}" 4408 4426 echo "CrystalHD support ${crystalhd-no}" 4409 4427 fi 4410 4428 echo "OpenGL video ${opengl_video-no}" -
home/mark/trunk/mythtv/external/FFmpeg/libavutil/libm.h
59 59 #endif /* HAVE_LOG2F */ 60 60 61 61 #if !HAVE_LRINT 62 static av_always_inline av_const long int lrint(double x)63 {64 return rint(x);65 }62 //static av_always_inline av_const long int lrint(double x) 63 //{ 64 // return rint(x); 65 // } 66 66 #endif /* HAVE_LRINT */ 67 67 68 68 #if !HAVE_LRINTF … … 73 73 #endif /* HAVE_LRINTF */ 74 74 75 75 #if !HAVE_ROUND 76 static av_always_inline av_const double round(double x)77 {78 return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);79 }76 //static av_always_inline av_const double round(double x) 77 //{ 78 // return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); 79 //} 80 80 #endif /* HAVE_ROUND */ 81 81 82 82 #if !HAVE_ROUNDF -
home/mark/trunk/mythtv/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(bool direct_update = false); 13 ~VideoOutputOpenGLVAAPI(); 14 15 bool Init(int width, int height, float aspect, WId winid, 16 int winx, int winy, int winw, int winh, 17 MythCodecID codec_id, WId embedid = 0); 18 bool CreateVAAPIContext(QSize size); 19 void DeleteVAAPIContext(void); 20 bool CreateBuffers(void); 21 void* GetVAAPIContext(void); 22 uint8_t* GetSurfaceIDPointer(void* buf); 23 void SetProfile(void); 24 void TearDown(void); 25 bool InputChanged(const QSize &input_size, float aspect, 26 MythCodecID av_codec_id, void *codec_private, 27 bool &aspect_only); 28 void ProcessFrame(VideoFrame *frame, OSD *osd, 29 FilterChain *filterList, 30 const PIPMap &pipPlayers, 31 FrameScanType scan); 32 bool ApproveDeintFilter(const QString& filtername) const; 33 bool SetDeinterlacingEnabled(bool enable); 34 bool SetupDeinterlace(bool i, const QString& ovrf=""); 35 36 static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, 37 const QSize &video_dim); 38 static MythCodecID GetBestSupportedCodec(uint width, uint height, 39 uint stream_type, 40 bool no_acceleration, 41 PixelFormat &pix_fmt); 42 43 private: 44 VAAPIContext *m_ctx; 45 }; 46 47 #endif // VIDEOOUTPUTOPENGLVAAPI_H 48 -
home/mark/trunk/mythtv/libs/libmythtv/videoout_opengl.cpp
39 39 opts.priorities->insert("opengl", 65); 40 40 } 41 41 42 VideoOutputOpenGL::VideoOutputOpenGL( )42 VideoOutputOpenGL::VideoOutputOpenGL(bool direct_update) 43 43 : VideoOutput(), 44 44 gl_context_lock(QMutex::Recursive), 45 45 gl_context(NULL), gl_videochain(NULL), gl_pipchain_active(NULL), 46 gl_parent_win(0), gl_embed_win(0), gl_painter(NULL) 46 gl_parent_win(0), gl_embed_win(0), gl_painter(NULL), 47 gl_direct_update(direct_update) 47 48 { 48 49 bzero(&av_pause_frame, sizeof(av_pause_frame)); 49 50 av_pause_frame.buf = NULL; … … 246 247 OpenGLLocker ctx_lock(gl_context); 247 248 gl_videochain = new OpenGLVideo(); 248 249 success = gl_videochain->Init(gl_context, db_use_picture_controls, 249 window.Get VideoDim(), dvr,250 window.GetActualVideoDim(), dvr, 250 251 window.GetDisplayVideoRect(), 251 252 window.GetVideoRect(), true, 252 GetFilters(), !codec_is_std(video_codec_id),253 GetFilters(), gl_direct_update, 253 254 db_letterbox_colour); 254 255 if (success) 255 256 { -
home/mark/trunk/mythtv/libs/libmythtv/avformatdecoder.cpp
52 52 } 53 53 #endif // USING_VDPAU 54 54 55 #ifdef USING_VAAPI 56 #include "videoout_openglvaapi.h" 57 #endif // USING_VAAPI 58 55 59 extern "C" { 56 60 #include "libavutil/avutil.h" 57 61 #include "libavcodec/ac3_parser.h" … … 126 130 void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src, 127 131 int offset[4], int y, int type, int height); 128 132 133 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic); 134 129 135 static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id) 130 136 { 131 137 AVCodec *codec = c; … … 238 244 (*opts.equiv_decoders)["vdpau"].append("dummy"); 239 245 #endif 240 246 247 #ifdef USING_VAAPI 248 opts.decoders->append("vaapi"); 249 (*opts.equiv_decoders)["vaapi"].append("dummy"); 250 #endif 251 241 252 PrivateDecoder::GetDecoders(opts); 242 253 } 243 254 … … 1256 1267 enc->draw_horiz_band = render_slice_vdpau; 1257 1268 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1258 1269 } 1270 else if (CODEC_IS_VAAPI(codec, enc)) 1271 { 1272 enc->get_buffer = get_avf_buffer_vaapi; 1273 enc->get_format = get_format_vaapi; 1274 enc->release_buffer = release_avf_buffer; 1275 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1276 } 1259 1277 else if (codec && codec->capabilities & CODEC_CAP_DR1) 1260 1278 { 1261 1279 enc->flags |= CODEC_FLAG_EMU_EDGE; … … 1801 1819 handled = true; 1802 1820 } 1803 1821 #endif // USING_VDPAU 1822 #ifdef USING_VAAPI 1823 MythCodecID vaapi_mcid; 1824 PixelFormat pix_fmt = PIX_FMT_YUV420P; 1825 vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 1826 width, height, mpeg_version(enc->codec_id), 1827 no_hardware_decoders, pix_fmt); 1828 1829 if (vaapi_mcid >= video_codec_id) 1830 { 1831 enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid); 1832 video_codec_id = vaapi_mcid; 1833 handled = true; 1834 if (!no_hardware_decoders && 1835 codec_is_vaapi(video_codec_id)) 1836 { 1837 enc->pix_fmt = pix_fmt; 1838 } 1839 } 1840 #endif // USING_VAAPI 1804 1841 #ifdef USING_XVMC 1805 1842 1806 1843 bool force_xv = no_hardware_decoders; … … 2515 2552 } 2516 2553 } 2517 2554 2555 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic) 2556 { 2557 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 2558 VideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame(false); 2559 2560 pic->data[0] = frame->buf; 2561 pic->data[1] = NULL; 2562 pic->data[2] = NULL; 2563 pic->data[3] = NULL; 2564 pic->linesize[0] = 0; 2565 pic->linesize[1] = 0; 2566 pic->linesize[2] = 0; 2567 pic->linesize[3] = 0; 2568 pic->opaque = frame; 2569 pic->type = FF_BUFFER_TYPE_USER; 2570 pic->age = 256 * 256 * 256 * 64; 2571 frame->pix_fmt = c->pix_fmt; 2572 2573 #ifdef USING_VAAPI 2574 if (nd->GetPlayer()->getVideoOutput()) 2575 { 2576 VideoOutputOpenGLVAAPI *vo = 2577 dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetPlayer()->getVideoOutput()); 2578 c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext(); 2579 pic->data[3] = vo->GetSurfaceIDPointer(frame->buf); 2580 } 2581 #endif 2582 2583 return 0; 2584 } 2585 2518 2586 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len) 2519 2587 { 2520 2588 if (!len) -
home/mark/trunk/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
1 #include "videoout_openglvaapi.h" 2 3 #define LOC QString("VidOutGLVAAPI: ") 4 #define ERR QString("VidOutGLVAAPI Error: ") 5 6 void VideoOutputOpenGLVAAPI::GetRenderOptions(render_opts &opts) 7 { 8 opts.renderers->append("openglvaapi"); 9 opts.renderers->append("openglvaapiglx"); 10 11 (*opts.deints)["openglvaapi"].append("vaapionefield"); 12 (*opts.deints)["openglvaapi"].append("vaapibobdeint"); 13 (*opts.deints)["openglvaapi"].append("none"); 14 (*opts.osds)["openglvaapi"].append("opengl2"); 15 16 (*opts.deints)["openglvaapiglx"].append("vaapionefield"); 17 (*opts.deints)["openglvaapiglx"].append("vaapibobdeint"); 18 (*opts.deints)["openglvaapiglx"].append("none"); 19 (*opts.osds)["openglvaapiglx"].append("opengl2"); 20 21 if (opts.decoders->contains("vaapi")) 22 { 23 (*opts.safe_renderers)["vaapi"].append("openglvaapi"); 24 (*opts.safe_renderers)["vaapi"].append("openglvaapiglx"); 25 } 26 if (opts.decoders->contains("ffmpeg")) 27 { 28 (*opts.safe_renderers)["ffmpeg"].append("openglvaapi"); 29 (*opts.safe_renderers)["ffmpeg"].append("openglvaapiglx"); 30 } 31 if (opts.decoders->contains("libmpeg2")) 32 { 33 (*opts.safe_renderers)["libmpeg2"].append("openglvaapi"); 34 (*opts.safe_renderers)["libmpeg2"].append("openglvaapiglx"); 35 } 36 37 (*opts.safe_renderers)["dummy"].append("openglvaapi"); 38 (*opts.safe_renderers)["nuppel"].append("openglvaapi"); 39 (*opts.safe_renderers)["dummy"].append("openglvaapiglx"); 40 (*opts.safe_renderers)["nuppel"].append("openglvaapiglx"); 41 42 opts.priorities->insert("openglvaapi", 100); 43 opts.priorities->insert("openglvaapiglx", 110); 44 } 45 46 VideoOutputOpenGLVAAPI::VideoOutputOpenGLVAAPI(bool direct_update) 47 : VideoOutputOpenGL(direct_update), m_ctx(NULL) 48 { 49 if (gCoreContext->GetNumSetting("UseVideoModes", 0)) 50 display_res = DisplayRes::GetDisplayRes(true); 51 } 52 53 VideoOutputOpenGLVAAPI::~VideoOutputOpenGLVAAPI() 54 { 55 TearDown(); 56 } 57 58 void VideoOutputOpenGLVAAPI::TearDown(void) 59 { 60 DeleteVAAPIContext(); 61 } 62 63 bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &input_size, float aspect, 64 MythCodecID av_codec_id, void *codec_private, 65 bool &aspect_only) 66 { 67 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5") 68 .arg(input_size.width()).arg(input_size.height()).arg(aspect) 69 .arg(toString(video_codec_id)).arg(toString(av_codec_id))); 70 71 if (!codec_is_vaapi(av_codec_id)) 72 return VideoOutputOpenGL::InputChanged(input_size, aspect, av_codec_id, 73 codec_private, aspect_only); 74 75 QMutexLocker locker(&gl_context_lock); 76 bool cid_changed = (video_codec_id != av_codec_id); 77 bool res_changed = input_size != window.GetActualVideoDim(); 78 bool asp_changed = aspect != window.GetVideoAspect(); 79 80 if (!res_changed && !cid_changed) 81 { 82 if (asp_changed) 83 { 84 aspect_only = true; 85 VideoAspectRatioChanged(aspect); 86 MoveResize(); 87 } 88 return true; 89 } 90 91 TearDown(); 92 QRect disp = window.GetDisplayVisibleRect(); 93 if (Init(input_size.width(), input_size.height(), 94 aspect, gl_parent_win, disp.left(), disp.top(), 95 disp.width(), disp.height(), av_codec_id, gl_embed_win)) 96 { 97 BestDeint(); 98 return true; 99 } 100 101 VERBOSE(VB_IMPORTANT, ERR + QString("Failed to re-initialise video output.")); 102 errorState = kError_Unknown; 103 104 return false; 105 } 106 107 bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect, 108 WId winid, int winx, int winy, int winw, 109 int winh, MythCodecID codec_id, WId embedid) 110 { 111 if (codec_is_vaapi(codec_id)) 112 { 113 video_codec_id = codec_id; 114 if (!CreateVAAPIContext(QSize(width, height))) 115 return false; 116 } 117 118 return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy, 119 winw, winh, video_codec_id, embedid); 120 } 121 122 bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size) 123 { 124 if (m_ctx) 125 DeleteVAAPIContext(); 126 m_ctx = new VAAPIContext(video_codec_id, gl_direct_update); 127 if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers()) 128 return true; 129 VERBOSE(VB_IMPORTANT, ERR + QString("Failed to create VAAPI context.")); 130 errorState = kError_Unknown; 131 return false; 132 } 133 134 void VideoOutputOpenGLVAAPI::DeleteVAAPIContext(void) 135 { 136 delete m_ctx; 137 m_ctx = NULL; 138 } 139 140 bool VideoOutputOpenGLVAAPI::CreateBuffers(void) 141 { 142 if ((!codec_is_vaapi(video_codec_id)) || !m_ctx) 143 return VideoOutputOpenGL::CreateBuffers(); 144 145 QMutexLocker locker(&gl_context_lock); 146 int num_buffers = m_ctx->GetNumBuffers(); 147 const QSize video_dim = window.GetActualVideoDim(); 148 vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame 149 150 bool ok = true; 151 for (int i = 0; i < num_buffers; i++) 152 { 153 ok &= vbuffers.CreateBuffer(video_dim.width(), 154 video_dim.height(), i, 155 m_ctx->GetVideoSurface(i), FMT_VAAPI); 156 } 157 return ok; 158 } 159 160 void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void) 161 { 162 if (m_ctx) 163 return &m_ctx->m_ctx; 164 return NULL; 165 } 166 167 uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf) 168 { 169 if (m_ctx) 170 return m_ctx->GetSurfaceIDPointer(buf); 171 return NULL; 172 } 173 174 void VideoOutputOpenGLVAAPI::SetProfile(void) 175 { 176 if (db_vdisp_profile) 177 db_vdisp_profile->SetVideoRenderer("openglvaapi"); 178 } 179 180 bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const 181 { 182 return filtername.contains("vaapi"); 183 } 184 185 bool VideoOutputOpenGLVAAPI::SetDeinterlacingEnabled(bool enable) 186 { 187 m_deinterlacing = enable; 188 SetupDeinterlace(enable); 189 return m_deinterlacing; 190 } 191 192 bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf) 193 { 194 m_deinterlacing = i; 195 return m_deinterlacing; 196 } 197 198 void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd, 199 FilterChain *filterList, 200 const PIPMap &pipPlayers, 201 FrameScanType scan) 202 { 203 VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan); 204 205 QMutexLocker locker(&gl_context_lock); 206 if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain && frame) 207 { 208 bool success = false; 209 if (gl_direct_update) 210 { 211 gl_context->makeCurrent(); 212 uint tex = gl_videochain->GetInputTexture(); 213 gl_context->EnableTextures(tex); 214 success = m_ctx->CopySurfaceToTexture(frame->buf, tex, 215 gl_videochain->GetTextureType(), 216 scan); 217 if (success) 218 gl_videochain->SetInputUpdated(); 219 gl_context->doneCurrent(); 220 } 221 else 222 { 223 gl_context->makeCurrent(); 224 success = m_ctx->FillFrame(frame, gl_videochain); 225 gl_context->doneCurrent(); 226 } 227 if (!success) 228 VERBOSE(VB_PLAYBACK, ERR + "Failed to update video texture."); 229 } 230 } 231 232 QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers( 233 MythCodecID myth_codec_id, const QSize &video_dim) 234 { 235 (void) video_dim; 236 QStringList list; 237 if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) && 238 !getenv("NO_VAAPI")) 239 { 240 list += "openglvaapi"; 241 list += "openglvaapiglx"; 242 } 243 return list; 244 } 245 246 MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 247 uint width, uint height, 248 uint stream_type, bool no_acceleration, 249 PixelFormat &pix_fmt) 250 { 251 static bool debug = true; 252 if (debug) 253 { 254 VERBOSE(VB_IMPORTANT, LOC + "Testing VAAPI codec support"); 255 debug = false; 256 } 257 258 QSize size(width, height); 259 bool use_cpu = no_acceleration; 260 VideoDisplayProfile vdp; 261 vdp.SetInput(size); 262 QString dec = vdp.GetDecoder(); 263 264 MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1)); 265 if (codec_is_vaapi(test_cid)) 266 use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt); 267 else 268 use_cpu = true; 269 270 if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu) 271 return (MythCodecID)(kCodec_MPEG1 + (stream_type-1)); 272 273 return test_cid; 274 } -
home/mark/trunk/mythtv/libs/libmythtv/libmythtv.pro
354 354 using_opengl_video:HEADERS += openglvideo.h videoout_opengl.h 355 355 using_opengl_video:SOURCES += openglvideo.cpp videoout_opengl.cpp 356 356 357 using_vaapi: DEFINES += USING_VAAPI 358 using_vaapi: DEFINES += vaapicontext.h videoout_openglvaapi.h 359 using_vaapi: SOURCES += vaapicontext.cpp videoout_openglvaapi.cpp 360 using_vaapi: LIBS += -lva -lva-x11 -lva-glx 361 357 362 # Misc. frontend 358 363 HEADERS += DetectLetterbox.h 359 364 SOURCES += DetectLetterbox.cpp -
home/mark/trunk/mythtv/libs/libmythtv/vaapicontext.cpp
1 #include "openglvideo.h" 2 #include "mythverbose.h" 3 #include "mythxdisplay.h" 4 #include "mythcodecid.h" 5 #include "frame.h" 6 #include "vaapicontext.h" 7 #include "myth_imgconvert.h" 8 9 #define LOC QString("VAAPI: ") 10 #define ERR QString("VAAPI Error: ") 11 #define NUM_VAAPI_BUFFERS 20 12 13 #ifndef VA_FOURCC_I420 14 #define VA_FOURCC_I420 0x30323449 15 #endif 16 17 #define INIT_ST \ 18 VAStatus va_status; \ 19 bool ok = true; 20 21 #define CHECK_ST \ 22 ok &= (va_status == VA_STATUS_SUCCESS); \ 23 if (!ok) { \ 24 VERBOSE(VB_IMPORTANT, ERR + QString("Error at %1:%2 (#%3, %4)") \ 25 .arg(__FILE__).arg( __LINE__).arg(va_status) \ 26 .arg(vaErrorStr(va_status))); \ 27 } 28 29 #define CREATE_CHECK(arg1, arg2) \ 30 if (ok) \ 31 { \ 32 ok = arg1; \ 33 if (!ok) \ 34 VERBOSE(VB_IMPORTANT, ERR + arg2); \ 35 } 36 37 QString profileToString(VAProfile profile); 38 QString entryToString(VAEntrypoint entry); 39 VAProfile preferredProfile(MythCodecID codec); 40 41 QString profileToString(VAProfile profile) 42 { 43 if (VAProfileMPEG2Simple == profile) return "MPEG2Simple"; 44 if (VAProfileMPEG2Main == profile) return "MPEG2Main"; 45 if (VAProfileMPEG4Simple == profile) return "MPEG4Simple"; 46 if (VAProfileMPEG4AdvancedSimple == profile) return "MPEG4AdvSimple"; 47 if (VAProfileMPEG4Main == profile) return "MPEG4Main"; 48 if (VAProfileH264Baseline == profile) return "H264Base"; 49 if (VAProfileH264Main == profile) return "H264Main"; 50 if (VAProfileH264High == profile) return "H264High"; 51 if (VAProfileVC1Simple == profile) return "VC1Simple"; 52 if (VAProfileVC1Main == profile) return "VC1Main"; 53 if (VAProfileVC1Advanced == profile) return "VC1Advanced"; 54 if (VAProfileH263Baseline == profile) return "H263Base"; 55 return "Unknown"; 56 } 57 58 QString entryToString(VAEntrypoint entry) 59 { 60 if (VAEntrypointVLD == entry) return "VLD "; 61 if (VAEntrypointIZZ == entry) return "IZZ (UNSUPPORTED) "; 62 if (VAEntrypointIDCT == entry) return "IDCT (UNSUPPORTED) "; 63 if (VAEntrypointMoComp == entry) return "MC (UNSUPPORTED) "; 64 if (VAEntrypointDeblocking == entry) return "Deblock (UNSUPPORTED) "; 65 if (VAEntrypointEncSlice == entry) return "EncSlice (UNSUPPORTED) "; 66 return "Unknown"; 67 } 68 69 VAProfile preferredProfile(MythCodecID codec) 70 { 71 // FIXME handle unsupported codecs properly 72 if (kCodec_H263_VAAPI == codec) return VAProfileMPEG4AdvancedSimple; 73 if (kCodec_MPEG4_VAAPI == codec) return VAProfileMPEG4AdvancedSimple; 74 if (kCodec_H264_VAAPI == codec) return VAProfileH264High; 75 if (kCodec_VC1_VAAPI == codec) return VAProfileVC1Advanced; 76 if (kCodec_WMV3_VAAPI == codec) return VAProfileVC1Main; 77 return VAProfileMPEG2Main; 78 } 79 80 class VAAPIDisplay 81 { 82 public: 83 VAAPIDisplay() : m_va_disp(NULL), m_x_disp(NULL), m_ref_count(0) { } 84 ~VAAPIDisplay() 85 { 86 if (m_va_disp) 87 { 88 INIT_ST 89 XLOCK(m_x_disp, va_status = vaTerminate(m_va_disp)); 90 CHECK_ST 91 } 92 if (m_x_disp) 93 { 94 m_x_disp->Sync(true); 95 delete m_x_disp; 96 } 97 } 98 99 bool Create(bool use_glx) 100 { 101 m_x_disp = OpenMythXDisplay(); 102 if (!m_x_disp) 103 return false; 104 105 MythXLocker locker(m_x_disp); 106 int major_ver, minor_ver; 107 108 if (use_glx) 109 m_va_disp = vaGetDisplayGLX(m_x_disp->GetDisplay()); 110 else 111 m_va_disp = vaGetDisplay(m_x_disp->GetDisplay()); 112 113 if (!m_va_disp) 114 { 115 VERBOSE(VB_IMPORTANT, ERR + "Failed to create VADisplay"); 116 return false; 117 } 118 119 INIT_ST 120 va_status = vaInitialize(m_va_disp, &major_ver, &minor_ver); 121 CHECK_ST 122 123 static bool debugged = false; 124 if (ok && !debugged) 125 { 126 debugged = true; 127 VERBOSE(VB_IMPORTANT, LOC + QString("Version: %1.%2") 128 .arg(major_ver).arg(minor_ver)); 129 VERBOSE(VB_IMPORTANT, LOC + QString("Vendor : %1") 130 .arg(vaQueryVendorString(m_va_disp))); 131 } 132 if (ok) 133 { 134 UpRef(); 135 VERBOSE(VB_PLAYBACK, LOC + 136 QString("Created VAAPI display (GLX: %1)").arg(use_glx)); 137 } 138 return ok; 139 } 140 141 void UpRef(void) 142 { 143 XLOCK(m_x_disp, m_ref_count++) 144 } 145 146 void DownRef(void) 147 { 148 m_x_disp->Lock(); 149 m_ref_count--; 150 if (m_ref_count <= 0) 151 { 152 if (gVAAPIDisplay == this) 153 gVAAPIDisplay = NULL; 154 VERBOSE(VB_PLAYBACK, LOC + "Deleting VAAPI display."); 155 m_x_disp->Unlock(); 156 delete this; 157 return; 158 } 159 m_x_disp->Unlock(); 160 } 161 162 static VAAPIDisplay* GetDisplay(bool use_glx) 163 { 164 if (gVAAPIDisplay) 165 { 166 gVAAPIDisplay->UpRef(); 167 return gVAAPIDisplay; 168 } 169 170 gVAAPIDisplay = new VAAPIDisplay(); 171 if (gVAAPIDisplay && gVAAPIDisplay->Create(use_glx)) 172 return gVAAPIDisplay; 173 174 delete gVAAPIDisplay; 175 gVAAPIDisplay = NULL; 176 return NULL; 177 } 178 179 static VAAPIDisplay *gVAAPIDisplay; 180 void *m_va_disp; 181 MythXDisplay *m_x_disp; 182 int m_ref_count; 183 }; 184 185 VAAPIDisplay* VAAPIDisplay::gVAAPIDisplay = NULL; 186 187 bool VAAPIContext::IsFormatAccelerated(QSize size, MythCodecID codec, 188 PixelFormat &pix_fmt) 189 { 190 bool result = false; 191 VAAPIContext *ctx = new VAAPIContext(codec, false); 192 if (ctx) 193 { 194 result = ctx->CreateDisplay(size); 195 pix_fmt = ctx->GetPixelFormat(); 196 } 197 delete ctx; 198 return result; 199 } 200 201 VAAPIContext::VAAPIContext(MythCodecID codec, bool use_glx) 202 : m_use_glx(use_glx), m_codec(codec), 203 m_vaProfile(VAProfileMPEG2Main)/* ?? */, 204 m_vaEntrypoint(VAEntrypointEncSlice), 205 m_pix_fmt(PIX_FMT_YUV420P), m_numSurfaces(NUM_VAAPI_BUFFERS), 206 m_surfaces(NULL), m_surfaceData(NULL) 207 { 208 memset(&m_ctx, 0, sizeof(vaapi_context)); 209 memset(&m_image, 0, sizeof(VAImage)); 210 init(&m_frame, FMT_NONE, NULL, 0, 0, 0); 211 } 212 213 VAAPIContext::~VAAPIContext() 214 { 215 if (m_frame.buf) 216 delete [] m_frame.buf; 217 218 ClearGLXSurfaces(); 219 220 if (m_display) 221 { 222 m_display->m_x_disp->Lock(); 223 224 INIT_ST 225 if (m_image.image_id != VA_INVALID_ID) 226 { 227 va_status = vaDestroyImage(m_ctx.display, m_image.image_id); 228 CHECK_ST 229 } 230 if (m_ctx.context_id) 231 { 232 va_status = vaDestroyContext(m_ctx.display, m_ctx.context_id); 233 CHECK_ST 234 } 235 if (m_ctx.config_id) 236 { 237 va_status = vaDestroyConfig(m_ctx.display, m_ctx.config_id); 238 CHECK_ST 239 } 240 if (m_surfaces) 241 { 242 va_status = vaDestroySurfaces(m_ctx.display, m_surfaces, m_numSurfaces); 243 CHECK_ST 244 } 245 } 246 247 if (m_surfaces) 248 delete [] m_surfaces; 249 if (m_surfaceData) 250 delete [] m_surfaceData; 251 252 if (m_display) 253 { 254 m_display->m_x_disp->Unlock(); 255 m_display->DownRef(); 256 } 257 258 VERBOSE(VB_PLAYBACK, LOC + "Deleted context"); 259 } 260 261 bool VAAPIContext::CreateDisplay(QSize size)\ 262 { 263 m_size = size; 264 bool ok = true; 265 m_display = VAAPIDisplay::GetDisplay(m_use_glx); 266 CREATE_CHECK(!m_size.isEmpty(), "Invalid size") 267 CREATE_CHECK(m_display != NULL, "Invalid display") 268 CREATE_CHECK(InitDisplay(), "Invalid VADisplay") 269 CREATE_CHECK(InitProfiles(), "No supported profiles") 270 if (ok) 271 VERBOSE(VB_PLAYBACK, LOC + QString("Created ctx display (%1x%2->%3x%4)") 272 .arg(size.width()).arg(size.height()) 273 .arg(m_size.width()).arg(m_size.height())); 274 return ok; 275 } 276 277 bool VAAPIContext::CreateBuffers(void) 278 { 279 bool ok = true; 280 CREATE_CHECK(!m_size.isEmpty(), "Invalid size") 281 CREATE_CHECK(InitBuffers(), "Failed to create buffers.") 282 CREATE_CHECK(InitContext(), "Failed to create context") 283 if (!m_use_glx) 284 CREATE_CHECK(InitImage(), "Failed to create VAImage.") 285 if (ok) 286 VERBOSE(VB_PLAYBACK, LOC + "Created buffers"); 287 return ok; 288 } 289 290 bool VAAPIContext::InitDisplay(void) 291 { 292 if (!m_display) 293 return false; 294 m_ctx.display = m_display->m_va_disp; 295 return m_ctx.display; 296 } 297 298 bool VAAPIContext::InitProfiles(void) 299 { 300 if (!(codec_is_vaapi(m_codec)) || !m_ctx.display) 301 return false; 302 303 MythXLocker locker(m_display->m_x_disp); 304 int max_profiles, max_entrypoints; 305 VAProfile profile_wanted = preferredProfile(m_codec); 306 VAProfile profile_found = VAProfileMPEG2Main; // FIXME 307 VAEntrypoint entry_found = VAEntrypointEncSlice; // unsupported value 308 309 max_profiles = vaMaxNumProfiles(m_ctx.display); 310 max_entrypoints = vaMaxNumEntrypoints(m_ctx.display); 311 VAProfile *profiles = new VAProfile[max_profiles]; 312 VAEntrypoint *entries = new VAEntrypoint[max_entrypoints]; 313 314 static bool debugged = false; 315 if (profiles && entries) 316 { 317 INIT_ST 318 int act_profiles, act_entries; 319 va_status = vaQueryConfigProfiles(m_ctx.display, 320 profiles, 321 &act_profiles); 322 CHECK_ST 323 if (ok && act_profiles > 0) 324 { 325 for (int i = 0; i < act_profiles; i++) 326 { 327 va_status = vaQueryConfigEntrypoints(m_ctx.display, 328 profiles[i], 329 entries, 330 &act_entries); 331 if (va_status == VA_STATUS_SUCCESS && act_entries > 0) 332 { 333 if (profiles[i] == profile_wanted) 334 { 335 profile_found = profile_wanted; 336 for (int j = 0; j < act_entries; j++) 337 if (entries[j] < entry_found) 338 entry_found = entries[j]; 339 } 340 341 if (!debugged) 342 { 343 QString entrylist = "Entrypoints: "; 344 for (int j = 0; j < act_entries; j++) 345 entrylist += entryToString(entries[j]); 346 VERBOSE(VB_IMPORTANT, LOC + QString("Profile: %1 %2") 347 .arg(profileToString(profiles[i])).arg(entrylist)); 348 } 349 } 350 } 351 } 352 debugged = true; 353 } 354 delete profiles; 355 delete entries; 356 357 VERBOSE(VB_PLAYBACK, LOC + QString("Desired profile for '%1': %2") 358 .arg(toString(m_codec)).arg(profileToString(profile_wanted))); 359 VERBOSE(VB_PLAYBACK, LOC + QString("Found profile %1 with entry %2") 360 .arg(profileToString(profile_found)).arg(entryToString(entry_found))); 361 362 if (profile_wanted != profile_found) 363 { 364 VERBOSE(VB_IMPORTANT, ERR + "Failed to find supported profile."); 365 return false; 366 } 367 368 if (entry_found > VAEntrypointVLD) 369 { 370 VERBOSE(VB_IMPORTANT, ERR + "Failed to find suitable entry point."); 371 return false; 372 } 373 374 m_vaProfile = profile_wanted; 375 m_vaEntrypoint = entry_found; 376 if (VAEntrypointVLD == m_vaEntrypoint) 377 m_pix_fmt = PIX_FMT_VAAPI_VLD; 378 return true; 379 } 380 381 bool VAAPIContext::InitBuffers(void) 382 { 383 if (!m_ctx.display) 384 return false; 385 386 MythXLocker locker(m_display->m_x_disp); 387 m_surfaces = new VASurfaceID[m_numSurfaces]; 388 m_surfaceData = new vaapi_surface[m_numSurfaces]; 389 390 if (!m_surfaces || !m_surfaceData) 391 return false; 392 393 INIT_ST 394 va_status = vaCreateSurfaces(m_ctx.display, m_size.width(), m_size.height(), 395 VA_RT_FORMAT_YUV420, m_numSurfaces, 396 m_surfaces); 397 CHECK_ST 398 399 for (int i = 0; i < m_numSurfaces; i++) 400 m_surfaceData[i].m_id = m_surfaces[i]; 401 return ok; 402 } 403 404 bool VAAPIContext::InitContext(void) 405 { 406 if (!m_ctx.display || m_vaEntrypoint > VAEntrypointVLD) 407 return false; 408 409 MythXLocker locker(m_display->m_x_disp); 410 VAConfigAttrib attrib; 411 attrib.type = VAConfigAttribRTFormat; 412 INIT_ST 413 va_status = vaGetConfigAttributes(m_ctx.display, m_vaProfile, 414 m_vaEntrypoint, &attrib, 1); 415 CHECK_ST 416 417 if (!ok || !(attrib.value & VA_RT_FORMAT_YUV420)) 418 { 419 VERBOSE(VB_IMPORTANT, ERR + "Failed to confirm YUV420 chroma"); 420 return false; 421 } 422 423 va_status = vaCreateConfig(m_ctx.display, m_vaProfile, m_vaEntrypoint, 424 &attrib, 1, &m_ctx.config_id); 425 CHECK_ST 426 if (!ok) 427 { 428 VERBOSE(VB_IMPORTANT, ERR + "Failed to create decoder config."); 429 return false; 430 } 431 432 va_status = vaCreateContext(m_ctx.display, m_ctx.config_id, 433 m_size.width(), m_size.height(), VA_PROGRESSIVE, 434 m_surfaces, m_numSurfaces, 435 &m_ctx.context_id); 436 CHECK_ST 437 if (!ok) 438 { 439 VERBOSE(VB_IMPORTANT, ERR + "Failed to create decoder context."); 440 return false; 441 } 442 return true; 443 } 444 445 bool VAAPIContext::InitImage(void) 446 { 447 int count = vaMaxNumImageFormats(m_ctx.display); 448 if (!count) 449 return false; 450 451 INIT_ST 452 VAImageFormat *fmts = new VAImageFormat[count]; 453 va_status = vaQueryImageFormats(m_ctx.display, fmts, &count); 454 CHECK_ST 455 if (!ok) 456 { 457 delete [] fmts; 458 return false; 459 } 460 461 for (int i = 0; i < count; i++) 462 { 463 if (!(fmts[i].fourcc == VA_FOURCC_YV12 || 464 fmts[i].fourcc == VA_FOURCC_NV12 || 465 fmts[i].fourcc == VA_FOURCC_I420)) 466 { 467 continue; 468 } 469 470 VERBOSE(VB_PLAYBACK, LOC + QString("Testing image format %1: %2") 471 .arg(i+1).arg(fourcc_str(fmts[i].fourcc))); 472 473 INIT_ST 474 va_status = vaCreateImage(m_ctx.display, &fmts[i], 475 m_size.width(), m_size.height(), &m_image); 476 CHECK_ST 477 if (m_image.image_id == VA_INVALID_ID) 478 { 479 VERBOSE(VB_IMPORTANT, LOC + "Failed to create VAImage"); 480 continue; 481 } 482 483 if (m_image.width != m_size.width() || m_image.height != m_size.height()) 484 VERBOSE(VB_IMPORTANT, LOC + "VAImage size does not match frame size."); 485 486 va_status = vaGetImage(m_ctx.display, m_surfaces[0], 0, 0, 487 m_image.width, m_image.height, 488 m_image.image_id); 489 if (VA_STATUS_SUCCESS == va_status) 490 { 491 VERBOSE(VB_PLAYBACK, LOC + QString("Using %1 image format") 492 .arg(fourcc_str(fmts[i].fourcc))); 493 494 init(&m_frame, FMT_YV12, NULL, m_image.width, m_image.height, 495 (m_image.width * m_image.height * 3) / 2); 496 497 if (m_image.format.fourcc == VA_FOURCC_NV12) 498 { 499 m_frame.buf = new unsigned char[m_frame.size]; 500 } 501 else 502 { 503 m_frame.pitches[0] = (int)m_image.pitches[0]; 504 m_frame.offsets[0] = (int)m_image.offsets[0]; 505 int u = m_image.format.fourcc == VA_FOURCC_I420 ? 1 : 2; 506 int v = m_image.format.fourcc == VA_FOURCC_I420 ? 2 : 1; 507 m_frame.pitches[1] = (int)m_image.pitches[u]; 508 m_frame.pitches[2] = (int)m_image.pitches[v]; 509 m_frame.offsets[1] = (int)m_image.offsets[u]; 510 m_frame.offsets[2] = (int)m_image.offsets[v]; 511 } 512 return true; 513 } 514 vaDestroyImage(m_ctx.display, m_image.image_id); 515 } 516 return false; 517 } 518 519 void* VAAPIContext::GetVideoSurface(int i) 520 { 521 if (i < 0 || i >= m_numSurfaces) 522 return NULL; 523 return &m_surfaceData[i]; 524 } 525 526 uint8_t* VAAPIContext::GetSurfaceIDPointer(void* buf) 527 { 528 if (!buf) 529 return NULL; 530 531 const vaapi_surface *surf = (vaapi_surface*)buf; 532 INIT_ST 533 va_status = vaSyncSurface(m_ctx.display, surf->m_id); 534 CHECK_ST 535 return (uint8_t*)(uintptr_t)surf->m_id; 536 } 537 538 bool VAAPIContext::FillFrame(VideoFrame *frame, OpenGLVideo *chain) 539 { 540 if (!frame || !chain || m_use_glx) 541 return false; 542 543 const vaapi_surface *surf = (vaapi_surface*)frame->buf; 544 if (!surf) 545 return false; 546 547 VASurfaceID id = surf->m_id; 548 549 INIT_ST 550 VASurfaceStatus status; 551 va_status = vaQuerySurfaceStatus(m_ctx.display, id, &status); 552 CHECK_ST 553 if (VASurfaceReady != status) 554 { 555 VERBOSE(VB_PLAYBACK, LOC + QString("Surface not ready %1") 556 .arg(status)); 557 return true; 558 } 559 560 m_display->m_x_disp->Lock(); 561 va_status = vaGetImage(m_ctx.display, id, 0, 0, 562 m_image.width, m_image.height, 563 m_image.image_id); 564 if (!ok) 565 return false; 566 567 uint8_t *buffer = NULL; 568 va_status = vaMapBuffer(m_ctx.display, m_image.buf, (void**)&buffer); 569 CHECK_ST 570 if (!buffer) 571 return false; 572 573 if (m_image.format.fourcc == VA_FOURCC_NV12) 574 { 575 AVPicture img_in, img_out; 576 avpicture_fill(&img_out, (uint8_t *)m_frame.buf, PIX_FMT_YUV420P, 577 m_image.width, m_image.height); 578 avpicture_fill(&img_in, buffer, PIX_FMT_NV12, 579 m_image.width, m_image.height); 580 myth_sws_img_convert(&img_out, PIX_FMT_YUV420P, &img_in, PIX_FMT_NV12, 581 m_image.width, m_image.height); 582 } 583 else 584 m_frame.buf = (unsigned char*)buffer; 585 586 m_frame.interlaced_frame = frame->interlaced_frame; 587 chain->UpdateInputFrame(&m_frame, false); 588 va_status = vaUnmapBuffer(m_ctx.display, m_image.buf); 589 m_display->m_x_disp->Unlock(); 590 591 if (m_image.format.fourcc != VA_FOURCC_NV12) 592 m_frame.buf = NULL; 593 CHECK_ST 594 return true; 595 } 596 597 bool VAAPIContext::CopySurfaceToTexture(const void* buf, uint texture, 598 uint texture_type, 599 FrameScanType scan) 600 { 601 if (!buf || !texture || !m_use_glx) 602 return false; 603 604 const vaapi_surface *surf = (vaapi_surface*)buf; 605 void* glx_surface = GetGLXSurface(texture, texture_type); 606 if (!glx_surface) 607 return false; 608 609 int field = VA_FRAME_PICTURE; 610 if (scan == kScan_Interlaced) 611 field = VA_TOP_FIELD; 612 else if (scan == kScan_Intr2ndField) 613 field = VA_BOTTOM_FIELD; 614 INIT_ST 615 XLOCK(m_display->m_x_disp, 616 va_status = vaCopySurfaceGLX(m_ctx.display, glx_surface, 617 surf->m_id, field)); 618 CHECK_ST 619 return true; 620 } 621 622 void* VAAPIContext::GetGLXSurface(uint texture, uint texture_type) 623 { 624 if (m_glxSurfaces.contains(texture)) 625 return m_glxSurfaces.value(texture); 626 627 void *glx_surface = NULL; 628 INIT_ST 629 XLOCK(m_display->m_x_disp, 630 va_status = vaCreateSurfaceGLX(m_ctx.display, texture_type, 631 texture, &glx_surface)); 632 CHECK_ST 633 if (!glx_surface) 634 { 635 VERBOSE(VB_IMPORTANT, ERR + "Failed to create GLX surface."); 636 return NULL; 637 } 638 639 m_glxSurfaces.insert(texture, glx_surface); 640 641 VERBOSE(VB_PLAYBACK, LOC + QString("Number of VAAPI GLX surfaces: %1") 642 .arg(m_glxSurfaces.size())); 643 return glx_surface; 644 } 645 646 void VAAPIContext::ClearGLXSurfaces(void) 647 { 648 if (!m_display) 649 return; 650 651 m_display->m_x_disp->Lock(); 652 INIT_ST 653 foreach (void* surface, m_glxSurfaces) 654 { 655 va_status = vaDestroySurfaceGLX(m_ctx.display, surface); 656 CHECK_ST 657 } 658 m_glxSurfaces.clear(); 659 m_display->m_x_disp->Unlock(); 660 } -
home/mark/trunk/mythtv/libs/libmythtv/videoout_opengl.h
10 10 { 11 11 public: 12 12 static void GetRenderOptions(render_opts &opts, QStringList &cpudeints); 13 VideoOutputOpenGL( );13 VideoOutputOpenGL(bool direct_update = false); 14 14 virtual ~VideoOutputOpenGL(); 15 15 16 16 virtual bool Init(int width, int height, float aspect, WId winid, … … 70 70 VideoFrame av_pause_frame; 71 71 72 72 MythOpenGLPainter *gl_painter; 73 bool gl_direct_update; 73 74 }; 74 75 75 76 #endif -
home/mark/trunk/mythtv/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 bool force_rgbatex, 48 48 LetterBoxColour letterbox_colour = kLetterBoxColour_Black); 49 49 50 50 uint GetInputTexture(void); … … 128 128 OpenGLFilterType defaultUpsize; 129 129 uint gl_features; 130 130 bool using_ycbcrtex; 131 bool using_ hardwaretex;131 bool using_rgbatex; 132 132 LetterBoxColour gl_letterbox_colour; 133 133 }; 134 134 #endif // _OPENGL_VIDEO_H__ -
home/mark/trunk/mythtv/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 using_rgbatex(false), 88 88 gl_letterbox_colour(kLetterBoxColour_Black) 89 89 { 90 90 } … … 140 140 QSize videoDim, QRect displayVisibleRect, 141 141 QRect displayVideoRect, QRect videoRect, 142 142 bool viewport_control, QString options, 143 bool hw_accel,143 bool force_rgbatex, 144 144 LetterBoxColour letterbox_colour) 145 145 { 146 146 gl_context = glcontext; … … 177 177 178 178 SetViewPort(display_visible_rect.size()); 179 179 180 using_ hardwaretex = hw_accel;181 bool use_pbo = !using_hardwaretex && (gl_features & kGLExtPBufObj);180 using_rgbatex = force_rgbatex; 181 bool use_pbo = gl_features & kGLExtPBufObj; 182 182 bool basic_features = gl_features & kGLExtFragProg; 183 183 bool full_features = basic_features && (gl_features & kGLExtFBufObj); 184 using_ycbcrtex = !using_ hardwaretex && !full_features &&184 using_ycbcrtex = !using_rgbatex && !full_features && 185 185 (gl_features & kGLMesaYCbCr); 186 186 187 187 if (using_ycbcrtex) … … 196 196 QString("No OpenGL feature support for Bicubic filter.")); 197 197 } 198 198 199 if (!using_ hardwaretex &&199 if (!using_rgbatex && 200 200 (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect)) 201 201 textureType = gl_context->GetTextureType(textureRects); 202 202 203 203 GLuint tex = 0; 204 204 bool ok = false; 205 205 206 if (basic_features && !using_ hardwaretex)206 if (basic_features && !using_rgbatex) 207 207 { 208 208 tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo); 209 209 ok = tex && AddFilter(kGLFilterYUV2RGB); 210 210 } 211 else if (using_ycbcrtex || using_ hardwaretex)211 else if (using_ycbcrtex || using_rgbatex) 212 212 { 213 213 tex = CreateVideoTexture(actual_video_dim, 214 214 inputTextureSize, use_pbo); … … 216 216 if (ok && using_ycbcrtex) 217 217 VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for" 218 218 " colorspace conversion.")); 219 else if (ok && using_ hardwaretex)219 else if (ok && using_rgbatex) 220 220 VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel.")); 221 221 else 222 222 { 223 223 using_ycbcrtex = false; 224 using_ hardwaretex = false;224 using_rgbatex = false; 225 225 } 226 226 } 227 227 … … 717 717 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType, 718 718 GL_UNSIGNED_SHORT_8_8_MESA, 719 719 GL_YCBCR_MESA, GL_YCBCR_MESA); 720 else if (using_hardwaretex)721 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,722 GL_UNSIGNED_BYTE, GL_RGBA,723 GL_RGBA, GL_LINEAR,724 GL_CLAMP_TO_EDGE);725 720 else 726 721 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType); 727 722 tex_size = gl_context->GetTextureSize(textureType, size); … … 785 780 { 786 781 return; 787 782 } 783 788 784 if (hardwareDeinterlacing) 789 785 RotateTextures(); 790 786 -
home/mark/trunk/mythtv/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 const QStringList vaapilist 156 = VideoOutputOpenGLVAAPI::GetAllowedRenderers(codec_id, video_dim); 157 renderers += vaapilist; 158 #endif // USING_VAAPI 159 146 160 VERBOSE(VB_PLAYBACK, LOC + "Allowed renderers: " + 147 161 to_comma_list(renderers)); 148 162 … … 205 219 vo = new VideoOutputVDPAU(); 206 220 #endif // USING_VDPAU 207 221 222 #ifdef USING_VAAPI 223 if (renderer == "openglvaapi") 224 vo = new VideoOutputOpenGLVAAPI(); 225 if (renderer == "openglvaapiglx") 226 vo = new VideoOutputOpenGLVAAPI(true); 227 #endif // USING_VAAPI 228 208 229 #ifdef USING_XV 209 230 if (xvlist.contains(renderer)) 210 231 vo = new VideoOutputXv(); -
home/mark/trunk/mythtv/libs/libmythtv/vaapicontext.h
1 #ifndef VAAPICONTEXT_H 2 #define VAAPICONTEXT_H 3 4 #include <QHash> 5 6 extern "C" { 7 #include "libavcodec/vaapi.h" 8 } 9 #include "va/va.h" 10 #include "va/va_x11.h" 11 #include "va/va_glx.h" 12 13 struct vaapi_surface 14 { 15 VASurfaceID m_id; 16 }; 17 18 class VAAPIDisplay; 19 class OpenGLVideo; 20 21 class VAAPIContext 22 { 23 public: 24 static bool IsFormatAccelerated(QSize size, MythCodecID codec, 25 PixelFormat &pix_fmt); 26 VAAPIContext(MythCodecID codec, bool use_glx); 27 ~VAAPIContext(); 28 29 bool CreateDisplay(QSize size); 30 bool CreateBuffers(void); 31 void* GetVideoSurface(int i); 32 uint8_t* GetSurfaceIDPointer(void* buf); 33 34 int GetNumBuffers(void) { return m_numSurfaces; } 35 PixelFormat GetPixelFormat(void) { return m_pix_fmt; } 36 37 bool FillFrame(VideoFrame *frame, OpenGLVideo *chain); 38 39 bool CopySurfaceToTexture(const void* buf, uint texture, uint texture_type, 40 FrameScanType scan); 41 void* GetGLXSurface(uint texture, uint texture_type); 42 void ClearGLXSurfaces(void); 43 44 bool InitDisplay(void); 45 bool InitProfiles(void); 46 bool InitBuffers(void); 47 bool InitContext(void); 48 bool InitImage(void); 49 50 bool m_use_glx; 51 vaapi_context m_ctx; 52 MythCodecID m_codec; 53 QSize m_size; 54 VAAPIDisplay *m_display; 55 VAProfile m_vaProfile; 56 VAEntrypoint m_vaEntrypoint; 57 PixelFormat m_pix_fmt; 58 int m_numSurfaces; 59 VASurfaceID *m_surfaces; 60 vaapi_surface *m_surfaceData; 61 QHash<uint, void*> m_glxSurfaces; 62 VAImage m_image; 63 VideoFrame m_frame; 64 }; 65 66 #endif // VAAPICONTEXT_H -
home/mark/trunk/mythtv/libs/libmythtv/videodisplayprofile.cpp
642 642 dec_name["xvmc-vld"] = QObject::tr("VIA XvMC"); 643 643 dec_name["macaccel"] = QObject::tr("Mac hardware acceleration"); 644 644 dec_name["vdpau"] = QObject::tr("NVidia VDPAU acceleration"); 645 dec_name["vaapi"] = QObject::tr("VAAPI acceleration"); 645 646 } 646 647 647 648 QString ret = decoder; … … 680 681 if (decoder == "xvmc-vld") 681 682 msg += QObject::tr("VIA XvMC will use the VIA VLD XvMC extension."); 682 683 683 684 684 if (decoder == "macaccel") 685 685 msg += QObject::tr( 686 686 "Mac hardware will try to use the graphics " … … 691 691 "VDPAU will attempt to use the graphics hardware to " 692 692 "accelerate video decoding and playback."); 693 693 694 if (decoder == "vaapi") 695 msg += QObject::tr( 696 "VAAPI will attempt to use the graphics hardware to " 697 "accelerate video decoding."); 694 698 return msg; 695 699 } 696 700 … … 748 752 return QObject::tr("Advanced (1x, HW)"); 749 753 else if ("vdpauadvanceddoublerate" == short_name) 750 754 return QObject::tr("Advanced (2x, HW)"); 755 else if ("vaapionefield" == short_name) 756 return QObject::tr("One Field (1x, HW)"); 757 else if ("vaapibobdeint" == short_name) 758 return QObject::tr("Bob (2x, HW)"); 751 759 752 760 return ""; 753 761 } … … 1237 1245 "This is the only video renderer for NVidia VDPAU decoding."); 1238 1246 } 1239 1247 1248 if (renderer == "openglvaapi") 1249 { 1250 msg = QObject::tr( 1251 "This video renderer uses VAAPI for video decoding and " 1252 "OpenGL for scaling and color conversion."); 1253 } 1254 1255 if (renderer == "openglvaapiglx") 1256 { 1257 msg = QObject::tr( 1258 "This video renderer uses VAAPI for video decoding and " 1259 "OpenGL for scaling and color conversion. Video frames are " 1260 "transferred directly from VAAPI to OpenGL."); 1261 } 1262 1240 1263 return msg; 1241 1264 } 1242 1265 … … 1370 1393 msg = kBasicMsg + " " + kDoubleRateMsg + " " + kUsingGPU; 1371 1394 else if (deint == "vdpauadvanceddoublerate") 1372 1395 msg = kAdvMsg + " " + kDoubleRateMsg + " " + kUsingGPU; 1396 else if (deint == "vaapionefield") 1397 msg = kOneFieldMsg + " " + kUsingGPU; 1398 else if (deint == "vaapibobdeint") 1399 msg = kBobMsg + " " + kUsingGPU; 1373 1400 else 1374 1401 msg = QObject::tr("'%1' has not been documented yet.").arg(deint); 1375 1402
