Ticket #13311: 20180903_1555_livetv_fix.patch
File 20180903_1555_livetv_fix.patch, 86.1 KB (added by , 6 years ago) |
---|
-
mythtv/configure
diff --git a/mythtv/configure b/mythtv/configure index f7cfc291b82..f87ee232317 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 … … HWACCEL_AUTODETECT_LIBRARY_LIST=" 1401 1402 crystalhd 1402 1403 dxva2 1403 1404 vaapi 1405 vaapi2 1404 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 … … ffmpeg_optset extra_cxxflags extra_ldflags target_os 7057 7060 ffmpeg_optset pkg_config prefix libdir as objcc dep_cc host_cc 7058 7061 ffmpeg_optset host_ld 7059 7062 ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid 7060 ffmpeg_optenable vdpau vaapilibxml2 libass dxva27063 ffmpeg_optenable vdpau libxml2 libass dxva2 7061 7064 ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883 7062 7065 ffmpeg_optenable crystalhd sdl2 ffplay 7063 7066 if test $target_os = "android"; then … … if test $target_os = "android"; then 7066 7069 else 7067 7070 disable mediacodec 7068 7071 fi 7069 7072 if enabled vaapi || enabled vaapi2 7073 ffopts="$ffopts --enable-vaapi" 7074 fi 7070 7075 ffmpeg_extra_cflags="$extra_cflags -w" 7071 7076 7072 7077 ## Call FFmpeg configure here … … if enabled x11 ; then 7272 7277 echo "xv support ${xv-no}" 7273 7278 echo "VDPAU support ${vdpau-no}" 7274 7279 echo "VAAPI support ${vaapi-no}" 7280 echo "VAAPI2 support ${vaapi2-no}" 7275 7281 echo "CrystalHD support ${crystalhd-no}" 7276 7282 echo "OpenMAX support ${openmax-no}" 7277 7283 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..b5061eca0b5 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 #ifdef USING_VAAPI1519 1531 static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt) 1520 1532 { 1521 1533 return fmt == AV_PIX_FMT_VAAPI_MOCO || … … static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt) 1523 1535 fmt == AV_PIX_FMT_VAAPI_VLD; 1524 1536 } 1525 1537 1538 #ifdef USING_VAAPI 1539 1526 1540 // Declared separately to allow attribute 1527 1541 static enum AVPixelFormat get_format_vaapi(struct AVCodecContext *, 1528 1542 const enum AVPixelFormat *) MUNUSED; … … enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx, 1549 1563 } 1550 1564 #endif 1551 1565 1566 #ifdef USING_VAAPI2 1567 static enum AVPixelFormat get_format_vaapi2(struct AVCodecContext *avctx, 1568 const enum AVPixelFormat *valid_fmts) 1569 { 1570 enum AVPixelFormat ret = AV_PIX_FMT_NONE; 1571 while (*valid_fmts != AV_PIX_FMT_NONE) { 1572 if (IS_VAAPI_PIX_FMT(*valid_fmts)) 1573 { 1574 ret = *valid_fmts; 1575 avctx->pix_fmt = ret; 1576 // Vaapi2Context::SetHwframeCtx(avctx, 20); 1577 break; 1578 } 1579 valid_fmts++; 1580 } 1581 return ret; 1582 } 1583 #endif 1584 1552 1585 #ifdef USING_MEDIACODEC 1553 1586 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx, 1554 1587 const enum AVPixelFormat *valid_fmts) … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1629 1662 else 1630 1663 #endif 1631 1664 #ifdef USING_VAAPI 1632 if (CODEC_IS_VAAPI(codec, enc) )1665 if (CODEC_IS_VAAPI(codec, enc) && codec_is_vaapi(video_codec_id)) 1633 1666 { 1634 1667 enc->get_buffer2 = get_avf_buffer_vaapi; 1635 1668 enc->get_format = get_format_vaapi; … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1644 1677 enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 1645 1678 } 1646 1679 else 1680 #endif 1681 #ifdef USING_VAAPI2 1682 if (codec_is_vaapi2(video_codec_id)) 1683 { 1684 enc->get_buffer2 = get_avf_buffer_vaapi2; 1685 enc->get_format = get_format_vaapi2; 1686 } 1687 else 1647 1688 #endif 1648 1689 if (codec && codec->capabilities & AV_CODEC_CAP_DR1) 1649 1690 { … … void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 1659 1700 .arg(ff_codec_id_string(enc->codec_id))); 1660 1701 } 1661 1702 1703 // delete m_mythcodecctx; 1704 // m_mythcodecctx = MythCodecContext::createMythCodecContext(video_codec_id, stream); 1705 if (m_mythcodecctx) 1706 { 1707 m_mythcodecctx->setPlayer(m_parent); 1708 int ret = m_mythcodecctx->HwDecoderInit(enc); 1709 if (ret < 0) 1710 { 1711 char error[AV_ERROR_MAX_STRING_SIZE]; 1712 if (ret < 0) 1713 { 1714 LOG(VB_GENERAL, LOG_ERR, LOC + 1715 QString("HwDecoderInit unable to initialize hardware decoder: %1 (%2)") 1716 .arg(av_make_error_string(error, sizeof(error), ret)) 1717 .arg(ret)); 1718 // force it to switch to software decoding 1719 averror_count = SEQ_PKT_ERR_MAX + 1; 1720 m_streams_changed = true; 1721 } 1722 } 1723 } 1724 1662 1725 if (FlagIsSet(kDecodeLowRes) || FlagIsSet(kDecodeSingleThreaded) || 1663 1726 FlagIsSet(kDecodeFewBlocks) || FlagIsSet(kDecodeNoLoopFilter) || 1664 1727 FlagIsSet(kDecodeNoDecode)) … … int AvFormatDecoder::ScanStreams(bool novideo) 2536 2599 } 2537 2600 } 2538 2601 #endif // USING_MEDIACODEC 2602 #ifdef USING_VAAPI2 2603 if (!foundgpudecoder) 2604 { 2605 MythCodecID vaapi2_mcid; 2606 AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; 2607 vaapi2_mcid = Vaapi2Context::GetBestSupportedCodec( 2608 &codec, dec, mpeg_version(enc->codec_id), 2609 pix_fmt); 2610 2611 if (codec_is_vaapi2(vaapi2_mcid)) 2612 { 2613 gCodecMap->freeCodecContext(ic->streams[selTrack]); 2614 enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec); 2615 video_codec_id = vaapi2_mcid; 2616 foundgpudecoder = true; 2617 } 2618 } 2619 #endif // USING_VAAPI2 2539 2620 } 2540 2621 // default to mpeg2 2541 2622 if (video_codec_id == kCodec_NONE) … … int AvFormatDecoder::ScanStreams(bool novideo) 2554 2635 if (!codec_is_std(video_codec_id)) 2555 2636 thread_count = 1; 2556 2637 2638 // video-codec-id is set - now create the MythCodecContext. 2639 delete m_mythcodecctx; 2640 m_mythcodecctx = MythCodecContext::createMythCodecContext 2641 (video_codec_id, ic->streams[selTrack]); 2642 2557 2643 use_frame_timing = false; 2558 2644 if (! private_dec 2559 && (codec_is_std(video_codec_id) || codec_is_mediacodec(video_codec_id))) 2645 && (codec_is_std(video_codec_id) 2646 || codec_is_mediacodec(video_codec_id) 2647 || codec_is_vaapi2(video_codec_id))) 2560 2648 use_frame_timing = true; 2561 2649 2562 2650 if (FlagIsSet(kDecodeSingleThreaded)) … … int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int /*flags*/) 3056 3144 } 3057 3145 #endif 3058 3146 3147 #ifdef USING_VAAPI2 3148 int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags) 3149 { 3150 AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque); 3151 3152 nd->directrendering = false; 3153 return avcodec_default_get_buffer2(c, pic, flags); 3154 } 3155 #endif 3156 3059 3157 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte) 3060 3158 { 3061 3159 if (!len) … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3630 3728 // into separate routines or separate threads. 3631 3729 // Also now that it always consumes a whole buffer some code 3632 3730 // in the caller may be able to be optimized. 3633 ret = avcodec_receive_frame(context, mpa_pic); 3731 3732 // FilteredReceiveFrame will call avcodec_receive_frame and 3733 // apply any codec-dependent filtering 3734 ret = m_mythcodecctx->FilteredReceiveFrame(context, mpa_pic); 3634 3735 3635 3736 if (ret == 0) 3636 3737 gotpicture = 1; … … bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 3671 3772 QString("video avcodec_send_packet error: %1 (%2) gotpicture:%3") 3672 3773 .arg(av_make_error_string(error, sizeof(error), ret2)) 3673 3774 .arg(ret2).arg(gotpicture)); 3674 if ( ret == AVERROR_INVALIDDATA || ret2 == AVERROR_INVALIDDATA)3775 if (++averror_count > SEQ_PKT_ERR_MAX) 3675 3776 { 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 } 3777 // If erroring on GPU assist, try switching to software decode 3778 if (codec_is_std(video_codec_id)) 3779 m_parent->SetErrored(QObject::tr("Video Decode Error")); 3780 else 3781 m_streams_changed = true; 3684 3782 } 3685 3783 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL) 3686 3784 m_streams_changed = true; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3840 3938 } 3841 3939 else if (!directrendering) 3842 3940 { 3941 AVFrame *tmp_frame = NULL; 3942 AVFrame *use_frame = NULL; 3943 #ifdef USING_VAAPI2 3944 if (IS_VAAPI_PIX_FMT((AVPixelFormat)mpa_pic->format)) 3945 { 3946 int ret = 0; 3947 tmp_frame = av_frame_alloc(); 3948 use_frame = tmp_frame; 3949 /* retrieve data from GPU to CPU */ 3950 if ((ret = av_hwframe_transfer_data(use_frame, mpa_pic, 0)) < 0) { 3951 LOG(VB_GENERAL, LOG_ERR, LOC 3952 + QString("Error %1 transferring the data to system memory") 3953 .arg(ret)); 3954 av_frame_free(&use_frame); 3955 return false; 3956 } 3957 } 3958 else 3959 #endif // USING_VAAPI2 3960 use_frame = mpa_pic; 3961 3843 3962 AVFrame tmppicture; 3844 3963 3845 3964 VideoFrame *xf = picframe; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3847 3966 3848 3967 unsigned char *buf = picframe->buf; 3849 3968 av_image_fill_arrays(tmppicture.data, tmppicture.linesize, 3850 buf, AV_PIX_FMT_YUV420P, context->width,3851 context->height, IMAGE_ALIGN);3969 buf, AV_PIX_FMT_YUV420P, use_frame->width, 3970 use_frame->height, IMAGE_ALIGN); 3852 3971 tmppicture.data[0] = buf + picframe->offsets[0]; 3853 3972 tmppicture.data[1] = buf + picframe->offsets[1]; 3854 3973 tmppicture.data[2] = buf + picframe->offsets[2]; … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3857 3976 tmppicture.linesize[2] = picframe->pitches[2]; 3858 3977 3859 3978 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,3979 sws_ctx = sws_getCachedContext(sws_ctx, use_frame->width, 3980 use_frame->height, (AVPixelFormat)use_frame->format, 3981 use_frame->width, use_frame->height, 3863 3982 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 3864 3983 NULL, NULL, NULL); 3865 3984 if (!sws_ctx) … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3867 3986 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate sws context"); 3868 3987 return false; 3869 3988 } 3870 sws_scale(sws_ctx, mpa_pic->data, mpa_pic->linesize, 0, dim.height(),3989 sws_scale(sws_ctx, use_frame->data, use_frame->linesize, 0, dim.height(), 3871 3990 tmppicture.data, tmppicture.linesize); 3872 3991 3873 3992 if (xf) … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3880 3999 xf->aspect = current_aspect; 3881 4000 m_parent->DiscardVideoFrame(xf); 3882 4001 } 4002 if (tmp_frame) 4003 av_frame_free(&tmp_frame); 3883 4004 } 3884 4005 else if (!picframe) 3885 4006 { … … bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 3928 4049 // If fps has doubled due to frame-doubling deinterlace 3929 4050 // Set fps to double value. 3930 4051 double fpschange = calcfps / fps; 4052 int prior = fpsMultiplier; 3931 4053 if (fpschange > 1.9 && fpschange < 2.1) 3932 4054 fpsMultiplier = 2; 3933 4055 if (fpschange > 0.5 && fpschange < 0.6) 3934 4056 fpsMultiplier = 1; 4057 if (fpsMultiplier != prior) 4058 m_parent->SetFrameRate(fps); 3935 4059 } 3936 4060 3937 4061 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..684664acd11 100644
a b DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo) 45 45 video_inverted(false), 46 46 decodeAllSubtitles(false), 47 47 // language preference 48 languagePreference(iso639_get_language_key_list()) 48 languagePreference(iso639_get_language_key_list()), 49 m_mythcodecctx(NULL) 49 50 { 50 51 ResetTracks(); 51 52 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..faad6f6d172 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, 388 389 const AVCodec *pCodec, bool nullCodec) 389 390 { 390 391 QMutexLocker lock(&mapLock); 391 AVCodecContext *avctx = stream Map.value(stream, NULL);392 AVCodecContext *avctx = streamAvMap.value(stream, NULL); 392 393 if (!avctx) 393 394 { 394 395 if (stream == NULL || stream->codecpar == NULL) … … 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 stream Map.insert(stream, avctx);415 avctx->pkt_timebase = stream->time_base; 416 streamAvMap.insert(stream, avctx); 416 417 } 417 418 } 418 419 return avctx; … … AVCodecContext *MythCodecMap::getCodecContext(const AVStream *stream, 420 421 421 422 AVCodecContext *MythCodecMap::hasCodecContext(const AVStream *stream) 422 423 { 423 return stream Map.value(stream, NULL);424 return streamAvMap.value(stream, NULL); 424 425 } 425 426 426 427 void MythCodecMap::freeCodecContext(const AVStream *stream) 427 428 { 428 429 QMutexLocker lock(&mapLock); 429 AVCodecContext *avctx = stream Map.take(stream);430 AVCodecContext *avctx = streamAvMap.take(stream); 430 431 if (avctx) 431 432 avcodec_free_context(&avctx); 432 433 } … … void MythCodecMap::freeCodecContext(const AVStream *stream) 434 435 void MythCodecMap::freeAllCodecContexts() 435 436 { 436 437 QMutexLocker lock(&mapLock); 437 QMap<const AVStream*, AVCodecContext*>::iterator i = stream Map.begin();438 while (i != stream Map.end()) {438 QMap<const AVStream*, AVCodecContext*>::iterator i = streamAvMap.begin(); 439 while (i != streamAvMap.end()) { 439 440 const AVStream *stream = i.key(); 440 441 ++i; 441 442 freeCodecContext(stream); -
mythtv/libs/libmythtv/mythavutil.h
diff --git a/mythtv/libs/libmythtv/mythavutil.h b/mythtv/libs/libmythtv/mythavutil.h index 1357fe2c54c..f287b8e54ea 100644
a b class MTV_PUBLIC MythCodecMap 98 98 void freeCodecContext(const AVStream*); 99 99 void freeAllCodecContexts(); 100 100 protected: 101 QMap<const AVStream*, AVCodecContext*> stream Map;101 QMap<const AVStream*, AVCodecContext*> streamAvMap; 102 102 QMutex mapLock; 103 103 }; 104 104 -
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..3cee6b4ed0d
- + 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(AVStream* initStream) : 49 stream(initStream), 50 buffersink_ctx(NULL), 51 buffersrc_ctx(NULL), 52 filter_graph(NULL), 53 filtersInitialized(false), 54 hw_frames_ctx(0), 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, AVStream* initStream) 70 { 71 MythCodecContext *mctx = NULL; 72 #ifdef USING_VAAPI2 73 if (codec_is_vaapi2(codec)) 74 mctx = new Vaapi2Context(initStream); 75 #endif 76 if (!mctx) 77 mctx = new MythCodecContext(initStream); 78 return mctx; 79 } 80 81 QStringList MythCodecContext::MythCodecContext::GetDeinterlacers(QString decodername) 82 { 83 QStringList ret; 84 #ifdef USING_VAAPI2 85 if (decodername == "vaapi2") 86 { 87 ret.append("vaapi2default"); 88 ret.append("vaapi2bob"); 89 ret.append("vaapi2weave"); 90 ret.append("vaapi2motion_adaptive"); 91 ret.append("vaapi2motion_compensated"); 92 ret.append("vaapi2doubleratedefault"); 93 ret.append("vaapi2doubleratebob"); 94 ret.append("vaapi2doublerateweave"); 95 ret.append("vaapi2doubleratemotion_adaptive"); 96 ret.append("vaapi2doubleratemotion_compensated"); 97 98 /* 99 "mode", "Deinterlacing mode", 100 "default", "Use the highest-numbered (and therefore possibly most advanced) deinterlacing algorithm", 101 "bob", "Use the bob deinterlacing algorithm", 102 "weave", "Use the weave deinterlacing algorithm", 103 "motion_adaptive", "Use the motion adaptive deinterlacing algorithm", 104 "motion_compensated", "Use the motion compensated deinterlacing algorithm", 105 106 "rate", "Generate output at frame rate or field rate", 107 "frame", "Output at frame rate (one frame of output for each field-pair)", 108 "field", "Output at field rate (one frame of output for each field)", 109 110 "auto", "Only deinterlace fields, passing frames through unchanged", 111 1 = enabled 112 0 = disabled 113 */ 114 115 } 116 #endif 117 return ret; 118 } 119 120 121 // Currently this will only set up the filter after an interlaced frame. 122 // If we need other filters apart from deinterlace filters we will 123 // need to make a change here. 124 125 int MythCodecContext::FilteredReceiveFrame(AVCodecContext *ctx, AVFrame *frame) 126 { 127 int ret = 0; 128 129 while (1) 130 { 131 if (filter_graph) 132 { 133 ret = av_buffersink_get_frame(buffersink_ctx, frame); 134 if (ret >= 0) 135 { 136 if (priorPts[0] && ptsUsed == priorPts[1]) 137 { 138 frame->pts = priorPts[1] + (priorPts[1] - priorPts[0])/2; 139 frame->scte_cc_len = 0; 140 frame->atsc_cc_len = 0; 141 av_frame_remove_side_data(frame, AV_FRAME_DATA_A53_CC); 142 } 143 else 144 { 145 frame->pts = priorPts[1]; 146 ptsUsed = priorPts[1]; 147 } 148 // {const char *msg = QString("filter pts=%1 interlaced=%2") 149 // .arg(frame->pts).arg(frame->interlaced_frame).toLocal8Bit(); 150 // fprintf(stderr,"%s\n", msg);} 151 } 152 if (ret != AVERROR(EAGAIN)) 153 break; 154 } 155 156 // EAGAIN or no filter graph 157 ret = avcodec_receive_frame(ctx, frame); 158 if (ret < 0) 159 break; 160 // {const char *msg = QString("codec pts=%1 interlaced=%2") 161 // .arg(frame->pts).arg(frame->interlaced_frame).toLocal8Bit(); 162 // fprintf(stderr,"%s\n", msg);} 163 priorPts[0]=priorPts[1]; 164 priorPts[1]=frame->pts; 165 if (frame->interlaced_frame || filter_graph) 166 { 167 if (!filtersInitialized 168 || width != frame->width 169 || height != frame->height) 170 { 171 // bypass any frame of unknown format 172 if (frame->format < 0) 173 break; 174 ret = InitDeinterlaceFilter(ctx, frame); 175 if (ret < 0) 176 { 177 LOG(VB_GENERAL, LOG_ERR, LOC + "InitDeinterlaceFilter failed - continue without filters"); 178 break; 179 } 180 } 181 if (filter_graph) 182 { 183 ret = av_buffersrc_add_frame(buffersrc_ctx, frame); 184 if (ret < 0) 185 break; 186 } 187 else 188 break; 189 } 190 else 191 break; 192 } 193 194 return ret; 195 } 196 197 // Setup or change deinterlacer. 198 // enable - true to enable, false to disable 199 // name - empty to use video profile deinterlacers, otherwise 200 // use the supplied name. 201 // return true if the deinterlacer was found as a hardware deinterlacer. 202 // return false if the deinterlacer is nnt a hardware deinterlacer, 203 // and a videououtput deinterlacer should be tried instead. 204 205 bool MythCodecContext::setDeinterlacer(bool enable, QString name) 206 { 207 QMutexLocker lock(&contextLock); 208 // Code to disable interlace 209 if (!enable) 210 { 211 if (deinterlacername.isEmpty()) 212 return true; 213 else 214 { 215 deinterlacername.clear(); 216 filtersInitialized = false; 217 return true; 218 } 219 } 220 221 // Code to enable or change interlace 222 if (name.isEmpty()) 223 { 224 if (deinterlacername.isEmpty()) 225 { 226 VideoOutput *vo = player->GetVideoOutput(); 227 VideoDisplayProfile *vdisp_profile = vo->GetProfile(); 228 // if (player->CanSupportDoubleRate()) 229 name = vdisp_profile->GetFilteredDeint(QString()); 230 // else 231 // name = vdisp_profile->GetFallbackDeinterlacer(); 232 } 233 else 234 name = deinterlacername; 235 } 236 bool ret = true; 237 if (!isValidDeinterlacer(name)) 238 name.clear(); 239 240 if (name.isEmpty()) 241 ret = false; 242 243 if (deinterlacername == name) 244 return ret; 245 246 deinterlacername = name; 247 doublerate = deinterlacername.contains("doublerate"); 248 filtersInitialized = false; 249 return ret; 250 } 251 252 bool MythCodecContext::BestDeint(void) 253 { 254 deinterlacername.clear(); 255 return setDeinterlacer(true); 256 } 257 258 bool MythCodecContext::FallbackDeint(void) 259 { 260 return setDeinterlacer(true,GetFallbackDeint()); 261 } 262 263 QString MythCodecContext::GetFallbackDeint(void) 264 { 265 VideoOutput *vo = player->GetVideoOutput(); 266 VideoDisplayProfile *vdisp_profile = vo->GetProfile(); 267 return vdisp_profile->GetFallbackDeinterlacer(); 268 } 269 270 271 int MythCodecContext::InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame) 272 { 273 QMutexLocker lock(&contextLock); 274 char args[512]; 275 int ret = 0; 276 CloseFilters(); 277 width = frame->width; 278 height = frame->height; 279 if (!player) 280 return -1; 281 filtersInitialized = true; 282 doublerate = deinterlacername.contains("doublerate"); 283 284 if (doublerate && !player->CanSupportDoubleRate()) 285 { 286 QString request = deinterlacername; 287 deinterlacername = GetFallbackDeint(); 288 LOG(VB_PLAYBACK, LOG_INFO, LOC 289 + QString("Deinterlacer %1 requires double rate, switching to %2 instead.") 290 .arg(request).arg(deinterlacername)); 291 if (!isValidDeinterlacer(deinterlacername)) 292 deinterlacername.clear(); 293 doublerate = deinterlacername.contains("doublerate"); 294 295 // if the fallback is a non-vaapi - deinterlace will be turned off 296 // and the videoout methods can take over. 297 } 298 // VideoOutput *vo = player->GetVideoOutput(); 299 // VideoDisplayProfile *vdisp_profile = vo->GetProfile(); 300 // if (deinterlacername.isEmpty()) 301 // { 302 // if (player->CanSupportDoubleRate()) 303 // deinterlacername = vdisp_profile->GetFilteredDeint(QString()); 304 // else 305 // deinterlacername = vdisp_profile->GetFallbackDeinterlacer(); 306 // } 307 QString filters = GetDeinterlaceFilter(); 308 309 if (filters.isEmpty()) 310 { 311 LOG(VB_GENERAL, LOG_INFO, LOC + 312 "Disabled hardware decoder based deinterlacer."); 313 return ret; 314 } 315 const AVFilter *buffersrc = avfilter_get_by_name("buffer"); 316 const AVFilter *buffersink = avfilter_get_by_name("buffersink"); 317 AVFilterInOut *outputs = avfilter_inout_alloc(); 318 AVFilterInOut *inputs = avfilter_inout_alloc(); 319 AVRational time_base = stream->time_base; 320 // enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; 321 // enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_VAAPI_VLD, AV_PIX_FMT_NONE }; 322 AVBufferSrcParameters* params = NULL; 323 324 filter_graph = avfilter_graph_alloc(); 325 if (!outputs || !inputs || !filter_graph) 326 { 327 ret = AVERROR(ENOMEM); 328 goto end; 329 } 330 331 /* buffer video source: the decoded frames from the decoder will be inserted here. */ 332 snprintf(args, sizeof(args), 333 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 334 frame->width, frame->height, frame->format, // ctx->pix_fmt, 335 time_base.num, time_base.den, 336 ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den); 337 338 // isInterlaced = frame->interlaced_frame; 339 340 ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", 341 args, NULL, filter_graph); 342 if (ret < 0) 343 { 344 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer source"); 345 goto end; 346 } 347 348 params = av_buffersrc_parameters_alloc(); 349 // params->format = frame->format; 350 // params->time_base.num = stream->time_base.num; 351 // params->time_base.den = stream->time_base.den; 352 // params->width = frame->width; 353 // params->height = frame->height; 354 // params->sample_aspect_ratio.num = ctx->sample_aspect_ratio.num; 355 // params->sample_aspect_ratio.den = ctx->sample_aspect_ratio.den; 356 if (hw_frames_ctx) 357 av_buffer_unref(&hw_frames_ctx); 358 hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); 359 params->hw_frames_ctx = hw_frames_ctx; 360 361 ret = av_buffersrc_parameters_set(buffersrc_ctx, params); 362 363 if (ret < 0) 364 { 365 LOG(VB_GENERAL, LOG_ERR, LOC + "av_buffersrc_parameters_set failed"); 366 goto end; 367 } 368 369 av_freep(¶ms); 370 371 /* buffer video sink: to terminate the filter chain. */ 372 ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", 373 NULL, NULL, filter_graph); 374 if (ret < 0) 375 { 376 LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer sink"); 377 goto end; 378 } 379 380 // ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts, 381 // AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN); 382 // if (ret < 0) 383 // { 384 // LOG(VB_GENERAL, LOG_ERR, LOC + "av_opt_set_int_list pix_fmts failed"); 385 // goto end; 386 // } 387 388 /* 389 * Set the endpoints for the filter graph. The filter_graph will 390 * be linked to the graph described by filters_descr. 391 */ 392 393 /* 394 * The buffer source output must be connected to the input pad of 395 * the first filter described by filters_descr; since the first 396 * filter input label is not specified, it is set to "in" by 397 * default. 398 */ 399 outputs->name = av_strdup("in"); 400 outputs->filter_ctx = buffersrc_ctx; 401 outputs->pad_idx = 0; 402 outputs->next = NULL; 403 404 /* 405 * The buffer sink input must be connected to the output pad of 406 * the last filter described by filters_descr; since the last 407 * filter output label is not specified, it is set to "out" by 408 * default. 409 */ 410 inputs->name = av_strdup("out"); 411 inputs->filter_ctx = buffersink_ctx; 412 inputs->pad_idx = 0; 413 inputs->next = NULL; 414 415 if ((ret = avfilter_graph_parse_ptr(filter_graph, filters.toLocal8Bit(), 416 &inputs, &outputs,0)) < 0) 417 { 418 LOG(VB_GENERAL, LOG_ERR, LOC 419 + QString("avfilter_graph_parse_ptr failed for %1").arg(filters)); 420 goto end; 421 } 422 423 if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) 424 { 425 LOG(VB_GENERAL, LOG_ERR, LOC 426 + QString("avfilter_graph_config failed")); 427 goto end; 428 } 429 430 // send the first packet to the filters 431 // frame->pts = frame->best_effort_timestamp; 432 // ret = av_buffersrc_add_frame(buffersrc_ctx, frame); 433 // av_frame_unref(frame); 434 435 // if (ret < 0) 436 // { 437 // LOG(VB_GENERAL, LOG_ERR, LOC 438 // + QString("av_buffersrc_add_frame first time failed")); 439 // goto end; 440 // } 441 442 LOG(VB_GENERAL, LOG_INFO, LOC + 443 QString("Enabled hardware decoder based deinterlace filter '%1': <%2>.") 444 .arg(deinterlacername).arg(filters)); 445 end: 446 if (ret < 0) 447 { 448 avfilter_graph_free(&filter_graph); 449 filter_graph = NULL; 450 doublerate = false; 451 } 452 avfilter_inout_free(&inputs); 453 avfilter_inout_free(&outputs); 454 455 return ret; 456 } 457 458 void MythCodecContext::CloseFilters() 459 { 460 avfilter_graph_free(&filter_graph); 461 filter_graph = NULL; 462 buffersink_ctx = NULL; 463 buffersrc_ctx = NULL; 464 filtersInitialized = false; 465 ptsUsed = 0; 466 priorPts[0] = 0; 467 priorPts[1] = 0; 468 // isInterlaced = 0; 469 width = 0; 470 height = 0; 471 472 if (hw_frames_ctx) 473 av_buffer_unref(&hw_frames_ctx); 474 } 475 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..f0470eea409
- + 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(AVStream* initStream); 44 virtual ~MythCodecContext(); 45 static MythCodecContext* createMythCodecContext(MythCodecID codec, AVStream* initStream); 46 virtual int HwDecoderInit(AVCodecContext * /*ctx*/) { return 0; } 47 virtual int FilteredReceiveFrame(AVCodecContext *ctx, AVFrame *frame); 48 int InitDeinterlaceFilter(AVCodecContext *ctx, AVFrame *frame); 49 void CloseFilters(); 50 static QStringList GetDeinterlacers(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 virtual bool isValidDeinterlacer(QString /*name*/) { return false; } 56 bool isDeinterlacing(void) { return filter_graph != NULL;} 57 QString getDeinterlacerName(void) { return deinterlacername; } 58 bool BestDeint(void); 59 bool FallbackDeint(void); 60 bool getDoubleRate(void) { return doublerate; } 61 QString GetFallbackDeint(void); 62 63 protected: 64 AVStream* stream; 65 AVFilterContext *buffersink_ctx; 66 AVFilterContext *buffersrc_ctx; 67 AVFilterGraph *filter_graph; 68 bool filtersInitialized; 69 AVBufferRef *hw_frames_ctx; 70 MythPlayer *player; 71 int64_t priorPts[2]; 72 int64_t ptsUsed; 73 int width; 74 int height; 75 QString deinterlacername; 76 QMutex contextLock; 77 bool doublerate; 78 }; 79 80 #endif // MYTHCODECCONTEXT_H 81 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..7b4f5a235a7 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" … … MythPlayer::MythPlayer(PlayerFlags flags) 226 227 bufferingCounter(0), 227 228 // Debugging variables 228 229 output_jmeter(new Jitterometer(LOC)), 230 isDeintSetup(false), 229 231 disable_passthrough(false) 230 232 { 231 233 memset(&tc_lastval, 0, sizeof(tc_lastval)); … … void MythPlayer::FallbackDeint(void) 676 678 m_double_process = false; 677 679 678 680 if (videoOutput) 679 videoOutput->FallbackDeint(); 681 { 682 videoOutput->SetupDeinterlace(false); 683 bool hwset = decoder->GetMythCodecContext()->FallbackDeint(); 684 if (!hwset) 685 videoOutput->FallbackDeint(); 686 } 680 687 } 681 688 682 689 void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock) … … void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock) 715 722 716 723 if ((m_scan_tracker % 400) == 0) 717 724 { 718 QString type = (m_scan_tracker < 0) ? "progressive" : "interlaced"; 725 QString type; 726 // = (m_scan_tracker < 0) ? "progressive" : "interlaced"; 727 if (m_scan_tracker < 0) 728 { 729 if (decoder->GetMythCodecContext()->isDeinterlacing()) 730 type = "codec-deinterlaced"; 731 else 732 type = "progressive"; 733 } 734 else 735 type = "interlaced"; 736 719 737 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("%1 %2 frames seen.") 720 738 .arg(abs(m_scan_tracker)).arg(type)); 721 739 } … … void MythPlayer::SetScanType(FrameScanType scan) 763 781 764 782 if (interlaced) 765 783 { 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 }784 m_deint_possible = videoOutput->SetDeinterlacingEnabled(true); 785 if (!m_deint_possible) 786 { 787 LOG(VB_GENERAL, LOG_INFO, LOC + "Unable to enable Video Output based deinterlacing"); 788 m_scan = scan; 789 return; 790 } 773 791 if (videoOutput->NeedsDoubleFramerate()) 774 792 { 775 793 m_double_framerate = true; … … void MythPlayer::SetScanType(FrameScanType scan) 782 800 } 783 801 } 784 802 m_double_process = videoOutput->IsExtraProcessingRequired(); 785 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Enabled deinterlacing");803 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Enabled Video Output based deinterlacing"); 786 804 } 787 805 else 788 806 { … … void MythPlayer::SetScanType(FrameScanType scan) 791 809 m_double_process = false; 792 810 m_double_framerate = false; 793 811 videoOutput->SetDeinterlacingEnabled(false); 794 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled deinterlacing");812 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled Video Output based deinterlacing"); 795 813 } 796 814 } 797 815 … … void MythPlayer::SetScanType(FrameScanType scan) 801 819 void MythPlayer::SetVideoParams(int width, int height, double fps, 802 820 FrameScanType scan, QString codecName) 803 821 { 822 823 SetupDeinterlace(); 804 824 bool paramsChanged = false; 805 825 806 826 if (width >= 1 && height >= 1) … … void MythPlayer::SetVideoParams(int width, int height, double fps, 849 869 m_scan_tracker = (m_scan == kScan_Interlaced) ? 2 : 0; 850 870 } 851 871 872 873 void MythPlayer::SetFrameRate(double fps) 874 { 875 video_frame_rate = fps; 876 float temp_speed = (play_speed == 0.0f) ? 877 audio.GetStretchFactor() : play_speed; 878 SetFrameInterval(kScan_Progressive, 879 1.0 / (video_frame_rate * temp_speed)); 880 } 881 852 882 void MythPlayer::SetFileLength(int total, int frames) 853 883 { 854 884 totalLength = total; … … void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 1883 1913 avsync_predictor += frame_interval + avsync_adjustment + repeat_delay; 1884 1914 if (avsync_predictor >= refreshrate) 1885 1915 { 1916 // LOG(VB_PLAYBACK, LOG_INFO, LOC + 1917 // QString("A/V predict no drop, refreshrate %1, avsync_predictor %2, diverge %3, ") 1918 // .arg(refreshrate).arg(avsync_predictor).arg(diverge)); 1886 1919 int refreshperiodsinframe = avsync_predictor/refreshrate; 1887 1920 avsync_predictor -= refreshrate * refreshperiodsinframe; 1888 1921 } 1889 1922 else 1890 1923 { 1891 1924 dropframe = true; 1892 dbg = "A/V predict drop frame, "; 1925 dbg = QString("A/V predict drop frame, refreshrate %1, avsync_predictor %2, diverge %3, ") 1926 .arg(refreshrate).arg(avsync_predictor).arg(diverge); 1893 1927 } 1894 1928 } 1895 1929 … … void MythPlayer::SetBuffering(bool new_buffering) 2182 2216 } 2183 2217 } 2184 2218 2219 // For debugging playback set this to increase the timeout so that 2220 // playback does not fail if stepping through code. 2221 // Set PREBUFFERDEBUG to any value and you will get 30 minutes. 2222 static char *preBufferDebug = getenv("PREBUFFERDEBUG"); 2223 2185 2224 bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2186 2225 { 2187 2226 if (!videoOutput) … … bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2247 2286 audio.Pause(false); 2248 2287 } 2249 2288 } 2250 if ((waited_for > 500) && !videoOutput->EnoughFreeFrames()) 2289 int msecs = 500; 2290 if (preBufferDebug) 2291 msecs = 1800000; 2292 if ((waited_for > msecs /*500*/) && !videoOutput->EnoughFreeFrames()) 2251 2293 { 2252 2294 LOG(VB_GENERAL, LOG_NOTICE, LOC + 2253 2295 "Timed out waiting for frames, and" … … bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 2257 2299 // to recover from serious problems if frames get leaked. 2258 2300 DiscardVideoFrames(true); 2259 2301 } 2260 if (waited_for > 30000) // 30 seconds for internet streamed media 2302 msecs = 30000; 2303 if (preBufferDebug) 2304 msecs = 1800000; 2305 if (waited_for > msecs /*30000*/) // 30 seconds for internet streamed media 2261 2306 { 2262 2307 LOG(VB_GENERAL, LOG_ERR, LOC + 2263 2308 "Waited too long for decoder to fill video buffers. Exiting.."); … … void MythPlayer::ForceDeinterlacer(const QString &overridefilter) 2382 2427 bool normal = play_speed > 0.99f && play_speed < 1.01f && normal_speed; 2383 2428 videofiltersLock.lock(); 2384 2429 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)) 2430 bool hwset = decoder->GetMythCodecContext()->setDeinterlacer(true, overridefilter); 2431 if (hwset) 2432 { 2433 m_double_framerate = false; 2434 m_double_process = false; 2435 videoOutput->SetupDeinterlace(false); 2436 } 2437 else 2438 { 2439 m_double_framerate = 2440 videoOutput->SetupDeinterlace(true, overridefilter) && 2441 videoOutput->NeedsDoubleFramerate(); 2442 m_double_process = videoOutput->IsExtraProcessingRequired(); 2443 } 2444 if ((decoder->GetMythCodecContext()->getDoubleRate() || m_double_framerate) 2445 && (!CanSupportDoubleRate() || !normal)) 2391 2446 FallbackDeint(); 2392 2447 2393 2448 videofiltersLock.unlock(); … … void MythPlayer::VideoStart(void) 2480 2535 } 2481 2536 else if (videoOutput) 2482 2537 { 2483 // Set up deinterlacing in the video output method 2484 m_double_framerate = 2485 (videoOutput->SetupDeinterlace(true) && 2486 videoOutput->NeedsDoubleFramerate()); 2538 isDeintSetup = false; 2539 // bool hwset = decoder->GetMythCodecContext()->setDeinterlacer(true); 2540 // if (hwset) 2541 // videoOutput->SetupDeinterlace(false); 2542 // else 2543 // { 2544 // // Set up deinterlacing in the video output method 2545 // m_double_framerate = 2546 // (videoOutput->SetupDeinterlace(true) && 2547 // videoOutput->NeedsDoubleFramerate()); 2548 2549 // m_double_process = videoOutput->IsExtraProcessingRequired(); 2550 // } 2551 videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int); 2487 2552 2488 m_double_process = videoOutput->IsExtraProcessingRequired(); 2553 // // Make sure video sync can do it 2554 // if (videosync != NULL && m_double_framerate) 2555 // { 2556 // if (!CanSupportDoubleRate()) 2557 // { 2558 // LOG(VB_GENERAL, LOG_ERR, LOC + 2559 // "Video sync method can't support double framerate " 2560 // "(refresh rate too low for 2x deint)"); 2561 // FallbackDeint(); 2562 // } 2563 // } 2564 } 2565 if (!videosync) 2566 { 2567 videosync = new BusyWaitVideoSync(videoOutput, rf_int); 2568 } 2489 2569 2490 videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int); 2570 InitAVSync(); 2571 videosync->Start(); 2572 } 2491 2573 2574 void MythPlayer::SetupDeinterlace(void) 2575 { 2576 if (isDeintSetup) 2577 return; 2578 if (videoOutput && decoder->GetMythCodecContext()) 2579 { 2580 bool hwset = decoder->GetMythCodecContext()->setDeinterlacer(true); 2581 if (hwset) 2582 videoOutput->SetupDeinterlace(false); 2583 else 2584 { 2585 // Set up deinterlacing in the video output method 2586 m_double_framerate = 2587 (videoOutput->SetupDeinterlace(true) && 2588 videoOutput->NeedsDoubleFramerate()); 2589 2590 m_double_process = videoOutput->IsExtraProcessingRequired(); 2591 } 2492 2592 // Make sure video sync can do it 2493 if (videosync != NULL && m_double_framerate) 2593 if (videosync != NULL && (m_double_framerate 2594 || decoder->GetMythCodecContext()->getDoubleRate())) 2494 2595 { 2495 2596 if (!CanSupportDoubleRate()) 2496 2597 { … … void MythPlayer::VideoStart(void) 2500 2601 FallbackDeint(); 2501 2602 } 2502 2603 } 2604 isDeintSetup = true; 2503 2605 } 2504 if (!videosync)2505 {2506 videosync = new BusyWaitVideoSync(videoOutput, rf_int);2507 }2508 2509 InitAVSync();2510 videosync->Start();2511 2606 } 2512 2607 2608 2513 2609 bool MythPlayer::VideoLoop(void) 2514 2610 { 2611 if (!isDeintSetup) 2612 SetupDeinterlace(); 2515 2613 if (videoPaused || isDummy) 2516 2614 { 2517 2615 switch (player_ctx->GetPIPState()) … … void MythPlayer::EventStart(void) 2999 3097 3000 3098 void MythPlayer::EventLoop(void) 3001 3099 { 3100 if (!isDeintSetup) 3101 SetupDeinterlace(); 3102 3002 3103 // recreate the osd if a reinit was triggered by another thread 3003 3104 if (reinit_osd) 3004 3105 ReinitOSD(); … … void MythPlayer::ChangeSpeed(void) 3807 3908 bool inter = (kScan_Interlaced == m_scan || 3808 3909 kScan_Intr2ndField == m_scan); 3809 3910 3810 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(); 3816 videofiltersLock.unlock(); 3817 3818 m_double_framerate = videoOutput->NeedsDoubleFramerate(); 3819 m_double_process = videoOutput->IsExtraProcessingRequired(); 3911 if (isDeintSetup) 3912 { 3913 videofiltersLock.lock(); 3914 bool doublerate = m_double_framerate || decoder->GetMythCodecContext()->getDoubleRate(); 3915 if (doublerate && !play_1) 3916 { 3917 bool hwdeint = decoder->GetMythCodecContext()->FallbackDeint(); 3918 if (!hwdeint) 3919 videoOutput->FallbackDeint(); 3920 } 3921 else if (!m_double_framerate && CanSupportDoubleRate() && play_1 3922 && (inter || decoder->GetMythCodecContext()->isDeinterlacing())) 3923 { 3924 videoOutput->SetupDeinterlace(false); 3925 bool hwdeint = decoder->GetMythCodecContext()->BestDeint(); 3926 if (!hwdeint) 3927 videoOutput->BestDeint(); 3928 } 3929 videofiltersLock.unlock(); 3930 m_double_framerate = videoOutput->NeedsDoubleFramerate(); 3931 m_double_process = videoOutput->IsExtraProcessingRequired(); 3932 } 3820 3933 } 3821 3934 3822 3935 if (normal_speed && audio.HasAudioOut()) -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index a17364522be..e0c85e00308 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; } … … class MTV_PUBLIC MythPlayer 560 562 FrameScanType detectInterlace(FrameScanType newScan, FrameScanType scan, 561 563 float fps, int video_height); 562 564 virtual void AutoDeint(VideoFrame* frame, bool allow_lock = true); 565 void SetupDeinterlace(void); 566 563 567 564 568 // Private Sets 565 569 void SetPlayingInfo(const ProgramInfo &pginfo); … … class MTV_PUBLIC MythPlayer 851 855 // Debugging variables 852 856 Jitterometer *output_jmeter; 853 857 858 bool isDeintSetup; 859 854 860 private: 855 861 void syncWithAudioStretch(); 856 862 bool disable_passthrough; -
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..4dbbc75bdef
- + 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(AVStream* initStream) : 40 MythCodecContext(initStream) 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 } 149 150 // If we find that it needs more buffers than the default 151 // we can uncomment this and call it from get_format_vaapi2 152 // int Vaapi2Context::SetHwframeCtx(AVCodecContext *ctx, int poolsize) 153 // { 154 // AVBufferRef *hw_frames_ref; 155 // AVHWFramesContext *frames_ctx = NULL; 156 // int err = 0; 157 158 // if (!(hw_frames_ref = av_hwframe_ctx_alloc(ctx->hw_device_ctx))) { 159 // fprintf(stderr, "Failed to create VAAPI frame context.\n"); 160 // return -1; 161 // } 162 // frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data); 163 // frames_ctx->format = AV_PIX_FMT_VAAPI; 164 // frames_ctx->sw_format = AV_PIX_FMT_NV12; 165 // frames_ctx->width = ctx->width; 166 // frames_ctx->height = ctx->height; 167 // frames_ctx->initial_pool_size = poolsize; 168 // if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) { 169 // fprintf(stderr, "Failed to initialize VAAPI frame context."); 170 // av_buffer_unref(&hw_frames_ref); 171 // return err; 172 // } 173 // ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref); 174 // if (!ctx->hw_frames_ctx) 175 // err = AVERROR(ENOMEM); 176 177 // av_buffer_unref(&hw_frames_ref); 178 // return err; 179 // } -
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..28deb7420c9
- + 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(AVStream* initStream); 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(); 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..990b1ae6f7b 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 #ifdef USING_VAAPI2 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..51b62527ecf 100644
a b void VideoOutputOpenGL::GetRenderOptions(render_opts &opts, 40 40 (*opts.safe_renderers)["openmax"].append("opengl"); 41 41 if (opts.decoders->contains("mediacodec")) 42 42 (*opts.safe_renderers)["mediacodec"].append("opengl"); 43 if (opts.decoders->contains("vaapi2")) 44 (*opts.safe_renderers)["vaapi2"].append("opengl"); 43 45 opts.priorities->insert("opengl", 65); 44 46 45 47 // lite profile - no colourspace control, GPU deinterlacing … … bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf, 270 272 StopEmbedding(); 271 273 } 272 274 273 if (!codec_is_std(av_codec_id) && !codec_is_mediacodec(av_codec_id)) 275 if (!codec_is_std(av_codec_id) 276 && !codec_is_mediacodec(av_codec_id) 277 && !codec_is_vaapi2(av_codec_id)) 274 278 { 275 279 LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported."); 276 280 errorState = kError_Unknown; … … QStringList VideoOutputOpenGL::GetAllowedRenderers( 741 745 { 742 746 list << "opengl" << "opengl-lite"; 743 747 } 744 else if (codec_is_mediacodec(myth_codec_id) && !getenv("NO_OPENGL")) 748 else if ((codec_is_mediacodec(myth_codec_id) || codec_is_vaapi2(myth_codec_id)) 749 && !getenv("NO_OPENGL")) 745 750 { 746 751 list << "opengl"; 747 752 } … … bool VideoOutputOpenGL::SetupDeinterlace( 812 817 if (db_vdisp_profile) 813 818 m_deintfiltername = db_vdisp_profile->GetFilteredDeint(overridefilter); 814 819 820 if (m_deintfiltername.startsWith("vaapi2")) 821 return false; 822 815 823 if (!m_deintfiltername.contains("opengl")) 816 824 { 817 825 gl_videochain->SetDeinterlacing(false); -
mythtv/libs/libmythtv/videoout_xv.cpp
diff --git a/mythtv/libs/libmythtv/videoout_xv.cpp b/mythtv/libs/libmythtv/videoout_xv.cpp index ccc756ace78..1074b1ea4c0 100644
a b void VideoOutputXv::GetRenderOptions(render_opts &opts, 122 122 (*opts.safe_renderers)["crystalhd"].append("xshm"); 123 123 (*opts.safe_renderers)["crystalhd"].append("xv-blit"); 124 124 } 125 126 // These could work but needs some debugging so disable for now 127 // if (opts.decoders->contains("vaapi2")) 128 // { 129 // (*opts.safe_renderers)["vaapi2"].append("xlib"); 130 // (*opts.safe_renderers)["vaapi2"].append("xshm"); 131 // (*opts.safe_renderers)["vaapi2"].append("xv-blit"); 132 // } 133 125 134 } 126 135 127 136 /** \class VideoOutputXv … … static QStringList allowed_video_renderers( 2090 2099 2091 2100 QStringList list; 2092 2101 if (codec_is_std(myth_codec_id)) 2102 // this needs some work 2103 // || codec_is_vaapi2(myth_codec_id)) 2093 2104 { 2094 2105 if (xv) 2095 2106 list += "xv-blit"; -
mythtv/libs/libmythtv/videooutbase.cpp
diff --git a/mythtv/libs/libmythtv/videooutbase.cpp b/mythtv/libs/libmythtv/videooutbase.cpp index 60b2d4fa249..dc892c46475 100644
a b bool VideoOutput::SetupDeinterlace(bool interlaced, 607 607 else 608 608 m_deintfiltername = ""; 609 609 610 m_deintFiltMan = new FilterManager;611 610 m_deintFilter = NULL; 611 m_deintFiltMan = NULL; 612 613 if (m_deintfiltername.startsWith("vaapi2")) 614 { 615 m_deinterlacing = false; 616 return false; 617 } 618 619 m_deintFiltMan = new FilterManager; 612 620 613 621 if (!m_deintfiltername.isEmpty()) 614 622 { -
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