Ticket #8593: vaapi_v7.diff
| File vaapi_v7.diff, 48.9 KB (added by markk, 21 months ago) |
|---|
-
home/mark/trunk/mythtv/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 --enable-crystalhd enable Broadcom CrystalHD hardware decoder support 132 133 --disable-opengl-video disable OpenGL based video display 133 134 --disable-quartz-video disable Mac OS X CoreVideo based video display … … 1347 1348 mythtranscode 1348 1349 opengl 1349 1350 vdpau 1351 vaapi 1350 1352 ' 1351 1353 1352 1354 CMDLINE_SELECT=" … … 1709 1711 xvmc_deps="xv X11_extensions_XvMClib_h" 1710 1712 xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h" 1711 1713 xvmcw_deps="xvmc" 1714 vaapi_deps="x11 opengl_video" 1712 1715 1713 1716 <<BLOCKQUOTE 1714 1717 # tests … … 3541 3544 check_header termios.h 3542 3545 check_header vdpau/vdpau.h 3543 3546 check_header vdpau/vdpau_x11.h 3547 check_header va/va.h 3548 check_header va/va_glx.h 3544 3549 check_header X11/extensions/XvMClib.h 3545 3550 3546 3551 check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex … … 3819 3824 disable crystalhd; 3820 3825 fi 3821 3826 3827 if enabled vaapi; then 3828 enabled va_va_h && enabled va_va_glx_h || disable vaapi 3829 if enabled vaapi; then 3830 # for XvBA/VDPAU backends we need splitted desktop 0.31.0 but 3831 # for upstream GLX support we need 0.31.1 ??? 3832 check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" || 3833 { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; } 3834 fi 3835 else 3836 disable vaapi 3837 fi 3838 3822 3839 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" 3823 3840 enabled debug && add_cxxflags -g"$debuglevel" 3824 3841 … … 4376 4393 echo "XvMC libs $VENDOR_XVMC_LIBS" 4377 4394 fi 4378 4395 echo "VDPAU support ${vdpau-no}" 4396 echo "VAAPI support ${vaapi-no}" 4379 4397 echo "CrystalHD support ${crystalhd-no}" 4380 4398 fi 4381 4399 echo "OpenGL video ${opengl_video-no}" -
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(); 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); 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
7 7 #include "osd.h" 8 8 #include "mythuihelper.h" 9 9 10 #define LOC QString("VidOut OGL: ")11 #define LOC_ERR QString("VidOut OGL: ")10 #define LOC QString("VidOutGL: ") 11 #define LOC_ERR QString("VidOutGL Error: ") 12 12 13 13 void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 14 14 QStringList &cpudeints) … … 125 125 winid, winx, winy, winw, winh, 126 126 codec_id, embedid); 127 127 128 if (db_vdisp_profile) 129 db_vdisp_profile->SetVideoRenderer("opengl"); 128 SetProfile(); 130 129 131 130 success &= SetupContext(); 132 131 InitDisplayMeasurements(width, height, false); 133 132 success &= CreateBuffers(); 133 success &= CreatePauseFrame(); 134 134 success &= SetupOpenGL(); 135 135 136 136 InitOSD(); … … 146 146 return success; 147 147 } 148 148 149 void VideoOutputOpenGL::SetProfile(void) 150 { 151 if (db_vdisp_profile) 152 db_vdisp_profile->SetVideoRenderer("opengl"); 153 } 154 149 155 bool VideoOutputOpenGL::InputChanged(const QSize &input_size, 150 156 float aspect, 151 157 MythCodecID av_codec_id, 152 158 void *codec_private, 153 159 bool &aspect_only) 154 160 { 155 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4 ")161 VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5") 156 162 .arg(input_size.width()).arg(input_size.height()).arg(aspect) 157 .arg(toString( av_codec_id)));163 .arg(toString(video_codec_id)).arg(toString(av_codec_id))); 158 164 159 165 QMutexLocker locker(&gl_context_lock); 160 161 166 if (!codec_is_std(av_codec_id)) 162 167 { 163 168 VERBOSE(VB_IMPORTANT, LOC_ERR + … … 244 249 window.GetVideoDim(), dvr, 245 250 window.GetDisplayVideoRect(), 246 251 window.GetVideoRect(), true, 247 GetFilters(), db_letterbox_colour); 252 GetFilters(), !codec_is_std(video_codec_id), 253 db_letterbox_colour); 248 254 if (success) 249 255 { 250 256 bool temp_deinterlacing = m_deinterlacing; … … 278 284 bool VideoOutputOpenGL::CreateBuffers(void) 279 285 { 280 286 QMutexLocker locker(&gl_context_lock); 281 282 bool success = true;283 287 vbuffers.Init(31, true, 1, 12, 4, 2, false); 284 success &= vbuffers.CreateBuffers(window.GetVideoDim().width(), 285 window.GetVideoDim().height()); 288 return vbuffers.CreateBuffers(window.GetVideoDim().width(), 289 window.GetVideoDim().height()); 290 } 286 291 292 bool VideoOutputOpenGL::CreatePauseFrame(void) 293 { 287 294 av_pause_frame.height = vbuffers.GetScratchFrame()->height; 288 295 av_pause_frame.width = vbuffers.GetScratchFrame()->width; 289 296 av_pause_frame.bpp = vbuffers.GetScratchFrame()->bpp; … … 292 299 av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber; 293 300 294 301 if (!av_pause_frame.buf) 295 success = false; 296 else 297 clear(&av_pause_frame, GUID_YV12_PLANAR); 302 return false; 298 303 299 return success; 304 clear(&av_pause_frame, GUID_YV12_PLANAR); 305 return true; 300 306 } 301 307 302 308 void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd, … … 308 314 if (!gl_videochain || !gl_context) 309 315 return; 310 316 317 bool sw_frame = codec_is_std(video_codec_id); 311 318 bool deint_proc = m_deinterlacing && (m_deintFilter != NULL); 312 319 OpenGLLocker ctx_lock(gl_context); 313 320 … … 319 326 pauseframe = true; 320 327 } 321 328 322 if (filterList )329 if (filterList && sw_frame) 323 330 filterList->ProcessFrame(frame); 324 331 325 332 bool safepauseframe = pauseframe && !IsBobDeint(); 326 if ( deint_proc && m_deinterlaceBeforeOSD &&333 if (sw_frame && deint_proc && m_deinterlaceBeforeOSD && 327 334 (!pauseframe || safepauseframe)) 328 335 { 329 336 m_deintFilter->ProcessFrame(frame, scan); … … 335 342 ShowPIPs(frame, pipPlayers); 336 343 } 337 344 338 if ( (!pauseframe || safepauseframe) &&345 if (sw_frame && (!pauseframe || safepauseframe) && 339 346 deint_proc && !m_deinterlaceBeforeOSD) 340 347 { 341 348 m_deintFilter->ProcessFrame(frame, scan); … … 343 350 344 351 bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint"); 345 352 346 if (gl_videochain )353 if (gl_videochain && sw_frame) 347 354 gl_videochain->UpdateInputFrame(frame, soft_bob); 348 355 } 349 356 … … 632 639 QSize(pipVideoWidth, pipVideoHeight), 633 640 dvr, position, 634 641 QRect(0, 0, pipVideoWidth, pipVideoHeight), 635 false, GetFilters() );642 false, GetFilters(), false); 636 643 gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort()); 637 644 if (!success) 638 645 { … … 653 660 QSize(pipVideoWidth, pipVideoHeight), 654 661 dvr, position, 655 662 QRect(0, 0, pipVideoWidth, pipVideoHeight), 656 false, GetFilters() );663 false, GetFilters(), false); 657 664 658 665 gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort()); 659 666 if (!success) -
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 … … 1154 1165 return fmt[i]; 1155 1166 } 1156 1167 1168 static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt) 1169 { 1170 return fmt == PIX_FMT_VAAPI_MOCO || 1171 fmt == PIX_FMT_VAAPI_IDCT || 1172 fmt == PIX_FMT_VAAPI_VLD; 1173 } 1174 1175 static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1176 const enum PixelFormat *fmt) 1177 { 1178 if (!fmt) 1179 return PIX_FMT_NONE; 1180 int i = 0; 1181 for (; fmt[i] != PIX_FMT_NONE ; i++) 1182 if (IS_VAAPI_PIX_FMT(fmt[i])) 1183 break; 1184 return fmt[i]; 1185 } 1186 1157 1187 static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt) 1158 1188 { 1159 1189 switch (fmt) … … 1201 1231 { 1202 1232 directrendering = true; 1203 1233 if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) && 1204 !CODEC_IS_HWACCEL(codec ))1234 !CODEC_IS_HWACCEL(codec, enc)) 1205 1235 { 1206 1236 SetLowBuffers(false); 1207 1237 } … … 1225 1255 enc->draw_horiz_band = render_slice_vdpau; 1226 1256 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1227 1257 } 1258 else if (CODEC_IS_VAAPI(codec, enc)) 1259 { 1260 enc->get_buffer = get_avf_buffer_vaapi; 1261 enc->get_format = get_format_vaapi; 1262 enc->release_buffer = release_avf_buffer; 1263 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1264 } 1228 1265 else if (codec && codec->capabilities & CODEC_CAP_DR1) 1229 1266 { 1230 1267 enc->flags |= CODEC_FLAG_EMU_EDGE; … … 1770 1807 handled = true; 1771 1808 } 1772 1809 #endif // USING_VDPAU 1810 #ifdef USING_VAAPI 1811 MythCodecID vaapi_mcid; 1812 PixelFormat pix_fmt = PIX_FMT_YUV420P; 1813 vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 1814 width, height, mpeg_version(enc->codec_id), 1815 no_hardware_decoders, pix_fmt); 1816 1817 if (vaapi_mcid >= video_codec_id) 1818 { 1819 enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid); 1820 video_codec_id = vaapi_mcid; 1821 handled = true; 1822 if (!no_hardware_decoders && 1823 codec_is_vaapi(video_codec_id)) 1824 { 1825 enc->pix_fmt = pix_fmt; 1826 } 1827 } 1828 #endif // USING_VAAPI 1773 1829 #ifdef USING_XVMC 1774 1830 1775 1831 bool force_xv = no_hardware_decoders; … … 2484 2540 } 2485 2541 } 2486 2542 2543 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic) 2544 { 2545 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 2546 VideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame(false); 2547 2548 pic->data[0] = frame->buf; 2549 pic->data[1] = NULL; 2550 pic->data[2] = NULL; 2551 pic->data[3] = NULL; 2552 pic->linesize[0] = 0; 2553 pic->linesize[1] = 0; 2554 pic->linesize[2] = 0; 2555 pic->linesize[3] = 0; 2556 pic->opaque = frame; 2557 pic->type = FF_BUFFER_TYPE_USER; 2558 pic->age = 256 * 256 * 256 * 64; 2559 frame->pix_fmt = c->pix_fmt; 2560 2561 #ifdef USING_VAAPI 2562 if (nd->GetPlayer()->getVideoOutput()) 2563 { 2564 VideoOutputOpenGLVAAPI *vo = 2565 dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetPlayer()->getVideoOutput()); 2566 c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext(); 2567 pic->data[3] = vo->GetSurfaceIDPointer(frame->buf); 2568 } 2569 #endif 2570 2571 return 0; 2572 } 2573 2487 2574 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len) 2488 2575 { 2489 2576 if (!len) … … 3362 3449 QStringList list = text.split('\n', QString::SkipEmptyParts); 3363 3450 delete dec; 3364 3451 subReader->AddRawTextSubtitle(list, pkt->convergence_duration); 3452 return true; 3365 3453 } 3366 3454 3367 3455 bool AvFormatDecoder::ProcessDataPacket(AVStream *curstream, AVPacket *pkt, -
home/mark/trunk/mythtv/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() 27 : VideoOutputOpenGL(), 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(video_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 = (video_codec_id != av_codec_id); 57 bool res_changed = input_size != window.GetVideoDim(); 58 bool asp_changed = aspect != window.GetVideoAspect(); 59 60 if (!res_changed && !cid_changed) 61 { 62 if (asp_changed) 63 { 64 aspect_only = true; 65 VideoAspectRatioChanged(aspect); 66 MoveResize(); 67 } 68 return true; 69 } 70 71 TearDown(); 72 QRect disp = window.GetDisplayVisibleRect(); 73 if (Init(input_size.width(), input_size.height(), 74 aspect, gl_parent_win, disp.left(), disp.top(), 75 disp.width(), disp.height(), av_codec_id, gl_embed_win)) 76 { 77 BestDeint(); 78 return true; 79 } 80 81 VERBOSE(VB_IMPORTANT, LOC_ERR + 82 QString("Failed to re-initialise video output.")); 83 errorState = kError_Unknown; 84 85 return false; 86 } 87 88 bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect, 89 WId winid, int winx, int winy, int winw, 90 int winh, MythCodecID codec_id, WId embedid) 91 { 92 if (codec_is_vaapi(codec_id)) 93 { 94 video_codec_id = codec_id; 95 if (!CreateVAAPIContext(QSize(width, height))) 96 return false; 97 } 98 99 return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy, 100 winw, winh, video_codec_id, embedid); 101 } 102 103 bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size) 104 { 105 if (m_ctx) 106 DeleteVAAPIContext(); 107 m_ctx = new VAAPIContext(video_codec_id); 108 if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers()) 109 return true; 110 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to create VAAPI context.")); 111 errorState = kError_Unknown; 112 return false; 113 } 114 115 void VideoOutputOpenGLVAAPI::DeleteVAAPIContext(void) 116 { 117 delete m_ctx; 118 m_ctx = NULL; 119 } 120 121 bool VideoOutputOpenGLVAAPI::CreateBuffers(void) 122 { 123 if ((!codec_is_vaapi(video_codec_id)) || !m_ctx) 124 return VideoOutputOpenGL::CreateBuffers(); 125 126 QMutexLocker locker(&gl_context_lock); 127 int num_buffers = m_ctx->GetNumBuffers(); 128 const QSize video_dim = window.GetVideoDim(); 129 vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame 130 131 bool ok = true; 132 for (int i = 0; i < num_buffers; i++) 133 { 134 ok &= vbuffers.CreateBuffer(video_dim.width(), 135 video_dim.height(), i, 136 m_ctx->GetVideoSurface(i), FMT_VAAPI); 137 } 138 return ok; 139 } 140 141 void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void) 142 { 143 if (m_ctx) 144 return &m_ctx->m_ctx; 145 return NULL; 146 } 147 148 uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf) 149 { 150 if (m_ctx) 151 return m_ctx->GetSurfaceIDPointer(buf); 152 return NULL; 153 } 154 155 void VideoOutputOpenGLVAAPI::SetProfile(void) 156 { 157 if (db_vdisp_profile) 158 db_vdisp_profile->SetVideoRenderer("openglvaapi"); 159 } 160 161 bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const 162 { 163 return filtername.contains("vaapi"); 164 } 165 166 bool VideoOutputOpenGLVAAPI::SetDeinterlacingEnabled(bool) 167 { 168 return true; 169 } 170 171 bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf) 172 { 173 return true; 174 } 175 176 void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd, 177 FilterChain *filterList, 178 const PIPMap &pipPlayers, 179 FrameScanType scan) 180 { 181 VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan); 182 183 if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain && frame) 184 { 185 gl_context->makeCurrent(); 186 uint tex = gl_videochain->GetInputTexture(); 187 gl_context->EnableTextures(tex); 188 if (m_ctx->CopySurfaceToTexture(frame->buf, tex, 189 gl_videochain->GetTextureType())) 190 { 191 gl_videochain->SetInputUpdated(); 192 } 193 gl_context->doneCurrent(); 194 } 195 } 196 197 QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers( 198 MythCodecID myth_codec_id, const QSize &video_dim) 199 { 200 (void) video_dim; 201 QStringList list; 202 if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) && 203 !getenv("NO_VAAPI")) 204 { 205 list += "openglvaapi"; 206 } 207 return list; 208 } 209 210 MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec( 211 uint width, uint height, 212 uint stream_type, bool no_acceleration, 213 PixelFormat &pix_fmt) 214 { 215 QSize size(width, height); 216 bool use_cpu = no_acceleration; 217 VideoDisplayProfile vdp; 218 vdp.SetInput(size); 219 QString dec = vdp.GetDecoder(); 220 221 MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1)); 222 use_cpu |= !codec_is_vaapi(test_cid); 223 use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt); 224 if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu) 225 return (MythCodecID)(kCodec_MPEG1 + (stream_type-1)); 226 227 return test_cid; 228 } -
home/mark/trunk/mythtv/libs/libmythtv/libmythtv.pro
352 352 using_opengl_video:HEADERS += openglvideo.h videoout_opengl.h 353 353 using_opengl_video:SOURCES += openglvideo.cpp videoout_opengl.cpp 354 354 355 using_vaapi: DEFINES += USING_VAAPI 356 using_vaapi: DEFINES += videoout_openglvaapi.h vaapicontext.h 357 using_vaapi: SOURCES += videoout_openglvaapi.cpp vaapicontext.cpp 358 using_vaapi: LIBS += -lva -lva-glx 359 355 360 # Misc. frontend 356 361 HEADERS += DetectLetterbox.h 357 362 SOURCES += DetectLetterbox.cpp -
home/mark/trunk/mythtv/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 } -
home/mark/trunk/mythtv/libs/libmythtv/videoout_opengl.h
11 11 public: 12 12 static void GetRenderOptions(render_opts &opts, QStringList &cpudeints); 13 13 VideoOutputOpenGL(); 14 ~VideoOutputOpenGL();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, 18 MythCodecID codec_id, WId embedid = 0); 19 void TearDown(void); 16 virtual bool Init(int width, int height, float aspect, WId winid, 17 int winx, int winy, int winw, int winh, 18 MythCodecID codec_id, WId embedid = 0); 19 virtual void SetProfile(void); 20 virtual void TearDown(void); 20 21 21 22 void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd); 22 v oid ProcessFrame(VideoFrame *frame, OSD *osd,23 FilterChain *filterList,24 const PIPMap &pipPlayers,25 FrameScanType scan);26 v oid Show(FrameScanType );27 bool InputChanged(const QSize &input_size, float aspect,28 MythCodecID av_codec_id, void *codec_private,29 bool &aspect_only);23 virtual void ProcessFrame(VideoFrame *frame, OSD *osd, 24 FilterChain *filterList, 25 const PIPMap &pipPlayers, 26 FrameScanType scan); 27 virtual void Show(FrameScanType ); 28 virtual bool InputChanged(const QSize &input_size, float aspect, 29 MythCodecID av_codec_id, void *codec_private, 30 bool &aspect_only); 30 31 void UpdatePauseFrame(void); 31 32 void DrawUnusedRects(bool) { } 32 33 void Zoom(ZoomDirection direction); … … 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 MythPlayer *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); -
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 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__ -
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 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 & kGLMesaYCbCr); 184 using_ycbcrtex = !using_hardwaretex && !full_features && 185 (gl_features & kGLMesaYCbCr); 182 186 183 187 if (using_ycbcrtex) 184 188 basic_features = false; … … 192 196 QString("No OpenGL feature support for Bicubic filter.")); 193 197 } 194 198 195 if ((defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect)) 199 if (!using_hardwaretex && 200 (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect)) 196 201 textureType = gl_context->GetTextureType(textureRects); 197 202 198 203 GLuint tex = 0; 199 204 bool ok = false; 200 205 201 if (basic_features )206 if (basic_features && !using_hardwaretex) 202 207 { 203 208 tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo); 204 209 ok = tex && AddFilter(kGLFilterYUV2RGB); 205 210 } 206 else if (using_ycbcrtex )211 else if (using_ycbcrtex || using_hardwaretex) 207 212 { 208 213 tex = CreateVideoTexture(actual_video_dim, 209 214 inputTextureSize, use_pbo); 210 215 ok = tex && AddFilter(kGLFilterResize); 211 if (ok )216 if (ok && using_ycbcrtex) 212 217 VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for" 213 218 " colorspace conversion.")); 219 else if (ok && using_hardwaretex) 220 VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel.")); 214 221 else 222 { 215 223 using_ycbcrtex = false; 224 using_hardwaretex = false; 225 } 216 226 } 217 227 218 228 if (ok) … … 707 717 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType, 708 718 GL_UNSIGNED_SHORT_8_8_MESA, 709 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); 710 725 else 711 726 tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType); 712 727 tex_size = gl_context->GetTextureSize(textureType, size); … … 737 752 return QSize(w, h); 738 753 } 739 754 755 uint OpenGLVideo::GetInputTexture(void) 756 { 757 return inputTextures[0]; 758 } 759 760 uint OpenGLVideo::GetTextureType(void) 761 { 762 return textureType; 763 } 764 765 void OpenGLVideo::SetInputUpdated(void) 766 { 767 inputUpdated = true; 768 } 769 740 770 /** 741 771 * \fn OpenGLVideo::UpdateInputFrame(const VideoFrame *frame, bool soft_bob) 742 772 * Update the current input texture using the data from the given YV12 video -
home/mark/trunk/mythtv/libs/libmythtv/mythcodecid.h
115 115 codec->id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)) 116 116 #define CODEC_IS_VDPAU(codec) (codec &&\ 117 117 codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) 118 #define CODEC_IS_HWACCEL(codec) (CODEC_IS_XVMC(codec) ||\ 119 CODEC_IS_VDPAU(codec)) 118 #define CODEC_IS_VAAPI(codec, enc) (codec && IS_VAAPI_PIX_FMT(enc->pix_fmt)) 119 #define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_XVMC(codec) ||\ 120 CODEC_IS_VDPAU(codec) ||\ 121 CODEC_IS_VAAPI(codec, enc)) 120 122 121 123 #endif // _MYTH_CODEC_ID_H_ -
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 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 … … 205 217 vo = new VideoOutputVDPAU(); 206 218 #endif // USING_VDPAU 207 219 220 #ifdef USING_VAAPI 221 if (renderer == "openglvaapi") 222 vo = new VideoOutputOpenGLVAAPI(); 223 #endif // USING_VAAPI 224 208 225 #ifdef USING_XV 209 226 if (xvlist.contains(renderer)) 210 227 vo = new VideoOutputXv(); -
home/mark/trunk/mythtv/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
