Ticket #13311: 20180909_1639_fix_configure.patch
File 20180909_1639_fix_configure.patch, 77.9 KB (added by , 6 years ago) |
---|
-
mythtv/configure
diff --git a/mythtv/configure b/mythtv/configure index f7cfc291b82..ec11749e0f5 100755
a b Advanced options (experts only): 134 134 --disable-vdpau disable NVidia VDPAU hardware acceleration. 135 135 --disable-crystalhd disable Broadcom CrystalHD hardware decoder support 136 136 --disable-vaapi disable VAAPI hardware accelerated video decoding 137 --disable-vaapi2 disable VAAPI2 hardware accelerated video decoding 137 138 --disable-openmax disable OpenMAX hardware accelerated video decoding 138 139 --disable-dxva2 disable hardware accelerated decoding on windows 139 140 --disable-mediacodec disable hardware accelerated decoding on android … … EXTERNAL_LIBRARY_LIST=" 1395 1396 opengl 1396 1397 sdl 1397 1398 sdl2 1399 vaapi 1400 vaapi2 1398 1401 " 1399 1402 1400 1403 HWACCEL_AUTODETECT_LIBRARY_LIST=" 1401 1404 crystalhd 1402 1405 dxva2 1403 vaapi1404 1406 vda 1405 1407 vdpau 1406 1408 " … … USING_LIST=' 2040 2042 opengl 2041 2043 opengles 2042 2044 vaapi 2045 vaapi2 2043 2046 vdpau 2044 2047 openmax 2045 2048 mediacodec … … enable libdns_sd 2769 2772 enable libxml2 2770 2773 enable lirc 2771 2774 enable mediacodec 2775 enable vaapi 2776 enable vaapi2 2772 2777 enable mheg 2773 2778 enable mythtranscode 2774 2779 enable opengl … … enabled vaapi && 6203 6208 check_cpp_condition "va/va.h" "VA_CHECK_VERSION(1, 0, 0)" && 6204 6209 enable vaapi_1 6205 6210 6211 enabled vaapi2 && 6212 check_func_headers va/va.h vaInitialize -lva || 6213 disable vaapi2 6214 6206 6215 enabled vdpau && 6207 6216 check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || 6208 6217 disable vdpau … … ffmpeg_optset extra_cxxflags extra_ldflags target_os 7057 7066 ffmpeg_optset pkg_config prefix libdir as objcc dep_cc host_cc 7058 7067 ffmpeg_optset host_ld 7059 7068 ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid 7060 ffmpeg_optenable vdpau vaapilibxml2 libass dxva27069 ffmpeg_optenable vdpau libxml2 libass dxva2 7061 7070 ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883 7062 7071 ffmpeg_optenable crystalhd sdl2 ffplay 7063 7072 if test $target_os = "android"; then … … if test $target_os = "android"; then 7066 7075 else 7067 7076 disable mediacodec 7068 7077 fi 7069 7078 if enabled vaapi || enabled vaapi2 ; then 7079 ffopts="$ffopts --enable-vaapi" 7080 fi 7070 7081 ffmpeg_extra_cflags="$extra_cflags -w" 7071 7082 7072 7083 ## Call FFmpeg configure here … … if enabled x11 ; then 7272 7283 echo "xv support ${xv-no}" 7273 7284 echo "VDPAU support ${vdpau-no}" 7274 7285 echo "VAAPI support ${vaapi-no}" 7286 echo "VAAPI2 support ${vaapi2-no}" 7275 7287 echo "CrystalHD support ${crystalhd-no}" 7276 7288 echo "OpenMAX support ${openmax-no}" 7277 7289 if enabled openmax ; then -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 5b5fce95e88..835a53e23c7 100644
a b using namespace std; 43 43 #include "lcddevice.h" 44 44 45 45 #include "audiooutput.h" 46 #include "mythcodeccontext.h" 46 47 47 48 #ifdef USING_VDPAU 48 49 #include "videoout_vdpau.h" … … extern "C" { 70 71 #include <QtAndroidExtras> 71 72 #endif 72 73 74 #ifdef USING_VAAPI2 75 #include "vaapi2context.h" 76 #endif 77 73 78 extern "C" { 74 79 #include "libavutil/avutil.h" 75 80 #include "libavutil/error.h" … … int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic, int flags); 182 187 #ifdef USING_VAAPI 183 188 int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int flags); 184 189 #endif 190 #ifdef USING_VAAPI2 191 int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags); 192 #endif 185 193 186 194 static int determinable_frame_size(struct AVCodecContext *avctx) 187 195 { … … void AvFormatDecoder::GetDecoders(render_opts &opts) 385 393 opts.decoders->append("vaapi"); 386 394 (*opts.equiv_decoders)["vaapi"].append("dummy"); 387 395 #endif 396 #ifdef USING_VAAPI2 397 opts.decoders->append("vaapi2"); 398 (*opts.equiv_decoders)["vaapi2"].append("dummy"); 399 #endif 388 400 #ifdef USING_MEDIACODEC 389 401 opts.decoders->append("mediacodec"); 390 402 (*opts.equiv_decoders)["mediacodec"].append("dummy"); … … AvFormatDecoder::~AvFormatDecoder() 478 490 delete ttd; 479 491 delete private_dec; 480 492 delete m_h264_parser; 493 delete m_mythcodecctx; 481 494 482 495 sws_freeContext(sws_ctx); 483 496 … … enum AVPixelFormat get_format_dxva2(struct AVCodecContext *avctx, 1515 1528 } 1516 1529 #endif 1517 1530 1518 #if def USING_VAAPI1531 #if defined(USING_VAAPI) || defined(USING_VAAPI2) 1519 1532 static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt) 1520 1533 { 1521 1534 return fmt == AV_PIX_FMT_VAAPI_MOCO || 1522 1535 fmt == AV_PIX_FMT_VAAPI_IDCT || 1523 1536 fmt == AV_PIX_FMT_VAAPI_VLD; 1524 1537 } 1538 #endif 1525 1539 1540 #ifdef USING_VAAPI 1526 1541 // Declared separately to allow attribute 1527 1542 static enum AVPixelFormat get_format_vaapi(struct AVCodecContext *, 1528 1543 const enum AVPixelFormat *) MUNUSED; … … enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1549 1564 } 1550 1565 #endif 1551 1566 1567 #ifdef USING_VAAPI2 1568 static enum AVPixelFormat get_format_vaapi2(struct AVCodecContext *avctx, 1569 const enum AVPixelFormat *valid_fmts) 1570 { 1571 enum AVPixelFormat ret = AV_PIX_FMT_NONE; 1572 while (*valid_fmts != AV_PIX_FMT_NONE) { 1573 if (IS_VAAPI_PIX_FMT(*valid_fmts)) 1574 { 1575 ret = *valid_fmts; 1576 avctx->pix_fmt = ret; 1577 // Vaapi2Context::SetHwframeCtx(avctx, 20); 1578 break; 1579 } 1580 valid_fmts++; 1581 } 1582 return ret; 1583 } 1584 #endif 1585 1552 1586 #ifdef USING_MEDIACODEC 1553 1587 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx, 1554 1588 const enum AVPixelFormat *valid_fmts) … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1629 1663 else 1630 1664 #endif 1631 1665 #ifdef USING_VAAPI 1632 if (CODEC_IS_VAAPI(codec, enc) )1666 if (CODEC_IS_VAAPI(codec, enc) && codec_is_vaapi(video_codec_id)) 1633 1667 { 1634 1668 enc->get_buffer2 = get_avf_buffer_vaapi; 1635 1669 enc->get_format = get_format_vaapi; … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1644 1678 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1645 1679 } 1646 1680 else 1681 #endif 1682 #ifdef USING_VAAPI2 1683 if (codec_is_vaapi2(video_codec_id)) 1684 { 1685 enc->get_buffer2 = get_avf_buffer_vaapi2; 1686 enc->get_format = get_format_vaapi2; 1687 } 1688 else 1647 1689 #endif 1648 1690 if (codec && codec->capabilities & AV_CODEC_CAP_DR1) 1649 1691 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1659 1701 .arg(ff_codec_id_string(enc->codec_id))); 1660 1702 } 1661 1703 1704 QString deinterlacer; 1705 if (m_mythcodecctx) 1706 deinterlacer = m_mythcodecctx->getDeinterlacerName(); 1707 delete m_mythcodecctx; 1708 m_mythcodecctx = MythCodecContext::createMythCodecContext(video_codec_id); 1709 m_mythcodecctx->setPlayer(m_parent); 1710 m_mythcodecctx->setStream(stream); 1711 m_mythcodecctx->setDeinterlacer(true,deinterlacer); 1712 1713 int ret = m_mythcodecctx->HwDecoderInit(enc); 1714 if (ret < 0) 1715 { 1716 char error[AV_ERROR_MAX_STRING_SIZE]; 1717 if (ret < 0) 1718 { 1719 LOG(VB_GENERAL, LOG_ERR, LOC + 1720 QString("HwDecoderInit unable to initialize hardware decoder: %1 (%2)") 1721 .arg(av_make_error_string(error, sizeof(error), ret)) 1722 .arg(ret)); 1723 // force it to switch to software decoding 1724 averror_count = SEQ_PKT_ERR_MAX + 1; 1725 m_streams_changed = true; 1726 } 1727 } 1728 1662 1729 if (FlagIsSet(kDecodeLowRes) || FlagIsSet(kDecodeSingleThreaded) || 1663 1730 FlagIsSet(kDecodeFewBlocks) || FlagIsSet(kDecodeNoLoopFilter) || 1664 1731 FlagIsSet(kDecodeNoDecode)) … … int AvFormatDecoder::ScanStreams(bool novideo) 2536 2603 } 2537 2604 } 2538 2605 #endif // USING_MEDIACODEC 2606 #ifdef USING_VAAPI2 2607 if (!foundgpudecoder) 2608 { 2609 MythCodecID vaapi2_mcid; 2610 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; 2611 vaapi2_mcid = Vaapi2Context::GetBestSupportedCodec( 2612 &codec, dec, mpeg_version(enc->codec_id), 2613 pix_fmt); 2614 2615 if (codec_is_vaapi2(vaapi2_mcid)) 2616 { 2617 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2618 enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2619 video_codec_id = vaapi2_mcid; 2620 foundgpudecoder = true; 2621 } 2622 } 2623 #endif // USING_VAAPI2 2539 2624 } 2540 2625 // default to mpeg2 2541 2626 if (video_codec_id == kCodec_NONE) … … int AvFormatDecoder::ScanStreams(bool novideo) 2556 2641 2557 2642 use_frame_timing = false; 2558 2643 if (! private_dec 2559 && (codec_is_std(video_codec_id) || codec_is_mediacodec(video_codec_id))) 2644 && (codec_is_std(video_codec_id) 2645 || codec_is_mediacodec(video_codec_id) 2646 || codec_is_vaapi2(video_codec_id))) 2560 2647 use_frame_timing = true; 2561 2648 2562 2649 if (FlagIsSet(kDecodeSingleThreaded)) … … int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int /*flags*/) 3056 3143 } 3057 3144 #endif 3058 3145 3146 #ifdef USING_VAAPI2 3147 int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags) 3148 { 3149 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 3150 nd->directrendering = false; 3151 return avcodec_default_get_buffer2(c, pic, flags); 3152 } 3153 #endif 3154 3059 3155 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte) 3060 3156 { 3061 3157 if (!len) … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3630 3726 // into separate routines or separate threads. 3631 3727 // Also now that it always consumes a whole buffer some code 3632 3728 // in the caller may be able to be optimized. 3633 ret = avcodec_receive_frame(context, mpa_pic); 3729 3730 // FilteredReceiveFrame will call avcodec_receive_frame and 3731 // apply any codec-dependent filtering 3732 ret = m_mythcodecctx->FilteredReceiveFrame(context, mpa_pic); 3634 3733 3635 3734 if (ret == 0) 3636 3735 gotpicture = 1; … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3671 3770 QString("video avcodec_send_packet error: %1 (%2) gotpicture:%3") 3672 3771 .arg(av_make_error_string(error, sizeof(error), ret2)) 3673 3772 .arg(ret2).arg(gotpicture)); 3674 if ( ret == AVERROR_INVALIDDATA || ret2 == AVERROR_INVALIDDATA)3773 if (++averror_count > SEQ_PKT_ERR_MAX) 3675 3774 { 3676 if (++averror_count > SEQ_PKT_ERR_MAX) 3677 { 3678 // If erroring on GPU assist, try switching to software decode 3679 if (codec_is_std(video_codec_id)) 3680 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3681 else 3682 m_streams_changed = true; 3683 } 3775 // If erroring on GPU assist, try switching to software decode 3776 if (codec_is_std(video_codec_id)) 3777 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3778 else 3779 m_streams_changed = true; 3684 3780 } 3685 3781 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL) 3686 3782 m_streams_changed = true; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3840 3936 } 3841 3937 else if (!directrendering) 3842 3938 { 3939 AVFrame *tmp_frame = NULL; 3940 AVFrame *use_frame = NULL; 3941 #ifdef USING_VAAPI2 3942 if (IS_VAAPI_PIX_FMT((AVPixelFormat)mpa_pic->format)) 3943 { 3944 int ret = 0; 3945 tmp_frame = av_frame_alloc(); 3946 use_frame = tmp_frame; 3947 /* retrieve data from GPU to CPU */ 3948 if ((ret = av_hwframe_transfer_data(use_frame, mpa_pic, 0)) < 0) { 3949 LOG(VB_GENERAL, LOG_ERR, LOC 3950 + QString("Error %1 transferring the data to system memory") 3951 .arg(ret)); 3952 av_frame_free(&use_frame); 3953 return false; 3954 } 3955 } 3956 else 3957 #endif // USING_VAAPI2 3958 use_frame = mpa_pic; 3959 3843 3960 AVFrame tmppicture; 3844 3961 3845 3962 VideoFrame *xf = picframe; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3847 3964 3848 3965 unsigned char *buf = picframe->buf; 3849 3966 av_image_fill_arrays(tmppicture.data, tmppicture.linesize, 3850 buf, AV_PIX_FMT_YUV420P, context->width,3851 context->height, IMAGE_ALIGN);3967 buf, AV_PIX_FMT_YUV420P, use_frame->width, 3968 use_frame->height, IMAGE_ALIGN); 3852 3969 tmppicture.data[0] = buf + picframe->offsets[0]; 3853 3970 tmppicture.data[1] = buf + picframe->offsets[1]; 3854 3971 tmppicture.data[2] = buf + picframe->offsets[2]; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3857 3974 tmppicture.linesize[2] = picframe->pitches[2]; 3858 3975 3859 3976 QSize dim = get_video_dim(*context); 3860 sws_ctx = sws_getCachedContext(sws_ctx, context->width,3861 context->height, context->pix_fmt,3862 context->width, context->height,3977 sws_ctx = sws_getCachedContext(sws_ctx, use_frame->width, 3978 use_frame->height, (AVPixelFormat)use_frame->format, 3979 use_frame->width, use_frame->height, 3863 3980 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 3864 3981 NULL, NULL, NULL); 3865 3982 if (!sws_ctx) … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3867 3984 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate sws context"); 3868 3985 return false; 3869 3986 } 3870 sws_scale(sws_ctx, mpa_pic->data, mpa_pic->linesize, 0, dim.height(),3987 sws_scale(sws_ctx, use_frame->data, use_frame->linesize, 0, dim.height(), 3871 3988 tmppicture.data, tmppicture.linesize); 3872 3989 3873 3990 if (xf) … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3880 3997 xf->aspect = current_aspect; 3881 3998 m_parent->DiscardVideoFrame(xf); 3882 3999 } 4000 if (tmp_frame) 4001 av_frame_free(&tmp_frame); 3883 4002 } 3884 4003 else if (!picframe) 3885 4004 { … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3928 4047 // If fps has doubled due to frame-doubling deinterlace 3929 4048 // Set fps to double value. 3930 4049 double fpschange = calcfps / fps; 4050 int prior = fpsMultiplier; 3931 4051 if (fpschange > 1.9 && fpschange < 2.1) 3932 4052 fpsMultiplier = 2; 3933 4053 if (fpschange > 0.5 && fpschange < 0.6) 3934 4054 fpsMultiplier = 1; 4055 if (fpsMultiplier != prior) 4056 m_parent->SetFrameRate(fps); 3935 4057 } 3936 4058 3937 4059 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index e4dded21576..1ea3785b7db 100644
a b class AvFormatDecoder : public DecoderBase 206 206 207 207 friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, 208 208 int flags); 209 friend int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, 210 int flags); 209 211 friend void release_avf_buffer(void *opaque, uint8_t *data); 210 212 211 213 friend int open_avf(URLContext *h, const char *filename, int flags); -
mythtv/libs/libmythtv/decoderbase.cpp
diff --git a/mythtv/libs/libmythtv/decoderbase.cpp b/mythtv/libs/libmythtv/decoderbase.cpp index b8a2edef83b..788598f119a 100644
a b using namespace std; 11 11 #include "iso639.h" 12 12 #include "DVD/dvdringbuffer.h" 13 13 #include "Bluray/bdringbuffer.h" 14 #include "mythcodeccontext.h" 14 15 15 16 #define LOC QString("Dec: ") 16 17 … … DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo) 45 46 video_inverted(false), 46 47 decodeAllSubtitles(false), 47 48 // language preference 48 languagePreference(iso639_get_language_key_list()) 49 languagePreference(iso639_get_language_key_list()), 50 // this will be deleted and recreated once decoder is set up 51 m_mythcodecctx(new MythCodecContext()) 49 52 { 50 53 ResetTracks(); 51 54 tracks[kTrackTypeAudio].push_back(StreamInfo(0, 0, 0, 0, 0)); -
mythtv/libs/libmythtv/decoderbase.h
diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h index 608c1e6b336..91c8804c8de 100644
a b class RingBuffer; 18 18 class TeletextViewer; 19 19 class MythPlayer; 20 20 class AudioPlayer; 21 class MythCodecContext; 21 22 22 23 const int kDecoderProbeBufferSize = 256 * 1024; 23 24 … … class DecoderBase 270 271 bool GetVideoInverted(void) const { return video_inverted; } 271 272 void TrackTotalDuration(bool track) { trackTotalDuration = track; } 272 273 int GetfpsMultiplier(void) { return fpsMultiplier; } 274 MythCodecContext *GetMythCodecContext(void) { return m_mythcodecctx; } 273 275 274 276 protected: 275 277 virtual int AutoSelectTrack(uint type); … … class DecoderBase 359 361 StreamInfo selectedTrack[(uint)kTrackTypeCount]; 360 362 /// language preferences for auto-selection of streams 361 363 vector<int> languagePreference; 364 MythCodecContext *m_mythcodecctx; 362 365 }; 363 366 364 367 inline int DecoderBase::IncrementTrack(uint type) -
mythtv/libs/libmythtv/libmythtv.pro
diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro index 939ca20984b..8ffe3b82665 100644
a b using_frontend { 366 366 HEADERS += decoderbase.h 367 367 HEADERS += nuppeldecoder.h avformatdecoder.h 368 368 HEADERS += privatedecoder.h 369 HEADERS += mythcodeccontext.h 369 370 SOURCES += decoderbase.cpp 370 371 SOURCES += nuppeldecoder.cpp avformatdecoder.cpp 371 372 SOURCES += privatedecoder.cpp 373 SOURCES += mythcodeccontext.cpp 372 374 373 375 using_crystalhd { 374 376 DEFINES += USING_CRYSTALHD … … using_frontend { 505 507 using_opengl_video:DEFINES += USING_GLVAAPI 506 508 } 507 509 510 using_vaapi2 { 511 DEFINES += USING_VAAPI2 512 HEADERS += vaapi2context.h 513 SOURCES += vaapi2context.cpp 514 } 515 508 516 using_mediacodec { 509 517 DEFINES += USING_MEDIACODEC 510 518 HEADERS += mediacodeccontext.h -
mythtv/libs/libmythtv/mythavutil.cpp
diff --git a/mythtv/libs/libmythtv/mythavutil.cpp b/mythtv/libs/libmythtv/mythavutil.cpp index c21aec44568..d3a17ccfe17 100644
a b 10 10 #include "mythavutil.h" 11 11 #include "mythcorecontext.h" 12 12 #include "mythconfig.h" 13 #include "vaapi2context.h" 13 14 extern "C" { 14 15 #include "libswscale/swscale.h" 15 16 #include "libavfilter/avfilter.h" … … AVCodecContext *MythCodecMap::getCodecContext(const AVStream *stream, 411 412 avcodec_free_context(&avctx); 412 413 if (avctx) 413 414 { 414 av _codec_set_pkt_timebase(avctx, stream->time_base);415 avctx->pkt_timebase = stream->time_base; 415 416 streamMap.insert(stream, avctx); 416 417 } 417 418 } -
new file mythtv/libs/libmythtv/mythcodeccontext.cpp
diff --git a/mythtv/libs/libmythtv/mythcodeccontext.cpp b/mythtv/libs/libmythtv/mythcodeccontext.cpp new file mode 100644 index 00000000000..ae1c84370a5
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org> 3 // 4 // This is part of MythTV (https://www.mythtv.org) 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program. If not, see <http://www.gnu.org/licenses/>. 22 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 #include "mythcorecontext.h" 26 #include "mythlogging.h" 27 #include "mythcodeccontext.h" 28 #include "videooutbase.h" 29 #include "mythplayer.h" 30 #ifdef USING_VAAPI2 31 #include "vaapi2context.h" 32 #endif 33 34 extern "C" { 35 #include "libavutil/pixfmt.h" 36 #include "libavutil/hwcontext.h" 37 #include "libavcodec/avcodec.h" 38 #include "libavfilter/avfilter.h" 39 #include "libavfilter/buffersink.h" 40 #include "libavfilter/buffersrc.h" 41 #include "libavformat/avformat.h" 42 #include "libavutil/opt.h" 43 #include "libavutil/buffer.h" 44 } 45 46 #define LOC QString("MythCodecContext: ") 47 48 MythCodecContext::MythCodecContext() : 49 stream(NULL), 50 buffersink_ctx(NULL), 51 buffersrc_ctx(NULL), 52 filter_graph(NULL), 53 filtersInitialized(false), 54 hw_frames_ctx(NULL), 55 player(NULL), 56 ptsUsed(0), 57 doublerate(false) 58 { 59 priorPts[0] = 0; 60 priorPts[1] = 0; 61 } 62 63 MythCodecContext::~MythCodecContext() 64 { 65 CloseFilters(); 66 } 67 68 // static 69 MythCodecContext *MythCodecContext::createMythCodecContext(MythCodecID codec) 70 { 71 MythCodecContext *mctx = NULL; 72 #ifdef USING_VAAPI2 73 if (codec_is_vaapi2(codec)) 74 mctx = new Vaapi2Context(); 75 #endif 76 if (!mctx) 77 mctx = new MythCodecContext(); 78 return mctx; 79 } 80 81 // static 82 QStringList MythCodecContext::GetDeinterlacers(QString decodername) 83 { 84 QStringList ret; 85 #ifdef USING_VAAPI2 86 if (decodername == "vaapi2") 87 { 88 ret.append("vaapi2default"); 89 ret.append("vaapi2bob"); 90 ret.append("vaapi2weave"); 91 ret.append("vaapi2motion_adaptive"); 92 ret.append("vaapi2motion_compensated"); 93 ret.append("vaapi2doubleratedefault"); 94 ret.append("vaapi2doubleratebob"); 95 ret.append("vaapi2doublerateweave"); 96 ret.append("vaapi2doubleratemotion_adaptive"); 97 ret.append("vaapi2doubleratemotion_compensated"); 98 99 /* 100 Explanation of vaapi2 deinterlacing modes. 101 "mode", "Deinterlacing mode", 102 "default", "Use the highest-numbered (and therefore possibly most advanced) deinterlacing algorithm", 103 "bob", "Use the bob deinterlacing algorithm", 104 "weave", "Use the weave deinterlacing algorithm", 105 "motion_adaptive", "Use the motion adaptive deinterlacing algorithm", 106 "motion_compensated", "Use the motion compensated deinterlacing algorithm", 107 108 "rate", "Generate output at frame rate or field rate", 109 "frame", "Output at frame rate (one frame of output for each field-pair)", 110 "field", "Output at field rate (one frame of output for each field)", 111 112 "auto", "Only deinterlace fields, passing frames through unchanged", 113 1 = enabled 114 0 = disabled 115 */ 116 117 } 118 #endif 119 return ret; 120 } 121 // static - Find if a deinterlacer is codec-provided 122 bool MythCodecContext::isCodecDeinterlacer(QString decodername) 123 { 124 return (decodername.startsWith("vaapi2")); 125 } 126 127 128 // Currently this will only set up the filter after an interlaced frame. 129 // If we need other filters apart from deinterlace filters we will 130 // need to make a change here. 131 132 int MythCodecContext::FilteredReceiveFrame(AVCodecContext *ctx, AVFrame *frame) 133 { 134 int ret = 0; 135 136 while (1) 137 { 138 if (filter_graph) 139 { 140 ret = av_buffersink_get_frame(buffersink_ctx, frame); 141 if (ret >= 0) 142 { 143 if (priorPts[0] && ptsUsed == priorPts[1]) 144 { 145 frame->pts = priorPts[1] + (priorPts[1] - priorPts[0])/2; 146 frame->scte_cc_len = 0; 147 frame->atsc_cc_len = 0; 148 av_frame_remove_side_data(frame, AV_FRAME_DATA_A53_CC); 149 } 150 else 151 { 152 frame->pts = priorPts[1]; 153 ptsUsed = priorPts[1]; 154 } 155 } 156 if (ret != AVERROR(EAGAIN)) 157 break; 158 } 159 160 // EAGAIN or no filter graph 161 ret = avcodec_receive_frame(ctx, frame); 162 if (ret < 0) 163 break; 164 priorPts[0]=priorPts[1]; 165 priorPts[1]=frame->pts; 166 if (frame->interlaced_frame || filter_graph) 167 { 168 if (!filtersInitialized 169 || width != frame->width 170 || height != frame->height) 171 { 172 // bypass any frame of unknown format 173 if (frame->format < 0) 174 break; 175 ret = InitDeinterlaceFilter(ctx, frame); 176 if (ret < 0) 177 { 178 LOG(VB_GENERAL, LOG_ERR, LOC + "InitDeinterlaceFilter failed - continue without filters"); 179 break; 180 } 181 } 182 if (filter_graph) 183 { 184 ret = av_buffersrc_add_frame(buffersrc_ctx, frame); 185 if (ret < 0) 186 break; 187 } 188 else 189 break; 190 } 191 else 192 break; 193 } 194 195 return ret; 196 } 197 198 // Setup or change deinterlacer. 199 // Same usage as VideoOutBase::SetupDeinterlace 200 // enable - true to enable, false to disable 201 // name - empty to use video profile deinterlacers, otherwise 202 // use the supplied name. 203 // return true if the deinterlacer was found as a hardware deinterlacer. 204 // return false if the deinterlacer is nnt a hardware deinterlacer, 205 // and a videououtput deinterlacer should be tried instead. 206 207 bool MythCodecContext::setDeinterlacer(bool enable, QString name) 208 { 209 QMutexLocker lock(&contextLock); 210 // Code to disable interlace 211 if (!enable) 212 { 213 if (deinterlacername.isEmpty()) 214 return true; 215 else 216 { 217 deinterlacername.clear(); 218 doublerate = false; 219 filtersInitialized = false; 220 return true; 221 } 222 } 223 224 // Code to enable or change interlace 225 if (name.isEmpty()) 226 { 227 if (deinterlacername.isEmpty()) 228 { 229 VideoOutput *vo = NULL; 230 VideoDisplayProfile *vdisp_profile = NULL; 231 if (player) 232 vo = player->GetVideoOutput(); 233 if (vo) 234 vdisp_profile = vo->GetProfile(); 235 if (vdisp_profile) 236 name = vdisp_profile->GetFilteredDeint(QString()); 237 } 238 else 239 name = deinterlacername; 240 } 241 bool ret = true; 242 if (!isCodecDeinterlacer(name)) 243 name.clear(); 244 245 if (name.isEmpty()) 246 ret = false; 247 248 if (deinterlacername == name) 249 return ret; 250 251 deinterlacername = name; 252 doublerate = deinterlacername.contains("doublerate"); 253 filtersInitialized = false; 254 return ret; 255 } 256 257 bool MythCodecContext::BestDeint(void) 258 { 259 deinterlacername.clear(); 260 doublerate = false; 261 return setDeinterlacer(true); 262 } 263 264 bool MythCodecContext::FallbackDeint(void) 265 { 266 return setDeinterlacer(true,GetFallbackDeint()); 267 } 268 269 QString MythCodecContext::GetFallbackDeint(void) 270 { 271 272 VideoOutput *vo = NULL; 273 VideoDisplayProfile *vdisp_profile = NULL; 274 if (player) 275 vo = player->GetVideoOutput(); 276 if (vo) 277 vdisp_profile = vo->GetProfile(); 278 if (vdisp_profile) 279 return vdisp_profile->GetFallbackDeinterlacer(); 280 return QString(); 281 } 282 283 int MythCodecContext::InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame) 284 { 285 QMutexLocker lock(&contextLock); 286 char args[512]; 287 int ret = 0; 288 CloseFilters(); 289 width = frame->width; 290 height = frame->height; 291 filtersInitialized = true; 292 if (!player || !stream) 293 { 294 LOG(VB_GENERAL, LOG_ERR, LOC + "Player or stream is not set up in MythCodecContext"); 295 return -1; 296 } 297 if (doublerate && !player->CanSupportDoubleRate()) 298 { 299 QString request = deinterlacername; 300 deinterlacername = GetFallbackDeint(); 301 LOG(VB_PLAYBACK, LOG_INFO, LOC 302 + QString("Deinterlacer %1 requires double rate, switching to %2 instead.") 303 .arg(request).arg(deinterlacername)); 304 if (!isCodecDeinterlacer(deinterlacername)) 305 deinterlacername.clear(); 306 doublerate = deinterlacername.contains("doublerate"); 307 308 // if the fallback is a non-vaapi - deinterlace will be turned off 309 // and the videoout methods can take over. 310 } 311 QString filters; 312 if (isValidDeinterlacer(deinterlacername)) 313 filters = GetDeinterlaceFilter(); 314 315 if (filters.isEmpty()) 316 { 317 LOG(VB_GENERAL, LOG_INFO, LOC + 318 "Disabled hardware decoder based deinterlacer."); 319 return ret; 320 } 321 const AVFilter *buffersrc = avfilter_get_by_name("buffer"); 322 const AVFilter *buffersink = avfilter_get_by_name("buffersink"); 323 AVFilterInOut *outputs = avfilter_inout_alloc(); 324 AVFilterInOut *inputs = avfilter_inout_alloc(); 325 AVRational time_base = stream->time_base; 326 AVBufferSrcParameters* params = NULL; 327 328 filter_graph = avfilter_graph_alloc(); 329 if (!outputs || !inputs || !filter_graph) 330 { 331 ret = AVERROR(ENOMEM); 332 goto end; 333 } 334 335 /* buffer video source: the decoded frames from the decoder will be inserted here. */ 336 snprintf(args, sizeof(args), 337 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 338 frame->width, frame->height, frame->format, // ctx->pix_fmt, 339 time_base.num, time_base.den, 340 ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den); 341 342 // isInterlaced = frame->interlaced_frame; 343 344 ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", 345 args, NULL, filter_graph); 346 if (ret < 0) 347 { 348 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer source"); 349 goto end; 350 } 351 352 params = av_buffersrc_parameters_alloc(); 353 if (hw_frames_ctx) 354 av_buffer_unref(&hw_frames_ctx); 355 hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); 356 params->hw_frames_ctx = hw_frames_ctx; 357 358 ret = av_buffersrc_parameters_set(buffersrc_ctx, params); 359 360 if (ret < 0) 361 { 362 LOG(VB_GENERAL, LOG_ERR, LOC + "av_buffersrc_parameters_set failed"); 363 goto end; 364 } 365 366 av_freep(¶ms); 367 368 /* buffer video sink: to terminate the filter chain. */ 369 ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", 370 NULL, NULL, filter_graph); 371 if (ret < 0) 372 { 373 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer sink"); 374 goto end; 375 } 376 377 /* 378 * Set the endpoints for the filter graph. The filter_graph will 379 * be linked to the graph described by filters_descr. 380 */ 381 382 /* 383 * The buffer source output must be connected to the input pad of 384 * the first filter described by filters_descr; since the first 385 * filter input label is not specified, it is set to "in" by 386 * default. 387 */ 388 outputs->name = av_strdup("in"); 389 outputs->filter_ctx = buffersrc_ctx; 390 outputs->pad_idx = 0; 391 outputs->next = NULL; 392 393 /* 394 * The buffer sink input must be connected to the output pad of 395 * the last filter described by filters_descr; since the last 396 * filter output label is not specified, it is set to "out" by 397 * default. 398 */ 399 inputs->name = av_strdup("out"); 400 inputs->filter_ctx = buffersink_ctx; 401 inputs->pad_idx = 0; 402 inputs->next = NULL; 403 404 if ((ret = avfilter_graph_parse_ptr(filter_graph, filters.toLocal8Bit(), 405 &inputs, &outputs,0)) < 0) 406 { 407 LOG(VB_GENERAL, LOG_ERR, LOC 408 + QString("avfilter_graph_parse_ptr failed for %1").arg(filters)); 409 goto end; 410 } 411 412 if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) 413 { 414 LOG(VB_GENERAL, LOG_ERR, LOC 415 + QString("avfilter_graph_config failed")); 416 goto end; 417 } 418 419 LOG(VB_GENERAL, LOG_INFO, LOC + 420 QString("Enabled hardware decoder based deinterlace filter '%1': <%2>.") 421 .arg(deinterlacername).arg(filters)); 422 end: 423 if (ret < 0) 424 { 425 avfilter_graph_free(&filter_graph); 426 filter_graph = NULL; 427 doublerate = false; 428 } 429 avfilter_inout_free(&inputs); 430 avfilter_inout_free(&outputs); 431 432 return ret; 433 } 434 435 void MythCodecContext::CloseFilters() 436 { 437 avfilter_graph_free(&filter_graph); 438 filter_graph = NULL; 439 buffersink_ctx = NULL; 440 buffersrc_ctx = NULL; 441 filtersInitialized = false; 442 ptsUsed = 0; 443 priorPts[0] = 0; 444 priorPts[1] = 0; 445 // isInterlaced = 0; 446 width = 0; 447 height = 0; 448 449 if (hw_frames_ctx) 450 av_buffer_unref(&hw_frames_ctx); 451 } 452 No newline at end of file -
new file mythtv/libs/libmythtv/mythcodeccontext.h
diff --git a/mythtv/libs/libmythtv/mythcodeccontext.h b/mythtv/libs/libmythtv/mythcodeccontext.h new file mode 100644 index 00000000000..234797aeac4
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org> 3 // 4 // This is part of MythTV (https://www.mythtv.org) 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program. If not, see <http://www.gnu.org/licenses/>. 22 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 26 #ifndef MYTHCODECONTEXT_H 27 #define MYTHCODECONTEXT_H 28 29 struct AVCodecContext; 30 struct AVFrame; 31 struct AVStream; 32 struct AVFilterContext; 33 struct AVFilterGraph; 34 struct AVBufferRef; 35 class MythPlayer; 36 37 #include "mythtvexp.h" 38 #include "mythcodecid.h" 39 40 class MTV_PUBLIC MythCodecContext 41 { 42 public: 43 MythCodecContext(void); 44 virtual ~MythCodecContext(); 45 static MythCodecContext* createMythCodecContext(MythCodecID codec); 46 virtual int HwDecoderInit(AVCodecContext * /*ctx*/) { return 0; } 47 void setStream(AVStream *initStream) { stream = initStream; } 48 virtual int FilteredReceiveFrame(AVCodecContext *ctx, AVFrame *frame); 49 static QStringList GetDeinterlacers(QString decodername); 50 static bool isCodecDeinterlacer(QString decodername); 51 virtual QStringList GetDeinterlacers(void) { return QStringList(); } 52 virtual QString GetDeinterlaceFilter() { return QString(); } 53 void setPlayer(MythPlayer *tPlayer) { player = tPlayer; } 54 bool setDeinterlacer(bool enable, QString name = QString()); 55 bool isDeinterlacing(void) { return filter_graph != NULL;} 56 QString getDeinterlacerName(void) { return deinterlacername; } 57 bool BestDeint(void); 58 bool FallbackDeint(void); 59 bool getDoubleRate(void) { return doublerate; } 60 QString GetFallbackDeint(void); 61 62 protected: 63 virtual bool isValidDeinterlacer(QString /*name*/) { return false; } 64 int InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame); 65 void CloseFilters(); 66 AVStream* stream; 67 AVFilterContext *buffersink_ctx; 68 AVFilterContext *buffersrc_ctx; 69 AVFilterGraph *filter_graph; 70 bool filtersInitialized; 71 AVBufferRef *hw_frames_ctx; 72 MythPlayer *player; 73 int64_t priorPts[2]; 74 int64_t ptsUsed; 75 int width; 76 int height; 77 QString deinterlacername; 78 QMutex contextLock; 79 bool doublerate; 80 }; 81 82 #endif // MYTHCODECCONTEXT_H 83 No newline at end of file -
mythtv/libs/libmythtv/mythcodecid.cpp
diff --git a/mythtv/libs/libmythtv/mythcodecid.cpp b/mythtv/libs/libmythtv/mythcodecid.cpp index b2023512b5f..cff4ba03585 100644
a b QString toString(MythCodecID codecid) 123 123 case kCodec_HEVC_MEDIACODEC: 124 124 return "HEVC MEDIACODEC"; 125 125 126 case kCodec_MPEG1_VAAPI2: 127 return "MPEG1 VAAPI2"; 128 case kCodec_MPEG2_VAAPI2: 129 return "MPEG2 VAAPI2"; 130 case kCodec_H263_VAAPI2: 131 return "H.263 VAAPI2"; 132 case kCodec_MPEG4_VAAPI2: 133 return "MPEG4 VAAPI2"; 134 case kCodec_H264_VAAPI2: 135 return "H.264 VAAPI2"; 136 case kCodec_VC1_VAAPI2: 137 return "VC1 VAAPI2"; 138 case kCodec_WMV3_VAAPI2: 139 return "WMV3 VAAPI2"; 140 case kCodec_VP8_VAAPI2: 141 return "VP8 VAAPI2"; 142 case kCodec_VP9_VAAPI2: 143 return "VP9 VAAPI2"; 144 case kCodec_HEVC_VAAPI2: 145 return "HEVC VAAPI2"; 146 126 147 default: 127 148 break; 128 149 } … … int myth2av_codecid(MythCodecID codec_id, bool &vdpau) 305 326 ret = AV_CODEC_ID_HEVC; 306 327 break; 307 328 329 case kCodec_MPEG1_VAAPI2: 330 ret = AV_CODEC_ID_MPEG1VIDEO; 331 break; 332 case kCodec_MPEG2_VAAPI2: 333 ret = AV_CODEC_ID_MPEG2VIDEO; 334 break; 335 case kCodec_H263_VAAPI2: 336 ret = AV_CODEC_ID_H263; 337 break; 338 case kCodec_MPEG4_VAAPI2: 339 ret = AV_CODEC_ID_MPEG4; 340 break; 341 case kCodec_H264_VAAPI2: 342 ret = AV_CODEC_ID_H264; 343 break; 344 case kCodec_VC1_VAAPI2: 345 ret = AV_CODEC_ID_VC1; 346 break; 347 case kCodec_WMV3_VAAPI2: 348 ret = AV_CODEC_ID_WMV3; 349 break; 350 case kCodec_VP8_VAAPI2: 351 ret = AV_CODEC_ID_VP8; 352 break; 353 case kCodec_VP9_VAAPI2: 354 ret = AV_CODEC_ID_VP9; 355 break; 356 case kCodec_HEVC_VAAPI2: 357 ret = AV_CODEC_ID_HEVC; 358 break; 359 308 360 default: 309 361 LOG(VB_GENERAL, LOG_ERR, 310 362 QString("Error: MythCodecID %1 has not been " … … QString get_encoding_type(MythCodecID codecid) 356 408 case kCodec_MPEG1_VAAPI: 357 409 case kCodec_MPEG1_DXVA2: 358 410 case kCodec_MPEG1_MEDIACODEC: 411 case kCodec_MPEG1_VAAPI2: 359 412 case kCodec_MPEG2: 360 413 case kCodec_MPEG2_VDPAU: 361 414 case kCodec_MPEG2_VAAPI: 362 415 case kCodec_MPEG2_DXVA2: 363 416 case kCodec_MPEG2_MEDIACODEC: 417 case kCodec_MPEG2_VAAPI2: 364 418 return "MPEG-2"; 365 419 366 420 case kCodec_H263: … … QString get_encoding_type(MythCodecID codecid) 368 422 case kCodec_H263_VAAPI: 369 423 case kCodec_H263_DXVA2: 370 424 case kCodec_H263_MEDIACODEC: 425 case kCodec_H263_VAAPI2: 371 426 return "H.263"; 372 427 373 428 case kCodec_NUV_MPEG4: … … QString get_encoding_type(MythCodecID codecid) 376 431 case kCodec_MPEG4_VAAPI: 377 432 case kCodec_MPEG4_DXVA2: 378 433 case kCodec_MPEG4_MEDIACODEC: 434 case kCodec_MPEG4_VAAPI2: 379 435 return "MPEG-4"; 380 436 381 437 case kCodec_H264: … … QString get_encoding_type(MythCodecID codecid) 383 439 case kCodec_H264_VAAPI: 384 440 case kCodec_H264_DXVA2: 385 441 case kCodec_H264_MEDIACODEC: 442 case kCodec_H264_VAAPI2: 386 443 return "H.264"; 387 444 388 445 case kCodec_VC1: … … QString get_encoding_type(MythCodecID codecid) 390 447 case kCodec_VC1_VAAPI: 391 448 case kCodec_VC1_DXVA2: 392 449 case kCodec_VC1_MEDIACODEC: 450 case kCodec_VC1_VAAPI2: 393 451 return "VC-1"; 394 452 395 453 case kCodec_WMV3: … … QString get_encoding_type(MythCodecID codecid) 397 455 case kCodec_WMV3_VAAPI: 398 456 case kCodec_WMV3_DXVA2: 399 457 case kCodec_WMV3_MEDIACODEC: 458 case kCodec_WMV3_VAAPI2: 400 459 return "WMV3"; 401 460 402 461 case kCodec_VP8: … … QString get_encoding_type(MythCodecID codecid) 404 463 case kCodec_VP8_VAAPI: 405 464 case kCodec_VP8_DXVA2: 406 465 case kCodec_VP8_MEDIACODEC: 466 case kCodec_VP8_VAAPI2: 407 467 return "VP8"; 408 468 409 469 case kCodec_VP9: … … QString get_encoding_type(MythCodecID codecid) 411 471 case kCodec_VP9_VAAPI: 412 472 case kCodec_VP9_DXVA2: 413 473 case kCodec_VP9_MEDIACODEC: 474 case kCodec_VP9_VAAPI2: 414 475 return "VP8"; 415 476 416 477 case kCodec_HEVC: … … QString get_encoding_type(MythCodecID codecid) 418 479 case kCodec_HEVC_VAAPI: 419 480 case kCodec_HEVC_DXVA2: 420 481 case kCodec_HEVC_MEDIACODEC: 482 case kCodec_HEVC_VAAPI2: 421 483 return "HEVC"; 422 484 423 485 case kCodec_NONE: … … QString get_encoding_type(MythCodecID codecid) 426 488 case kCodec_VAAPI_END: 427 489 case kCodec_DXVA2_END: 428 490 case kCodec_MEDIACODEC_END: 491 case kCodec_VAAPI2_END: 429 492 return QString(); 430 493 } 431 494 … … QString get_decoder_name(MythCodecID codec_id) 446 509 if (codec_is_mediacodec(codec_id)) 447 510 return "mediacodec"; 448 511 512 if (codec_is_vaapi2(codec_id)) 513 return "vaapi2"; 514 449 515 return "ffmpeg"; 450 516 } -
mythtv/libs/libmythtv/mythcodecid.h
diff --git a/mythtv/libs/libmythtv/mythcodecid.h b/mythtv/libs/libmythtv/mythcodecid.h index ce3620467d9..f1d225d4beb 100644
a b typedef enum 91 91 92 92 kCodec_MEDIACODEC_END, 93 93 94 kCodec_VAAPI2_BEGIN = kCodec_MEDIACODEC_END, 95 96 kCodec_MPEG1_VAAPI2, 97 kCodec_MPEG2_VAAPI2, 98 kCodec_H263_VAAPI2, 99 kCodec_MPEG4_VAAPI2, 100 kCodec_H264_VAAPI2, 101 kCodec_VC1_VAAPI2, 102 kCodec_WMV3_VAAPI2, 103 kCodec_VP8_VAAPI2, 104 kCodec_VP9_VAAPI2, 105 kCodec_HEVC_VAAPI2, 106 107 kCodec_VAAPI2_END, 108 94 109 } MythCodecID; 95 110 96 111 // MythCodecID convenience functions … … typedef enum 113 128 (id == kCodec_VC1_DXVA2))) 114 129 #define codec_is_mediacodec(id) ((id > kCodec_MEDIACODEC_BEGIN) && \ 115 130 (id < kCodec_MEDIACODEC_END)) 131 #define codec_is_vaapi2(id) ((id > kCodec_VAAPI2_BEGIN) && \ 132 (id < kCodec_VAAPI2_END)) 116 133 117 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id) )134 #define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id) || codec_is_vaapi2(id)) 118 135 119 136 QString get_encoding_type(MythCodecID codecid); 120 137 QString get_decoder_name(MythCodecID codec_id); … … int mpeg_version(int codec_id); 156 173 #define CODEC_IS_MEDIACODEC(codec) (0) 157 174 #endif 158 175 159 #define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_VDPAU(codec) || \160 CODEC_IS_VAAPI(codec, enc) || \161 CODEC_IS_DXVA2(codec, enc) || \162 CODEC_IS_MEDIACODEC(codec))163 164 176 #endif // _MYTH_CODEC_ID_H_ -
mythtv/libs/libmythtv/mythplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index e4e0bd83ead..f1b02571f31 100644
a b using namespace std; 53 53 #include "mythuiactions.h" // for ACTION_LEFT, ACTION_RIGHT, etc 54 54 #include "ringbuffer.h" // for RingBuffer, etc 55 55 #include "tv_actions.h" // for ACTION_BIGJUMPFWD, etc 56 #include "mythcodeccontext.h" 56 57 57 58 extern "C" { 58 59 #include "vsync.h" … … void MythPlayer::FallbackDeint(void) 676 677 m_double_process = false; 677 678 678 679 if (videoOutput) 679 videoOutput->FallbackDeint(); 680 { 681 videoOutput->SetupDeinterlace(false); 682 bool hwset = decoder->GetMythCodecContext()->FallbackDeint(); 683 if (!hwset) 684 videoOutput->FallbackDeint(); 685 } 680 686 } 681 687 682 688 void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock) … … void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock) 715 721 716 722 if ((m_scan_tracker % 400) == 0) 717 723 { 718 QString type = (m_scan_tracker < 0) ? "progressive" : "interlaced"; 724 QString type; 725 // = (m_scan_tracker < 0) ? "progressive" : "interlaced"; 726 if (m_scan_tracker < 0) 727 { 728 if (decoder->GetMythCodecContext()->isDeinterlacing()) 729 type = "codec-deinterlaced"; 730 else 731 type = "progressive"; 732 } 733 else 734 type = "interlaced"; 735 719 736 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("%1 %2 frames seen.") 720 737 .arg(abs(m_scan_tracker)).arg(type)); 721 738 } … … void MythPlayer::SetScanType(FrameScanType scan) 763 780 764 781 if (interlaced) 765 782 { 766 m_deint_possible = videoOutput->SetDeinterlacingEnabled(true);767 if (!m_deint_possible)768 {769 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to enabledeinterlacing");770 m_scan = scan;771 return;772 }783 m_deint_possible = videoOutput->SetDeinterlacingEnabled(true); 784 if (!m_deint_possible) 785 { 786 LOG(VB_GENERAL, LOG_INFO, LOC + "Unable to enable Video Output based deinterlacing"); 787 m_scan = scan; 788 return; 789 } 773 790 if (videoOutput->NeedsDoubleFramerate()) 774 791 { 775 792 m_double_framerate = true; … … void MythPlayer::SetScanType(FrameScanType scan) 782 799 } 783 800 } 784 801 m_double_process = videoOutput->IsExtraProcessingRequired(); 785 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Enabled deinterlacing");802 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Enabled Video Output based deinterlacing"); 786 803 } 787 804 else 788 805 { … … void MythPlayer::SetScanType(FrameScanType scan) 791 808 m_double_process = false; 792 809 m_double_framerate = false; 793 810 videoOutput->SetDeinterlacingEnabled(false); 794 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled deinterlacing");811 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled Video Output based deinterlacing"); 795 812 } 796 813 } 797 814 … … void MythPlayer::SetVideoParams(int width, int height, double fps, 849 866 m_scan_tracker = (m_scan == kScan_Interlaced) ? 2 : 0; 850 867 } 851 868 869 870 void MythPlayer::SetFrameRate(double fps) 871 { 872 video_frame_rate = fps; 873 float temp_speed = (play_speed == 0.0f) ? 874 audio.GetStretchFactor() : play_speed; 875 SetFrameInterval(kScan_Progressive, 876 1.0 / (video_frame_rate * temp_speed)); 877 } 878 852 879 void MythPlayer::SetFileLength(int total, int frames) 853 880 { 854 881 totalLength = total; … … void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 1889 1916 else 1890 1917 { 1891 1918 dropframe = true; 1892 dbg = "A/V predict drop frame, "; 1919 dbg = QString("A/V predict drop frame, refreshrate %1, avsync_predictor %2, diverge %3, ") 1920 .arg(refreshrate).arg(avsync_predictor).arg(diverge); 1893 1921 } 1894 1922 } 1895 1923 … … void MythPlayer::SetBuffering(bool new_buffering) 2182 2210 } 2183 2211 } 2184 2212 2213 // For debugging playback set this to increase the timeout so that 2214 // playback does not fail if stepping through code. 2215 // Set PREBUFFERDEBUG to any value and you will get 30 minutes. 2216 static char *preBufferDebug = getenv("PREBUFFERDEBUG"); 2217 2185 2218 bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2186 2219 { 2187 2220 if (!videoOutput) … … bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2247 2280 audio.Pause(false); 2248 2281 } 2249 2282 } 2250 if ((waited_for > 500) && !videoOutput->EnoughFreeFrames()) 2283 int msecs = 500; 2284 if (preBufferDebug) 2285 msecs = 1800000; 2286 if ((waited_for > msecs /*500*/) && !videoOutput->EnoughFreeFrames()) 2251 2287 { 2252 2288 LOG(VB_GENERAL, LOG_NOTICE, LOC + 2253 2289 "Timed out waiting for frames, and" … … bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2257 2293 // to recover from serious problems if frames get leaked. 2258 2294 DiscardVideoFrames(true); 2259 2295 } 2260 if (waited_for > 30000) // 30 seconds for internet streamed media 2296 msecs = 30000; 2297 if (preBufferDebug) 2298 msecs = 1800000; 2299 if (waited_for > msecs /*30000*/) // 30 seconds for internet streamed media 2261 2300 { 2262 2301 LOG(VB_GENERAL, LOG_ERR, LOC + 2263 2302 "Waited too long for decoder to fill video buffers. Exiting.."); … … void MythPlayer::ForceDeinterlacer(const QString &overridefilter) 2382 2421 bool normal = play_speed > 0.99f && play_speed < 1.01f && normal_speed; 2383 2422 videofiltersLock.lock(); 2384 2423 2385 m_double_framerate = 2386 videoOutput->SetupDeinterlace(true, overridefilter) && 2387 videoOutput->NeedsDoubleFramerate(); 2388 m_double_process = videoOutput->IsExtraProcessingRequired(); 2389 2390 if (m_double_framerate && (!CanSupportDoubleRate() || !normal)) 2424 bool hwset = decoder->GetMythCodecContext()->setDeinterlacer(true, overridefilter); 2425 if (hwset) 2426 { 2427 m_double_framerate = false; 2428 m_double_process = false; 2429 videoOutput->SetupDeinterlace(false); 2430 } 2431 else 2432 { 2433 m_double_framerate = 2434 videoOutput->SetupDeinterlace(true, overridefilter) && 2435 videoOutput->NeedsDoubleFramerate(); 2436 m_double_process = videoOutput->IsExtraProcessingRequired(); 2437 } 2438 if ((decoder->GetMythCodecContext()->getDoubleRate() || m_double_framerate) 2439 && (!CanSupportDoubleRate() || !normal)) 2391 2440 FallbackDeint(); 2392 2441 2393 2442 videofiltersLock.unlock(); … … void MythPlayer::VideoStart(void) 2480 2529 } 2481 2530 else if (videoOutput) 2482 2531 { 2483 // Set up deinterlacing in the video output method 2484 m_double_framerate = 2485 (videoOutput->SetupDeinterlace(true) && 2486 videoOutput->NeedsDoubleFramerate()); 2487 2488 m_double_process = videoOutput->IsExtraProcessingRequired(); 2532 bool hwset = decoder->GetMythCodecContext()->setDeinterlacer(true); 2533 if (hwset) 2534 videoOutput->SetupDeinterlace(false); 2535 else 2536 { 2537 // Set up deinterlacing in the video output method 2538 m_double_framerate = 2539 (videoOutput->SetupDeinterlace(true) && 2540 videoOutput->NeedsDoubleFramerate()); 2489 2541 2542 m_double_process = videoOutput->IsExtraProcessingRequired(); 2543 } 2490 2544 videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int); 2491 2545 2492 2546 // Make sure video sync can do it … … void MythPlayer::ChangeSpeed(void) 3808 3862 kScan_Intr2ndField == m_scan); 3809 3863 3810 3864 videofiltersLock.lock(); 3811 if (m_double_framerate && !play_1) 3812 videoOutput->FallbackDeint(); 3813 else if (!m_double_framerate && CanSupportDoubleRate() && play_1 && 3814 inter) 3815 videoOutput->BestDeint(); 3865 bool doublerate = m_double_framerate || decoder->GetMythCodecContext()->getDoubleRate(); 3866 if (doublerate && !play_1) 3867 { 3868 bool hwdeint = decoder->GetMythCodecContext()->FallbackDeint(); 3869 if (!hwdeint) 3870 videoOutput->FallbackDeint(); 3871 } 3872 else if (!m_double_framerate && CanSupportDoubleRate() && play_1 3873 && (inter || decoder->GetMythCodecContext()->isDeinterlacing())) 3874 { 3875 videoOutput->SetupDeinterlace(false); 3876 bool hwdeint = decoder->GetMythCodecContext()->BestDeint(); 3877 if (!hwdeint) 3878 videoOutput->BestDeint(); 3879 } 3816 3880 videofiltersLock.unlock(); 3817 3818 3881 m_double_framerate = videoOutput->NeedsDoubleFramerate(); 3819 3882 m_double_process = videoOutput->IsExtraProcessingRequired(); 3820 3883 } … … void MythPlayer::SetDecoder(DecoderBase *dec) 5502 5565 decoder = dec; 5503 5566 else 5504 5567 { 5568 // Copy the deinterlacer name to the new decoder. 5505 5569 DecoderBase *d = decoder; 5506 5570 decoder = dec; 5571 if (d && decoder) 5572 { 5573 QString deinterlacer = d->GetMythCodecContext()->getDeinterlacerName(); 5574 decoder->GetMythCodecContext()->setDeinterlacer(true,deinterlacer); 5575 } 5507 5576 delete d; 5508 5577 } 5509 5578 decoder_change_lock.unlock(); -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index a17364522be..fd4741e1db7 100644
a b class MTV_PUBLIC MythPlayer 166 166 void SetVideoResize(const QRect &videoRect); 167 167 void EnableFrameRateMonitor(bool enable = false); 168 168 void ForceDeinterlacer(const QString &override = QString()); 169 void SetFrameRate(double fps); 169 170 170 171 // Gets 171 172 QSize GetVideoBufferSize(void) const { return video_dim; } … … class MTV_PUBLIC MythPlayer 240 241 int &vw, int &vh, float &ar); 241 242 InteractiveTV *GetInteractiveTV(void); 242 243 VideoOutput *GetVideoOutput(void) { return videoOutput; } 244 MythCodecContext *GetMythCodecContext(void) { return decoder->GetMythCodecContext(); } 243 245 244 246 // Title stuff 245 247 virtual bool SwitchTitle(int /*title*/) { return false; } -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index 5ade8680bcc..b381bf6e9fc 100644
a b using namespace std; 78 78 #include "programtypes.h" 79 79 #include "ringbuffer.h" // for RingBuffer, etc 80 80 #include "tv_actions.h" // for ACTION_TOGGLESLEEP, etc 81 #include "mythcodeccontext.h" 81 82 82 83 #if ! HAVE_ROUND 83 84 #define round(x) ((int) ((x) + 0.5)) … … bool TV::MenuItemDisplayPlayback(const MenuItemContext &c) 11767 11768 } 11768 11769 else if (matchesGroup(actionName, "DEINTERLACER_", category, prefix)) 11769 11770 { 11770 if (m_tvm_scan_type != kScan_Progressive) 11771 if (m_tvm_scan_type != kScan_Progressive 11772 || ctx->player->GetMythCodecContext()->isDeinterlacing()) 11771 11773 { 11772 11774 foreach (QString deint, m_tvm_deinterlacers) 11773 11775 { … … void TV::PlaybackMenuInit(const MenuBase &menu) 12463 12465 m_tvm_subs_havetext = ctx->player->HasTextSubtitles(); 12464 12466 m_tvm_subs_forcedon = ctx->player->GetAllowForcedSubtitles(); 12465 12467 ctx->player->GetVideoOutput()->GetDeinterlacers(m_tvm_deinterlacers); 12466 m_tvm_currentdeinterlacer = 12467 ctx->player->GetVideoOutput()->GetDeinterlacer(); 12468 QStringList decoderdeints 12469 = ctx->player->GetMythCodecContext()->GetDeinterlacers(); 12470 m_tvm_deinterlacers.append(decoderdeints); 12471 m_tvm_currentdeinterlacer 12472 = ctx->player->GetMythCodecContext()->getDeinterlacerName(); 12473 if (m_tvm_currentdeinterlacer.isEmpty()) 12474 m_tvm_currentdeinterlacer = 12475 ctx->player->GetVideoOutput()->GetDeinterlacer(); 12468 12476 if (m_tvm_visual) 12469 12477 m_tvm_visualisers = ctx->player->GetVisualiserList(); 12470 12478 VideoOutput *vo = ctx->player->GetVideoOutput(); -
new file mythtv/libs/libmythtv/vaapi2context.cpp
diff --git a/mythtv/libs/libmythtv/vaapi2context.cpp b/mythtv/libs/libmythtv/vaapi2context.cpp new file mode 100644 index 00000000000..cf727b02be6
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org> 3 // 4 // This is part of MythTV (https://www.mythtv.org) 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program. If not, see <http://www.gnu.org/licenses/>. 22 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 #include "mythcorecontext.h" 26 #include "mythlogging.h" 27 #include "vaapi2context.h" 28 #include "videooutbase.h" 29 #include "mythplayer.h" 30 31 extern "C" { 32 #include "libavutil/pixfmt.h" 33 #include "libavutil/hwcontext.h" 34 #include "libavcodec/avcodec.h" 35 } 36 37 #define LOC QString("VAAPI2: ") 38 39 Vaapi2Context::Vaapi2Context() : 40 MythCodecContext() 41 { 42 43 } 44 45 MythCodecID Vaapi2Context::GetBestSupportedCodec( 46 AVCodec **ppCodec, 47 const QString &decoder, 48 uint stream_type, 49 AVPixelFormat &pix_fmt) 50 { 51 enum AVHWDeviceType type = AV_HWDEVICE_TYPE_VAAPI; 52 53 AVPixelFormat fmt = AV_PIX_FMT_NONE; 54 if (decoder == "vaapi2") 55 { 56 for (int i = 0;; i++) { 57 const AVCodecHWConfig *config = avcodec_get_hw_config(*ppCodec, i); 58 if (!config) { 59 LOG(VB_PLAYBACK, LOG_INFO, LOC + 60 QString("Decoder %1 does not support device type %2.") 61 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 62 break; 63 } 64 if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && 65 config->device_type == type) { 66 fmt = config->pix_fmt; 67 break; 68 } 69 } 70 } 71 if (fmt == AV_PIX_FMT_NONE) 72 return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1)); 73 else 74 { 75 LOG(VB_PLAYBACK, LOG_INFO, LOC + 76 QString("Decoder %1 supports device type %2.") 77 .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type))); 78 pix_fmt = fmt; 79 return (MythCodecID)(kCodec_MPEG1_VAAPI2 + (stream_type - 1)); 80 } 81 } 82 83 // const char *filter_descr = "scale=78:24,transpose=cclock"; 84 /* other way: 85 scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively 86 */ 87 88 int Vaapi2Context::HwDecoderInit(AVCodecContext *ctx) 89 { 90 int ret = 0; 91 AVBufferRef *hw_device_ctx = NULL; 92 93 const char *device = NULL; 94 QString vaapiDevice = gCoreContext->GetSetting("VAAPIDevice"); 95 if (!vaapiDevice.isEmpty()) 96 { 97 device = vaapiDevice.toLocal8Bit().constData(); 98 } 99 100 ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, 101 device, NULL, 0); 102 if (ret < 0) 103 { 104 char error[AV_ERROR_MAX_STRING_SIZE]; 105 LOG(VB_GENERAL, LOG_ERR, LOC + 106 QString("av_hwdevice_ctx_create Device = <%3> error: %1 (%2)") 107 .arg(av_make_error_string(error, sizeof(error), ret)) 108 .arg(ret).arg(vaapiDevice)); 109 } 110 else 111 { 112 ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx); 113 av_buffer_unref(&hw_device_ctx); 114 } 115 116 return ret; 117 } 118 119 QString Vaapi2Context::GetDeinterlaceFilter() 120 { 121 // example filter - deinterlace_vaapi=mode=default:rate=frame:auto=1 122 // example deinterlacername - vaapi2doubleratemotion_compensated 123 QString ret; 124 QString rate="frame"; 125 if (!isValidDeinterlacer(deinterlacername)) 126 return ret; 127 QString filtername = deinterlacername; 128 filtername.remove(0,6); //remove "vaapi2" 129 if (filtername.startsWith("doublerate")) 130 { 131 rate="field"; 132 filtername.remove(0,10); // remove "doublerate" 133 } 134 ret=QString("deinterlace_vaapi=mode=%1:rate=%2:auto=1") 135 .arg(filtername).arg(rate); 136 137 return ret; 138 } 139 140 bool Vaapi2Context::isValidDeinterlacer(QString filtername) 141 { 142 return filtername.startsWith("vaapi2"); 143 } 144 145 QStringList Vaapi2Context::GetDeinterlacers(void) 146 { 147 return MythCodecContext::GetDeinterlacers("vaapi2"); 148 } -
new file mythtv/libs/libmythtv/vaapi2context.h
diff --git a/mythtv/libs/libmythtv/vaapi2context.h b/mythtv/libs/libmythtv/vaapi2context.h new file mode 100644 index 00000000000..05562f0e238
- + 1 ////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org> 3 // 4 // This is part of MythTV (https://www.mythtv.org) 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program. If not, see <http://www.gnu.org/licenses/>. 22 // 23 ////////////////////////////////////////////////////////////////////////////// 24 25 26 #ifndef VAAPI2CONTEXT_H 27 #define VAAPI2CONTEXT_H 28 29 #include "mythtvexp.h" 30 #include "mythcodecid.h" 31 #include "mythcodeccontext.h" 32 33 extern "C" { 34 #include "libavcodec/avcodec.h" 35 } 36 37 class MTV_PUBLIC Vaapi2Context : public MythCodecContext 38 { 39 public: 40 Vaapi2Context(void); 41 static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec, 42 const QString &decoder, 43 uint stream_type, 44 AVPixelFormat &pix_fmt); 45 int HwDecoderInit(AVCodecContext *ctx); 46 virtual QString GetDeinterlaceFilter(void); 47 virtual bool isValidDeinterlacer(QString /*name*/ ); 48 virtual QStringList GetDeinterlacers(void); 49 50 }; 51 52 #endif // VAAPI2CONTEXT_H 53 No newline at end of file -
mythtv/libs/libmythtv/videodisplayprofile.cpp
diff --git a/mythtv/libs/libmythtv/videodisplayprofile.cpp b/mythtv/libs/libmythtv/videodisplayprofile.cpp index 700ee3bb990..4105b3d2ca7 100644
a b using namespace std; 8 8 #include "mythlogging.h" 9 9 #include "videooutbase.h" 10 10 #include "avformatdecoder.h" 11 #include "mythcodeccontext.h" 11 12 12 13 13 14 // options are NNN NNN-MMM 0-MMM NNN-99999 >NNN >=NNN <MMM <=MMM or blank … … bool ProfileItem::IsValid(QString *reason) const 258 259 } 259 260 260 261 QStringList deints = VideoDisplayProfile::GetDeinterlacers(renderer); 262 QStringList decoderdeints = MythCodecContext::GetDeinterlacers(decoder); 263 deints.append(decoderdeints); 261 264 QString deint0 = Get("pref_deint0"); 262 265 QString deint1 = Get("pref_deint1"); 263 266 if (!deint0.isEmpty() && !deints.contains(deint0)) … … QString VideoDisplayProfile::GetDecoderName(const QString &decoder) 852 855 dec_name["dxva2"] = QObject::tr("Windows hardware acceleration"); 853 856 dec_name["vda"] = QObject::tr("Mac VDA hardware acceleration"); 854 857 dec_name["mediacodec"] = QObject::tr("Android MediaCodec decoder"); 858 dec_name["vaapi2"] = QObject::tr("VAAPI2 acceleration"); 855 859 } 856 860 857 861 QString ret = decoder; … … QString VideoDisplayProfile::GetDecoderHelp(QString decoder) 913 917 "Mediacodec will use the graphics hardware to " 914 918 "accelerate video decoding on Android. "); 915 919 920 if (decoder == "vaapi2") 921 msg += QObject::tr( 922 "VAAPI2 is a new implementation of VAAPI to will use the graphics hardware to " 923 "accelerate video decoding on Intel CPUs. "); 924 916 925 return msg; 917 926 } 918 927 … … QString VideoDisplayProfile::GetDeinterlacerName(const QString &short_name) 941 950 else if ("fieldorderdoubleprocessdeint" == short_name) 942 951 return QObject::tr("Interlaced (2x)"); 943 952 else if ("opengllinearblend" == short_name) 944 return QObject::tr("Linear blend (HW )");953 return QObject::tr("Linear blend (HW-GL)"); 945 954 else if ("openglkerneldeint" == short_name) 946 return QObject::tr("Kernel (HW )");955 return QObject::tr("Kernel (HW-GL)"); 947 956 else if ("openglbobdeint" == short_name) 948 return QObject::tr("Bob (2x, HW )");957 return QObject::tr("Bob (2x, HW-GL)"); 949 958 else if ("openglonefield" == short_name) 950 return QObject::tr("One field (HW )");959 return QObject::tr("One field (HW-GL)"); 951 960 else if ("opengldoubleratekerneldeint" == short_name) 952 return QObject::tr("Kernel (2x, HW )");961 return QObject::tr("Kernel (2x, HW-GL)"); 953 962 else if ("opengldoubleratelinearblend" == short_name) 954 return QObject::tr("Linear blend (2x, HW )");963 return QObject::tr("Linear blend (2x, HW-GL)"); 955 964 else if ("opengldoubleratefieldorder" == short_name) 956 return QObject::tr("Interlaced (2x, HW )");965 return QObject::tr("Interlaced (2x, HW-GL)"); 957 966 else if ("vdpauonefield" == short_name) 958 967 return QObject::tr("One Field (1x, HW)"); 959 968 else if ("vdpaubobdeint" == short_name) … … QString VideoDisplayProfile::GetDeinterlacerName(const QString &short_name) 978 987 else if ("openmaxlinedouble" == short_name) 979 988 return QObject::tr("Line double (HW)"); 980 989 #endif // def USING_OPENMAX 990 #ifdef USING_VAAPI2 991 else if ("vaapi2default" == short_name) 992 return QObject::tr("Advanced (HW-VA)"); 993 else if ("vaapi2bob" == short_name) 994 return QObject::tr("Bob (HW-VA)"); 995 else if ("vaapi2weave" == short_name) 996 return QObject::tr("Weave (HW-VA)"); 997 else if ("vaapi2motion_adaptive" == short_name) 998 return QObject::tr("Motion Adaptive (HW-VA)"); 999 else if ("vaapi2motion_compensated" == short_name) 1000 return QObject::tr("Motion Compensated (HW-VA)"); 1001 else if ("vaapi2doubleratedefault" == short_name) 1002 return QObject::tr("Advanced (2x, HW-VA)"); 1003 else if ("vaapi2doubleratebob" == short_name) 1004 return QObject::tr("Bob (2x, HW-VA)"); 1005 else if ("vaapi2doublerateweave" == short_name) 1006 return QObject::tr("Weave (2x, HW-VA)"); 1007 else if ("vaapi2doubleratemotion_adaptive" == short_name) 1008 return QObject::tr("Motion Adaptive (2x, HW-VA)"); 1009 else if ("vaapi2doubleratemotion_compensated" == short_name) 1010 return QObject::tr("Motion Compensated (2x, HW-VA)"); 1011 #endif 981 1012 982 1013 return ""; 983 1014 } … … void VideoDisplayProfile::CreateProfiles(const QString &hostname) 1468 1499 CreateProfile(groupid, 1, "", "", "", 1469 1500 "mediacodec", 4, true, "opengl", 1470 1501 "opengl2", true, 1471 "none", "none", 1502 "opengldoubleratelinearblend", "opengllinearblend", 1503 ""); 1504 } 1505 #endif 1506 1507 #if defined(USING_VAAPI2) && defined(USING_OPENGL_VIDEO) 1508 if (!profiles.contains("VAAPI2 Normal")) { 1509 (void) QObject::tr("VAAPI2 Normal", 1510 "Sample: VAAPI2 Normal"); 1511 groupid = CreateProfileGroup("VAAPI2 Normal", hostname); 1512 CreateProfile(groupid, 1, "", "", "", 1513 "vaapi2", 4, true, "opengl", 1514 "opengl2", true, 1515 "vaapi2doubleratedefault", "vaapi2default", 1472 1516 ""); 1473 1517 } 1474 1518 #endif … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1615 1659 1616 1660 QString kUsingGPU = QObject::tr("(Hardware Accelerated)"); 1617 1661 1662 QString kUsingVA = QObject::tr("(VAAPI Hardware Accelerated)"); 1663 1664 QString kUsingGL = QObject::tr("(OpenGL Hardware Accelerated)"); 1665 1618 1666 QString kGreedyHMsg = QObject::tr( 1619 1667 "This deinterlacer uses several fields to reduce motion blur. " 1620 1668 "It has increased CPU requirements."); … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1635 1683 "This deinterlacer uses multiple fields to reduce motion blur " 1636 1684 "and smooth edges. "); 1637 1685 1686 QString kMostAdvMsg = QObject::tr( 1687 "Use the most advanced hardware deinterlacing algorithm available. "); 1688 1689 QString kWeaveMsg = QObject::tr( 1690 "Use the weave deinterlacing algorithm. "); 1691 1692 QString kMAMsg = QObject::tr( 1693 "Use the motion adaptive deinterlacing algorithm. "); 1694 1695 QString kMCMsg = QObject::tr( 1696 "Use the motion compensated deinterlacing algorithm. "); 1697 1638 1698 if (deint == "none") 1639 1699 msg = kNoneMsg; 1640 1700 else if (deint == "onefield") … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1648 1708 else if (deint == "kerneldoubleprocessdeint") 1649 1709 msg = kKernelMsg + " " + kDoubleRateMsg; 1650 1710 else if (deint == "openglonefield") 1651 msg = kOneFieldMsg + " " + kUsingG PU;1711 msg = kOneFieldMsg + " " + kUsingGL; 1652 1712 else if (deint == "openglbobdeint") 1653 msg = kBobMsg + " " + kUsingG PU;1713 msg = kBobMsg + " " + kUsingGL; 1654 1714 else if (deint == "opengllinearblend") 1655 msg = kLinearBlendMsg + " " + kUsingG PU;1715 msg = kLinearBlendMsg + " " + kUsingGL; 1656 1716 else if (deint == "openglkerneldeint") 1657 msg = kKernelMsg + " " + kUsingG PU;1717 msg = kKernelMsg + " " + kUsingGL; 1658 1718 else if (deint == "opengldoubleratelinearblend") 1659 msg = kLinearBlendMsg + " " + kDoubleRateMsg + " " + kUsingG PU;1719 msg = kLinearBlendMsg + " " + kDoubleRateMsg + " " + kUsingGL; 1660 1720 else if (deint == "opengldoubleratekerneldeint") 1661 msg = kKernelMsg + " " + kDoubleRateMsg + " " + kUsingG PU;1721 msg = kKernelMsg + " " + kDoubleRateMsg + " " + kUsingGL; 1662 1722 else if (deint == "opengldoubleratefieldorder") 1663 msg = kFieldOrderMsg + " " + kDoubleRateMsg + " " + kUsingG PU;1723 msg = kFieldOrderMsg + " " + kDoubleRateMsg + " " + kUsingGL; 1664 1724 else if (deint == "greedyhdeint") 1665 1725 msg = kGreedyHMsg; 1666 1726 else if (deint == "greedyhdoubleprocessdeint") … … QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 1687 1747 msg = kOneFieldMsg + " " + kUsingGPU; 1688 1748 else if (deint == "vaapibobdeint") 1689 1749 msg = kBobMsg + " " + kUsingGPU; 1750 1751 else if (deint == "vaapi2default") 1752 msg = kMostAdvMsg + " " + kUsingVA; 1753 else if (deint == "vaapi2bob") 1754 msg = kBobMsg + " " + kUsingVA; 1755 else if (deint == "vaapi2weave") 1756 msg = kWeaveMsg + " " + kUsingVA; 1757 else if (deint == "vaapi2motion_adaptive") 1758 msg = kMAMsg + " " + kUsingVA; 1759 else if (deint == "vaapi2motion_compensated") 1760 msg = kMCMsg + " " + kUsingVA; 1761 else if (deint == "vaapi2doubleratedefault") 1762 msg = kMostAdvMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1763 else if (deint == "vaapi2doubleratebob") 1764 msg = kBobMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1765 else if (deint == "vaapi2doublerateweave") 1766 msg = kWeaveMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1767 else if (deint == "vaapi2doubleratemotion_adaptive") 1768 msg = kMAMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1769 else if (deint == "vaapi2doubleratemotion_compensated") 1770 msg = kMCMsg + " " + kDoubleRateMsg + " " + kUsingVA; 1690 1771 else 1691 1772 msg = QObject::tr("'%1' has not been documented yet.").arg(deint); 1692 1773 -
mythtv/libs/libmythtv/videoout_opengl.cpp
diff --git a/mythtv/libs/libmythtv/videoout_opengl.cpp b/mythtv/libs/libmythtv/videoout_opengl.cpp index b689947d738..b055c2a608e 100644
a b 10 10 #include "openglvideo.h" 11 11 #include "mythrender_opengl.h" 12 12 #include "mythpainter_ogl.h" 13 #include "mythcodeccontext.h" 13 14 14 15 #define LOC QString("VidOutGL: ") 15 16 … … void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 40 41 (*opts.safe_renderers)["openmax"].append("opengl"); 41 42 if (opts.decoders->contains("mediacodec")) 42 43 (*opts.safe_renderers)["mediacodec"].append("opengl"); 44 if (opts.decoders->contains("vaapi2")) 45 (*opts.safe_renderers)["vaapi2"].append("opengl"); 43 46 opts.priorities->insert("opengl", 65); 44 47 45 48 // lite profile - no colourspace control, GPU deinterlacing … … bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf, 270 273 StopEmbedding(); 271 274 } 272 275 273 if (!codec_is_std(av_codec_id) && !codec_is_mediacodec(av_codec_id)) 276 if (!codec_is_std(av_codec_id) 277 && !codec_is_mediacodec(av_codec_id) 278 && !codec_is_vaapi2(av_codec_id)) 274 279 { 275 280 LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported."); 276 281 errorState = kError_Unknown; … … QStringList VideoOutputOpenGL::GetAllowedRenderers( 741 746 { 742 747 list << "opengl" << "opengl-lite"; 743 748 } 744 else if (codec_is_mediacodec(myth_codec_id) && !getenv("NO_OPENGL")) 749 else if ((codec_is_mediacodec(myth_codec_id) || codec_is_vaapi2(myth_codec_id)) 750 && !getenv("NO_OPENGL")) 745 751 { 746 752 list << "opengl"; 747 753 } … … bool VideoOutputOpenGL::SetupDeinterlace( 812 818 if (db_vdisp_profile) 813 819 m_deintfiltername = db_vdisp_profile->GetFilteredDeint(overridefilter); 814 820 821 if (MythCodecContext::isCodecDeinterlacer(m_deintfiltername)) 822 return false; 823 815 824 if (!m_deintfiltername.contains("opengl")) 816 825 { 817 826 gl_videochain->SetDeinterlacing(false); -
mythtv/libs/libmythtv/videooutbase.cpp
diff --git a/mythtv/libs/libmythtv/videooutbase.cpp b/mythtv/libs/libmythtv/videooutbase.cpp index 60b2d4fa249..608eeb703b6 100644
a b 18 18 #include "mythxdisplay.h" 19 19 #include "mythavutil.h" 20 20 #include "mthreadpool.h" 21 #include "mythcodeccontext.h" 21 22 22 23 #ifdef USING_XV 23 24 #include "videoout_xv.h" … … bool VideoOutput::SetupDeinterlace(bool interlaced, 607 608 else 608 609 m_deintfiltername = ""; 609 610 610 m_deintFiltMan = new FilterManager;611 611 m_deintFilter = NULL; 612 m_deintFiltMan = NULL; 613 614 if (MythCodecContext::isCodecDeinterlacer(m_deintfiltername)) 615 { 616 m_deinterlacing = false; 617 return false; 618 } 619 620 m_deintFiltMan = new FilterManager; 612 621 613 622 if (!m_deintfiltername.isEmpty()) 614 623 { -
mythtv/libs/libmythtv/videooutbase.h
diff --git a/mythtv/libs/libmythtv/videooutbase.h b/mythtv/libs/libmythtv/videooutbase.h index 0c11bd60ce2..35a5f2877a5 100644
a b class VideoOutput 76 76 virtual void PrepareFrame(VideoFrame *buffer, FrameScanType, 77 77 OSD *osd) = 0; 78 78 virtual void Show(FrameScanType) = 0; 79 VideoDisplayProfile *GetProfile() { return db_vdisp_profile; } 80 79 81 80 82 virtual void WindowResized(const QSize &) {} 81 83 -
mythtv/programs/mythfrontend/globalsettings.cpp
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index 7f87ba55caa..c169aab6a50 100644
a b 38 38 #include "mythuihelper.h" 39 39 #include "mythuidefines.h" 40 40 #include "langsettings.h" 41 #include "mythcodeccontext.h" 41 42 42 43 #ifdef USING_AIRPLAY 43 44 #include "AirPlay/mythraopconnection.h" … … static HostSpinBoxSetting *AudioReadAhead() 66 67 return gc; 67 68 } 68 69 70 #ifdef USING_VAAPI2 71 static HostTextEditSetting *VAAPIDevice() 72 { 73 HostTextEditSetting *ge = new HostTextEditSetting("VAAPIDevice"); 74 75 ge->setLabel(MainGeneralSettings::tr("Decoder Device for VAAPI2 hardware decoding")); 76 77 ge->setValue(""); 78 79 QString help = MainGeneralSettings::tr( 80 "Use this if your system does not detect the VAAPI device. " 81 "Example: '/dev/dri/renderD128'."); 82 83 ge->setHelpText(help); 84 85 return ge; 86 } 87 #endif 88 69 89 #if CONFIG_DEBUGTYPE 70 90 static HostCheckBoxSetting *FFmpegDemuxer() 71 91 { … … void PlaybackProfileItemConfig::decoderChanged(const QString &dec) 937 957 938 958 decoder->setHelpText(VideoDisplayProfile::GetDecoderHelp(dec)); 939 959 960 QString vrenderer2 = vidrend->getValue(); 961 vrenderChanged(vrenderer2); 962 940 963 InitLabel(); 941 964 } 942 965 … … void PlaybackProfileItemConfig::vrenderChanged(const QString &renderer) 944 967 { 945 968 QStringList osds = VideoDisplayProfile::GetOSDs(renderer); 946 969 QStringList deints = VideoDisplayProfile::GetDeinterlacers(renderer); 970 QString decodername = decoder->getValue(); 971 QStringList decoderdeints = MythCodecContext::GetDeinterlacers(decodername); 972 deints.append(decoderdeints); 947 973 QString losd = osdrend->getValue(); 948 974 QString ldeint0 = deint0->getValue(); 949 975 QString ldeint1 = deint1->getValue(); … … void PlaybackSettings::Load(void) 3958 3984 GroupSetting* general = new GroupSetting(); 3959 3985 general->setLabel(tr("General Playback")); 3960 3986 general->addChild(RealtimePriority()); 3987 #ifdef USING_VAAPI2 3988 general->addChild(VAAPIDevice()); 3989 #endif 3961 3990 general->addChild(AudioReadAhead()); 3962 3991 general->addChild(JumpToProgramOSD()); 3963 3992 general->addChild(ClearSavedPosition()); -
mythtv/programs/mythfrontend/mythfrontend.pro
diff --git a/mythtv/programs/mythfrontend/mythfrontend.pro b/mythtv/programs/mythfrontend/mythfrontend.pro index 580bc606af7..83517acfefc 100644
a b using_opengl:DEFINES += USING_OPENGL 116 116 using_opengl_video:DEFINES += USING_OPENGL_VIDEO 117 117 using_vdpau:DEFINES += USING_VDPAU 118 118 using_vaapi:using_opengl_video:DEFINES += USING_GLVAAPI 119 using_vaapi2:DEFINES += USING_VAAPI2 119 120 120 121 using_pulse:DEFINES += USING_PULSE 121 122 using_pulseoutput: DEFINES += USING_PULSEOUTPUT