Ticket #13311: 20180903_1555_livetv_fix.patch

File 20180903_1555_livetv_fix.patch, 86.1 KB (added by Peter Bennett, 6 years ago)

Fixes Live TV. Also fixes plugins build by removing requirement for mythcodecid.h

  • mythtv/configure

    diff --git a/mythtv/configure b/mythtv/configure
    index f7cfc291b82..f87ee232317 100755
    a b Advanced options (experts only): 
    134134  --disable-vdpau          disable NVidia VDPAU hardware acceleration.
    135135  --disable-crystalhd      disable Broadcom CrystalHD hardware decoder support
    136136  --disable-vaapi          disable VAAPI hardware accelerated video decoding
     137  --disable-vaapi2         disable VAAPI2 hardware accelerated video decoding
    137138  --disable-openmax        disable OpenMAX hardware accelerated video decoding
    138139  --disable-dxva2          disable hardware accelerated decoding on windows
    139140  --disable-mediacodec     disable hardware accelerated decoding on android
    HWACCEL_AUTODETECT_LIBRARY_LIST=" 
    14011402    crystalhd
    14021403    dxva2
    14031404    vaapi
     1405    vaapi2
    14041406    vda
    14051407    vdpau
    14061408"
    USING_LIST=' 
    20402042    opengl
    20412043    opengles
    20422044    vaapi
     2045    vaapi2
    20432046    vdpau
    20442047    openmax
    20452048    mediacodec
    ffmpeg_optset extra_cxxflags extra_ldflags target_os 
    70577060ffmpeg_optset pkg_config prefix libdir as objcc dep_cc host_cc
    70587061ffmpeg_optset host_ld
    70597062ffmpeg_optenable cross_compile libmp3lame libx264 libx265 libvpx libxvid
    7060 ffmpeg_optenable vdpau vaapi libxml2 libass dxva2
     7063ffmpeg_optenable vdpau libxml2 libass dxva2
    70617064ffmpeg_optenable libbluray libfontconfig libfreetype libiec61883
    70627065ffmpeg_optenable crystalhd sdl2 ffplay
    70637066if test $target_os = "android"; then
    if test $target_os = "android"; then 
    70667069else
    70677070    disable mediacodec
    70687071fi
    7069 
     7072if enabled vaapi || enabled vaapi2
     7073    ffopts="$ffopts --enable-vaapi"
     7074fi
    70707075ffmpeg_extra_cflags="$extra_cflags -w"
    70717076
    70727077## Call FFmpeg configure here
    if enabled x11 ; then 
    72727277  echo "xv support                ${xv-no}"
    72737278  echo "VDPAU support             ${vdpau-no}"
    72747279  echo "VAAPI support             ${vaapi-no}"
     7280  echo "VAAPI2 support            ${vaapi2-no}"
    72757281  echo "CrystalHD support         ${crystalhd-no}"
    72767282  echo "OpenMAX support           ${openmax-no}"
    72777283  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; 
    4343#include "lcddevice.h"
    4444
    4545#include "audiooutput.h"
     46#include "mythcodeccontext.h"
    4647
    4748#ifdef USING_VDPAU
    4849#include "videoout_vdpau.h"
    extern "C" { 
    7071#include <QtAndroidExtras>
    7172#endif
    7273
     74#ifdef USING_VAAPI2
     75#include "vaapi2context.h"
     76#endif
     77
    7378extern "C" {
    7479#include "libavutil/avutil.h"
    7580#include "libavutil/error.h"
    int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic, int flags); 
    182187#ifdef USING_VAAPI
    183188int  get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int flags);
    184189#endif
     190#ifdef USING_VAAPI2
     191int  get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic, int flags);
     192#endif
    185193
    186194static int determinable_frame_size(struct AVCodecContext *avctx)
    187195{
    void AvFormatDecoder::GetDecoders(render_opts &opts) 
    385393    opts.decoders->append("vaapi");
    386394    (*opts.equiv_decoders)["vaapi"].append("dummy");
    387395#endif
     396#ifdef USING_VAAPI2
     397    opts.decoders->append("vaapi2");
     398    (*opts.equiv_decoders)["vaapi2"].append("dummy");
     399#endif
    388400#ifdef USING_MEDIACODEC
    389401    opts.decoders->append("mediacodec");
    390402    (*opts.equiv_decoders)["mediacodec"].append("dummy");
    AvFormatDecoder::~AvFormatDecoder() 
    478490    delete ttd;
    479491    delete private_dec;
    480492    delete m_h264_parser;
     493    delete m_mythcodecctx;
    481494
    482495    sws_freeContext(sws_ctx);
    483496
    enum AVPixelFormat get_format_dxva2(struct AVCodecContext *avctx, 
    15151528}
    15161529#endif
    15171530
    1518 #ifdef USING_VAAPI
    15191531static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt)
    15201532{
    15211533    return fmt == AV_PIX_FMT_VAAPI_MOCO ||
    static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt) 
    15231535           fmt == AV_PIX_FMT_VAAPI_VLD;
    15241536}
    15251537
     1538#ifdef USING_VAAPI
     1539
    15261540// Declared separately to allow attribute
    15271541static enum AVPixelFormat get_format_vaapi(struct AVCodecContext *,
    15281542                                         const enum AVPixelFormat *) MUNUSED;
    enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx, 
    15491563}
    15501564#endif
    15511565
     1566#ifdef USING_VAAPI2
     1567static 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
    15521585#ifdef USING_MEDIACODEC
    15531586static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx,
    15541587                                           const enum AVPixelFormat *valid_fmts)
    void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 
    16291662    else
    16301663#endif
    16311664#ifdef USING_VAAPI
    1632     if (CODEC_IS_VAAPI(codec, enc))
     1665    if (CODEC_IS_VAAPI(codec, enc) && codec_is_vaapi(video_codec_id))
    16331666    {
    16341667        enc->get_buffer2     = get_avf_buffer_vaapi;
    16351668        enc->get_format      = get_format_vaapi;
    void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 
    16441677        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    16451678    }
    16461679    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
    16471688#endif
    16481689    if (codec && codec->capabilities & AV_CODEC_CAP_DR1)
    16491690    {
    void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 
    16591700                .arg(ff_codec_id_string(enc->codec_id)));
    16601701    }
    16611702
     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
    16621725    if (FlagIsSet(kDecodeLowRes)    || FlagIsSet(kDecodeSingleThreaded) ||
    16631726        FlagIsSet(kDecodeFewBlocks) || FlagIsSet(kDecodeNoLoopFilter)   ||
    16641727        FlagIsSet(kDecodeNoDecode))
    int AvFormatDecoder::ScanStreams(bool novideo) 
    25362599                    }
    25372600                }
    25382601#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
    25392620            }
    25402621            // default to mpeg2
    25412622            if (video_codec_id == kCodec_NONE)
    int AvFormatDecoder::ScanStreams(bool novideo) 
    25542635            if (!codec_is_std(video_codec_id))
    25552636                thread_count = 1;
    25562637
     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
    25572643            use_frame_timing = false;
    25582644            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)))
    25602648                use_frame_timing = true;
    25612649
    25622650            if (FlagIsSet(kDecodeSingleThreaded))
    int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic, int /*flags*/) 
    30563144}
    30573145#endif
    30583146
     3147#ifdef USING_VAAPI2
     3148int 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
    30593157void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte)
    30603158{
    30613159    if (!len)
    bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 
    36303728            //  into separate routines or separate threads.
    36313729            //  Also now that it always consumes a whole buffer some code
    36323730            //  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);
    36343735
    36353736            if (ret == 0)
    36363737                gotpicture = 1;
    bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 
    36713772                    QString("video avcodec_send_packet error: %1 (%2) gotpicture:%3")
    36723773                    .arg(av_make_error_string(error, sizeof(error), ret2))
    36733774                    .arg(ret2).arg(gotpicture));
    3674             if (ret == AVERROR_INVALIDDATA || ret2 == AVERROR_INVALIDDATA)
     3775            if (++averror_count > SEQ_PKT_ERR_MAX)
    36753776            {
    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;
    36843782            }
    36853783            if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
    36863784                m_streams_changed = true;
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    38403938    }
    38413939    else if (!directrendering)
    38423940    {
     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
    38433962        AVFrame tmppicture;
    38443963
    38453964        VideoFrame *xf = picframe;
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    38473966
    38483967        unsigned char *buf = picframe->buf;
    38493968        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);
    38523971        tmppicture.data[0] = buf + picframe->offsets[0];
    38533972        tmppicture.data[1] = buf + picframe->offsets[1];
    38543973        tmppicture.data[2] = buf + picframe->offsets[2];
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    38573976        tmppicture.linesize[2] = picframe->pitches[2];
    38583977
    38593978        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,
    38633982                                       AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
    38643983                                       NULL, NULL, NULL);
    38653984        if (!sws_ctx)
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    38673986            LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate sws context");
    38683987            return false;
    38693988        }
    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(),
    38713990                  tmppicture.data, tmppicture.linesize);
    38723991
    38733992        if (xf)
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    38803999            xf->aspect = current_aspect;
    38814000            m_parent->DiscardVideoFrame(xf);
    38824001        }
     4002        if (tmp_frame)
     4003            av_frame_free(&tmp_frame);
    38834004    }
    38844005    else if (!picframe)
    38854006    {
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    39284049        // If fps has doubled due to frame-doubling deinterlace
    39294050        // Set fps to double value.
    39304051        double fpschange = calcfps / fps;
     4052        int prior = fpsMultiplier;
    39314053        if (fpschange > 1.9 && fpschange < 2.1)
    39324054            fpsMultiplier = 2;
    39334055        if (fpschange > 0.5 && fpschange < 0.6)
    39344056            fpsMultiplier = 1;
     4057        if (fpsMultiplier != prior)
     4058            m_parent->SetFrameRate(fps);
    39354059    }
    39364060
    39374061    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 
    206206
    207207    friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic,
    208208                              int flags);
     209    friend int get_avf_buffer_vaapi2(struct AVCodecContext *c, AVFrame *pic,
     210                              int flags);
    209211    friend void release_avf_buffer(void *opaque, uint8_t *data);
    210212
    211213    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) 
    4545      video_inverted(false),
    4646      decodeAllSubtitles(false),
    4747      // language preference
    48       languagePreference(iso639_get_language_key_list())
     48      languagePreference(iso639_get_language_key_list()),
     49      m_mythcodecctx(NULL)
    4950{
    5051    ResetTracks();
    5152    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; 
    1818class TeletextViewer;
    1919class MythPlayer;
    2020class AudioPlayer;
     21class MythCodecContext;
    2122
    2223const int kDecoderProbeBufferSize = 256 * 1024;
    2324
    class DecoderBase 
    270271    bool GetVideoInverted(void) const { return video_inverted; }
    271272    void TrackTotalDuration(bool track) { trackTotalDuration = track; }
    272273    int GetfpsMultiplier(void) { return fpsMultiplier; }
     274    MythCodecContext *GetMythCodecContext(void) { return m_mythcodecctx; }
    273275
    274276  protected:
    275277    virtual int  AutoSelectTrack(uint type);
    class DecoderBase 
    359361    StreamInfo  selectedTrack[(uint)kTrackTypeCount];
    360362    /// language preferences for auto-selection of streams
    361363    vector<int> languagePreference;
     364    MythCodecContext *m_mythcodecctx;
    362365};
    363366
    364367inline 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 { 
    366366    HEADERS += decoderbase.h
    367367    HEADERS += nuppeldecoder.h          avformatdecoder.h
    368368    HEADERS += privatedecoder.h
     369    HEADERS += mythcodeccontext.h
    369370    SOURCES += decoderbase.cpp
    370371    SOURCES += nuppeldecoder.cpp        avformatdecoder.cpp
    371372    SOURCES += privatedecoder.cpp
     373    SOURCES += mythcodeccontext.cpp
    372374
    373375    using_crystalhd {
    374376        DEFINES += USING_CRYSTALHD
    using_frontend { 
    505507        using_opengl_video:DEFINES += USING_GLVAAPI
    506508    }
    507509
     510    using_vaapi2 {
     511        DEFINES += USING_VAAPI2
     512        HEADERS += vaapi2context.h
     513        SOURCES += vaapi2context.cpp
     514    }
     515
    508516    using_mediacodec {
    509517        DEFINES += USING_MEDIACODEC
    510518        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  
    1010#include "mythavutil.h"
    1111#include "mythcorecontext.h"
    1212#include "mythconfig.h"
     13#include "vaapi2context.h"
    1314extern "C" {
    1415#include "libswscale/swscale.h"
    1516#include "libavfilter/avfilter.h"
    AVCodecContext *MythCodecMap::getCodecContext(const AVStream *stream, 
    388389    const AVCodec *pCodec, bool nullCodec)
    389390{
    390391    QMutexLocker lock(&mapLock);
    391     AVCodecContext *avctx = streamMap.value(stream, NULL);
     392    AVCodecContext *avctx = streamAvMap.value(stream, NULL);
    392393    if (!avctx)
    393394    {
    394395        if (stream == NULL || stream->codecpar == NULL)
    AVCodecContext *MythCodecMap::getCodecContext(const AVStream *stream, 
    411412            avcodec_free_context(&avctx);
    412413        if (avctx)
    413414        {
    414             av_codec_set_pkt_timebase(avctx, stream->time_base);
    415             streamMap.insert(stream, avctx);
     415            avctx->pkt_timebase =  stream->time_base;
     416            streamAvMap.insert(stream, avctx);
    416417        }
    417418    }
    418419    return avctx;
    AVCodecContext *MythCodecMap::getCodecContext(const AVStream *stream, 
    420421
    421422AVCodecContext *MythCodecMap::hasCodecContext(const AVStream *stream)
    422423{
    423     return streamMap.value(stream, NULL);
     424    return streamAvMap.value(stream, NULL);
    424425}
    425426
    426427void MythCodecMap::freeCodecContext(const AVStream *stream)
    427428{
    428429    QMutexLocker lock(&mapLock);
    429     AVCodecContext *avctx = streamMap.take(stream);
     430    AVCodecContext *avctx = streamAvMap.take(stream);
    430431    if (avctx)
    431432        avcodec_free_context(&avctx);
    432433}
    void MythCodecMap::freeCodecContext(const AVStream *stream) 
    434435void MythCodecMap::freeAllCodecContexts()
    435436{
    436437    QMutexLocker lock(&mapLock);
    437     QMap<const AVStream*, AVCodecContext*>::iterator i = streamMap.begin();
    438     while (i != streamMap.end()) {
     438    QMap<const AVStream*, AVCodecContext*>::iterator i = streamAvMap.begin();
     439    while (i != streamAvMap.end()) {
    439440        const AVStream *stream = i.key();
    440441        ++i;
    441442        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 
    9898    void freeCodecContext(const AVStream*);
    9999    void freeAllCodecContexts();
    100100  protected:
    101     QMap<const AVStream*, AVCodecContext*> streamMap;
     101    QMap<const AVStream*, AVCodecContext*> streamAvMap;
    102102    QMutex mapLock;
    103103};
    104104
  • 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
     34extern "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
     48MythCodecContext::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
     63MythCodecContext::~MythCodecContext()
     64{
     65    CloseFilters();
     66}
     67
     68// static
     69MythCodecContext *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
     81QStringList 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
     125int 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
     205bool 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
     252bool MythCodecContext::BestDeint(void)
     253{
     254    deinterlacername.clear();
     255    return setDeinterlacer(true);
     256}
     257
     258bool MythCodecContext::FallbackDeint(void)
     259{
     260    return setDeinterlacer(true,GetFallbackDeint());
     261}
     262
     263QString MythCodecContext::GetFallbackDeint(void)
     264{
     265    VideoOutput *vo = player->GetVideoOutput();
     266    VideoDisplayProfile *vdisp_profile = vo->GetProfile();
     267    return vdisp_profile->GetFallbackDeinterlacer();
     268}
     269
     270
     271int 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(&params);
     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));
     445end:
     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
     458void 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
     29struct AVCodecContext;
     30struct AVFrame;
     31struct AVStream;
     32struct AVFilterContext;
     33struct AVFilterGraph;
     34struct AVBufferRef;
     35class MythPlayer;
     36
     37#include "mythtvexp.h"
     38#include "mythcodecid.h"
     39
     40class 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) 
    123123        case kCodec_HEVC_MEDIACODEC:
    124124            return "HEVC MEDIACODEC";
    125125
     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
    126147        default:
    127148            break;
    128149    }
    int myth2av_codecid(MythCodecID codec_id, bool &vdpau) 
    305326            ret = AV_CODEC_ID_HEVC;
    306327            break;
    307328
     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
    308360        default:
    309361            LOG(VB_GENERAL, LOG_ERR,
    310362                QString("Error: MythCodecID %1 has not been "
    QString get_encoding_type(MythCodecID codecid) 
    356408        case kCodec_MPEG1_VAAPI:
    357409        case kCodec_MPEG1_DXVA2:
    358410        case kCodec_MPEG1_MEDIACODEC:
     411        case kCodec_MPEG1_VAAPI2:
    359412        case kCodec_MPEG2:
    360413        case kCodec_MPEG2_VDPAU:
    361414        case kCodec_MPEG2_VAAPI:
    362415        case kCodec_MPEG2_DXVA2:
    363416        case kCodec_MPEG2_MEDIACODEC:
     417        case kCodec_MPEG2_VAAPI2:
    364418            return "MPEG-2";
    365419
    366420        case kCodec_H263:
    QString get_encoding_type(MythCodecID codecid) 
    368422        case kCodec_H263_VAAPI:
    369423        case kCodec_H263_DXVA2:
    370424        case kCodec_H263_MEDIACODEC:
     425        case kCodec_H263_VAAPI2:
    371426            return "H.263";
    372427
    373428        case kCodec_NUV_MPEG4:
    QString get_encoding_type(MythCodecID codecid) 
    376431        case kCodec_MPEG4_VAAPI:
    377432        case kCodec_MPEG4_DXVA2:
    378433        case kCodec_MPEG4_MEDIACODEC:
     434        case kCodec_MPEG4_VAAPI2:
    379435            return "MPEG-4";
    380436
    381437        case kCodec_H264:
    QString get_encoding_type(MythCodecID codecid) 
    383439        case kCodec_H264_VAAPI:
    384440        case kCodec_H264_DXVA2:
    385441        case kCodec_H264_MEDIACODEC:
     442        case kCodec_H264_VAAPI2:
    386443            return "H.264";
    387444
    388445        case kCodec_VC1:
    QString get_encoding_type(MythCodecID codecid) 
    390447        case kCodec_VC1_VAAPI:
    391448        case kCodec_VC1_DXVA2:
    392449        case kCodec_VC1_MEDIACODEC:
     450        case kCodec_VC1_VAAPI2:
    393451            return "VC-1";
    394452
    395453        case kCodec_WMV3:
    QString get_encoding_type(MythCodecID codecid) 
    397455        case kCodec_WMV3_VAAPI:
    398456        case kCodec_WMV3_DXVA2:
    399457        case kCodec_WMV3_MEDIACODEC:
     458        case kCodec_WMV3_VAAPI2:
    400459            return "WMV3";
    401460
    402461        case kCodec_VP8:
    QString get_encoding_type(MythCodecID codecid) 
    404463        case kCodec_VP8_VAAPI:
    405464        case kCodec_VP8_DXVA2:
    406465        case kCodec_VP8_MEDIACODEC:
     466        case kCodec_VP8_VAAPI2:
    407467            return "VP8";
    408468
    409469        case kCodec_VP9:
    QString get_encoding_type(MythCodecID codecid) 
    411471        case kCodec_VP9_VAAPI:
    412472        case kCodec_VP9_DXVA2:
    413473        case kCodec_VP9_MEDIACODEC:
     474        case kCodec_VP9_VAAPI2:
    414475            return "VP8";
    415476
    416477        case kCodec_HEVC:
    QString get_encoding_type(MythCodecID codecid) 
    418479        case kCodec_HEVC_VAAPI:
    419480        case kCodec_HEVC_DXVA2:
    420481        case kCodec_HEVC_MEDIACODEC:
     482        case kCodec_HEVC_VAAPI2:
    421483            return "HEVC";
    422484
    423485        case kCodec_NONE:
    QString get_encoding_type(MythCodecID codecid) 
    426488        case kCodec_VAAPI_END:
    427489        case kCodec_DXVA2_END:
    428490        case kCodec_MEDIACODEC_END:
     491        case kCodec_VAAPI2_END:
    429492            return QString();
    430493    }
    431494
    QString get_decoder_name(MythCodecID codec_id) 
    446509    if (codec_is_mediacodec(codec_id))
    447510        return "mediacodec";
    448511
     512    if (codec_is_vaapi2(codec_id))
     513        return "vaapi2";
     514
    449515    return "ffmpeg";
    450516}
  • 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 
    9191
    9292    kCodec_MEDIACODEC_END,
    9393
     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
    94109} MythCodecID;
    95110
    96111// MythCodecID convenience functions
    typedef enum 
    113128                                (id == kCodec_VC1_DXVA2)))
    114129#define codec_is_mediacodec(id) ((id > kCodec_MEDIACODEC_BEGIN) &&     \
    115130                               (id < kCodec_MEDIACODEC_END))
     131#define codec_is_vaapi2(id)    ((id > kCodec_VAAPI2_BEGIN) &&     \
     132                               (id < kCodec_VAAPI2_END))
    116133
    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))
    118135
    119136QString get_encoding_type(MythCodecID codecid);
    120137QString get_decoder_name(MythCodecID codec_id);
    int mpeg_version(int codec_id); 
    156173#define CODEC_IS_MEDIACODEC(codec) (0)
    157174#endif
    158175
    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 
    164176#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; 
    5353#include "mythuiactions.h"              // for ACTION_LEFT, ACTION_RIGHT, etc
    5454#include "ringbuffer.h"                 // for RingBuffer, etc
    5555#include "tv_actions.h"                 // for ACTION_BIGJUMPFWD, etc
     56#include "mythcodeccontext.h"
    5657
    5758extern "C" {
    5859#include "vsync.h"
    MythPlayer::MythPlayer(PlayerFlags flags) 
    226227      bufferingCounter(0),
    227228      // Debugging variables
    228229      output_jmeter(new Jitterometer(LOC)),
     230      isDeintSetup(false),
    229231      disable_passthrough(false)
    230232{
    231233    memset(&tc_lastval, 0, sizeof(tc_lastval));
    void MythPlayer::FallbackDeint(void) 
    676678     m_double_process   = false;
    677679
    678680     if (videoOutput)
    679          videoOutput->FallbackDeint();
     681     {
     682        videoOutput->SetupDeinterlace(false);
     683        bool hwset = decoder->GetMythCodecContext()->FallbackDeint();
     684        if (!hwset)
     685            videoOutput->FallbackDeint();
     686     }
    680687}
    681688
    682689void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock)
    void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock) 
    715722
    716723    if ((m_scan_tracker % 400) == 0)
    717724    {
    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
    719737        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("%1 %2 frames seen.")
    720738                .arg(abs(m_scan_tracker)).arg(type));
    721739    }
    void MythPlayer::SetScanType(FrameScanType scan) 
    763781
    764782    if (interlaced)
    765783    {
    766         m_deint_possible = videoOutput->SetDeinterlacingEnabled(true);
    767         if (!m_deint_possible)
    768         {
    769             LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to enable deinterlacing");
    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            }
    773791        if (videoOutput->NeedsDoubleFramerate())
    774792        {
    775793            m_double_framerate = true;
    void MythPlayer::SetScanType(FrameScanType scan) 
    782800            }
    783801        }
    784802        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");
    786804    }
    787805    else
    788806    {
    void MythPlayer::SetScanType(FrameScanType scan) 
    791809            m_double_process = false;
    792810            m_double_framerate = false;
    793811            videoOutput->SetDeinterlacingEnabled(false);
    794             LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled deinterlacing");
     812            LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled Video Output based deinterlacing");
    795813        }
    796814    }
    797815
    void MythPlayer::SetScanType(FrameScanType scan) 
    801819void MythPlayer::SetVideoParams(int width, int height, double fps,
    802820                                FrameScanType scan, QString codecName)
    803821{
     822
     823    SetupDeinterlace();
    804824    bool paramsChanged = false;
    805825
    806826    if (width >= 1 && height >= 1)
    void MythPlayer::SetVideoParams(int width, int height, double fps, 
    849869    m_scan_tracker = (m_scan == kScan_Interlaced) ? 2 : 0;
    850870}
    851871
     872
     873void 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
    852882void MythPlayer::SetFileLength(int total, int frames)
    853883{
    854884    totalLength = total;
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18831913        avsync_predictor += frame_interval + avsync_adjustment + repeat_delay;
    18841914        if (avsync_predictor >= refreshrate)
    18851915        {
     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));
    18861919            int refreshperiodsinframe = avsync_predictor/refreshrate;
    18871920            avsync_predictor -= refreshrate * refreshperiodsinframe;
    18881921        }
    18891922        else
    18901923        {
    18911924            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);
    18931927        }
    18941928    }
    18951929
    void MythPlayer::SetBuffering(bool new_buffering) 
    21822216    }
    21832217}
    21842218
     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.
     2222static char *preBufferDebug = getenv("PREBUFFERDEBUG");
     2223
    21852224bool MythPlayer::PrebufferEnoughFrames(int min_buffers)
    21862225{
    21872226    if (!videoOutput)
    bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 
    22472286                audio.Pause(false);
    22482287            }
    22492288        }
    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())
    22512293        {
    22522294            LOG(VB_GENERAL, LOG_NOTICE, LOC +
    22532295                "Timed out waiting for frames, and"
    bool MythPlayer::PrebufferEnoughFrames(int min_buffers) 
    22572299            // to recover from serious problems if frames get leaked.
    22582300            DiscardVideoFrames(true);
    22592301        }
    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
    22612306        {
    22622307            LOG(VB_GENERAL, LOG_ERR, LOC +
    22632308                "Waited too long for decoder to fill video buffers. Exiting..");
    void MythPlayer::ForceDeinterlacer(const QString &overridefilter) 
    23822427    bool normal = play_speed > 0.99f && play_speed < 1.01f && normal_speed;
    23832428    videofiltersLock.lock();
    23842429
    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))
    23912446        FallbackDeint();
    23922447
    23932448    videofiltersLock.unlock();
    void MythPlayer::VideoStart(void) 
    24802535    }
    24812536    else if (videoOutput)
    24822537    {
    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);
    24872552
    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    }
    24892569
    2490         videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int);
     2570    InitAVSync();
     2571    videosync->Start();
     2572}
    24912573
     2574void 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        }
    24922592        // 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()))
    24942595        {
    24952596            if (!CanSupportDoubleRate())
    24962597            {
    void MythPlayer::VideoStart(void) 
    25002601                FallbackDeint();
    25012602            }
    25022603        }
     2604        isDeintSetup = true;
    25032605    }
    2504     if (!videosync)
    2505     {
    2506         videosync = new BusyWaitVideoSync(videoOutput, rf_int);
    2507     }
    2508 
    2509     InitAVSync();
    2510     videosync->Start();
    25112606}
    25122607
     2608
    25132609bool MythPlayer::VideoLoop(void)
    25142610{
     2611    if (!isDeintSetup)
     2612        SetupDeinterlace();
    25152613    if (videoPaused || isDummy)
    25162614    {
    25172615        switch (player_ctx->GetPIPState())
    void MythPlayer::EventStart(void) 
    29993097
    30003098void MythPlayer::EventLoop(void)
    30013099{
     3100    if (!isDeintSetup)
     3101        SetupDeinterlace();
     3102
    30023103    // recreate the osd if a reinit was triggered by another thread
    30033104    if (reinit_osd)
    30043105        ReinitOSD();
    void MythPlayer::ChangeSpeed(void) 
    38073908        bool inter  = (kScan_Interlaced   == m_scan  ||
    38083909                       kScan_Intr2ndField == m_scan);
    38093910
    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        }
    38203933    }
    38213934
    38223935    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 
    166166    void SetVideoResize(const QRect &videoRect);
    167167    void EnableFrameRateMonitor(bool enable = false);
    168168    void ForceDeinterlacer(const QString &override = QString());
     169    void SetFrameRate(double fps);
    169170
    170171    // Gets
    171172    QSize   GetVideoBufferSize(void) const    { return video_dim; }
    class MTV_PUBLIC MythPlayer 
    240241                                int &vw, int &vh, float &ar);
    241242    InteractiveTV *GetInteractiveTV(void);
    242243    VideoOutput *GetVideoOutput(void)       { return videoOutput; }
     244    MythCodecContext *GetMythCodecContext(void) { return decoder->GetMythCodecContext(); }
    243245
    244246    // Title stuff
    245247    virtual bool SwitchTitle(int /*title*/) { return false; }
    class MTV_PUBLIC MythPlayer 
    560562    FrameScanType detectInterlace(FrameScanType newScan, FrameScanType scan,
    561563                                  float fps, int video_height);
    562564    virtual void AutoDeint(VideoFrame* frame, bool allow_lock = true);
     565    void  SetupDeinterlace(void);
     566
    563567
    564568    // Private Sets
    565569    void SetPlayingInfo(const ProgramInfo &pginfo);
    class MTV_PUBLIC MythPlayer 
    851855    // Debugging variables
    852856    Jitterometer *output_jmeter;
    853857
     858    bool isDeintSetup;
     859
    854860  private:
    855861    void syncWithAudioStretch();
    856862    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; 
    7878#include "programtypes.h"
    7979#include "ringbuffer.h"                 // for RingBuffer, etc
    8080#include "tv_actions.h"                 // for ACTION_TOGGLESLEEP, etc
     81#include "mythcodeccontext.h"
    8182
    8283#if ! HAVE_ROUND
    8384#define round(x) ((int) ((x) + 0.5))
    bool TV::MenuItemDisplayPlayback(const MenuItemContext &c) 
    1176711768    }
    1176811769    else if (matchesGroup(actionName, "DEINTERLACER_", category, prefix))
    1176911770    {
    11770         if (m_tvm_scan_type != kScan_Progressive)
     11771        if (m_tvm_scan_type != kScan_Progressive
     11772            || ctx->player->GetMythCodecContext()->isDeinterlacing())
    1177111773        {
    1177211774            foreach (QString deint, m_tvm_deinterlacers)
    1177311775            {
    void TV::PlaybackMenuInit(const MenuBase &menu) 
    1246312465        m_tvm_subs_havetext      = ctx->player->HasTextSubtitles();
    1246412466        m_tvm_subs_forcedon      = ctx->player->GetAllowForcedSubtitles();
    1246512467        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();
    1246812476        if (m_tvm_visual)
    1246912477            m_tvm_visualisers = ctx->player->GetVisualiserList();
    1247012478        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
     31extern "C" {
     32    #include "libavutil/pixfmt.h"
     33    #include "libavutil/hwcontext.h"
     34    #include "libavcodec/avcodec.h"
     35}
     36
     37#define LOC QString("VAAPI2: ")
     38
     39Vaapi2Context::Vaapi2Context(AVStream* initStream) :
     40    MythCodecContext(initStream)
     41{
     42
     43}
     44
     45MythCodecID 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
     88int 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
     119QString 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
     140bool Vaapi2Context::isValidDeinterlacer(QString filtername)
     141{
     142    return filtername.startsWith("vaapi2");
     143}
     144
     145QStringList 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
     33extern "C" {
     34    #include "libavcodec/avcodec.h"
     35}
     36
     37class 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; 
    88#include "mythlogging.h"
    99#include "videooutbase.h"
    1010#include "avformatdecoder.h"
     11#include "mythcodeccontext.h"
    1112
    1213
    1314// options are NNN NNN-MMM 0-MMM NNN-99999 >NNN >=NNN <MMM <=MMM or blank
    bool ProfileItem::IsValid(QString *reason) const 
    258259    }
    259260
    260261    QStringList deints    = VideoDisplayProfile::GetDeinterlacers(renderer);
     262    QStringList decoderdeints  = MythCodecContext::GetDeinterlacers(decoder);
     263    deints.append(decoderdeints);
    261264    QString     deint0    = Get("pref_deint0");
    262265    QString     deint1    = Get("pref_deint1");
    263266    if (!deint0.isEmpty() && !deints.contains(deint0))
    QString VideoDisplayProfile::GetDecoderName(const QString &decoder) 
    852855        dec_name["dxva2"]    = QObject::tr("Windows hardware acceleration");
    853856        dec_name["vda"]      = QObject::tr("Mac VDA hardware acceleration");
    854857        dec_name["mediacodec"] = QObject::tr("Android MediaCodec decoder");
     858        dec_name["vaapi2"]   = QObject::tr("VAAPI2 acceleration");
    855859    }
    856860
    857861    QString ret = decoder;
    QString VideoDisplayProfile::GetDecoderHelp(QString decoder) 
    913917            "Mediacodec will use the graphics hardware to "
    914918            "accelerate video decoding on Android. ");
    915919
     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
    916925    return msg;
    917926}
    918927
    QString VideoDisplayProfile::GetDeinterlacerName(const QString &short_name) 
    941950    else if ("fieldorderdoubleprocessdeint" == short_name)
    942951        return QObject::tr("Interlaced (2x)");
    943952    else if ("opengllinearblend" == short_name)
    944         return QObject::tr("Linear blend (HW)");
     953        return QObject::tr("Linear blend (HW-GL)");
    945954    else if ("openglkerneldeint" == short_name)
    946         return QObject::tr("Kernel (HW)");
     955        return QObject::tr("Kernel (HW-GL)");
    947956    else if ("openglbobdeint" == short_name)
    948         return QObject::tr("Bob (2x, HW)");
     957        return QObject::tr("Bob (2x, HW-GL)");
    949958    else if ("openglonefield" == short_name)
    950         return QObject::tr("One field (HW)");
     959        return QObject::tr("One field (HW-GL)");
    951960    else if ("opengldoubleratekerneldeint" == short_name)
    952         return QObject::tr("Kernel (2x, HW)");
     961        return QObject::tr("Kernel (2x, HW-GL)");
    953962    else if ("opengldoubleratelinearblend" == short_name)
    954         return QObject::tr("Linear blend (2x, HW)");
     963        return QObject::tr("Linear blend (2x, HW-GL)");
    955964    else if ("opengldoubleratefieldorder" == short_name)
    956         return QObject::tr("Interlaced (2x, HW)");
     965        return QObject::tr("Interlaced (2x, HW-GL)");
    957966    else if ("vdpauonefield" == short_name)
    958967        return QObject::tr("One Field (1x, HW)");
    959968    else if ("vdpaubobdeint" == short_name)
    QString VideoDisplayProfile::GetDeinterlacerName(const QString &short_name) 
    978987    else if ("openmaxlinedouble" == short_name)
    979988        return QObject::tr("Line double (HW)");
    980989#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
    9811012
    9821013    return "";
    9831014}
    void VideoDisplayProfile::CreateProfiles(const QString &hostname) 
    14681499        CreateProfile(groupid, 1, "", "", "",
    14691500                      "mediacodec", 4, true, "opengl",
    14701501                      "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",
    14721516                      "");
    14731517    }
    14741518#endif
    QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 
    16151659
    16161660    QString kUsingGPU = QObject::tr("(Hardware Accelerated)");
    16171661
     1662    QString kUsingVA = QObject::tr("(VAAPI Hardware Accelerated)");
     1663
     1664    QString kUsingGL = QObject::tr("(OpenGL Hardware Accelerated)");
     1665
    16181666    QString kGreedyHMsg = QObject::tr(
    16191667        "This deinterlacer uses several fields to reduce motion blur. "
    16201668        "It has increased CPU requirements.");
    QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 
    16351683        "This deinterlacer uses multiple fields to reduce motion blur "
    16361684        "and smooth edges. ");
    16371685
     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
    16381698    if (deint == "none")
    16391699        msg = kNoneMsg;
    16401700    else if (deint == "onefield")
    QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 
    16481708    else if (deint == "kerneldoubleprocessdeint")
    16491709        msg = kKernelMsg + " " + kDoubleRateMsg;
    16501710    else if (deint == "openglonefield")
    1651         msg = kOneFieldMsg + " " + kUsingGPU;
     1711        msg = kOneFieldMsg + " " + kUsingGL;
    16521712    else if (deint == "openglbobdeint")
    1653         msg = kBobMsg + " " + kUsingGPU;
     1713        msg = kBobMsg + " " + kUsingGL;
    16541714    else if (deint == "opengllinearblend")
    1655         msg = kLinearBlendMsg + " " + kUsingGPU;
     1715        msg = kLinearBlendMsg + " " + kUsingGL;
    16561716    else if (deint == "openglkerneldeint")
    1657         msg = kKernelMsg + " " + kUsingGPU;
     1717        msg = kKernelMsg + " " + kUsingGL;
    16581718    else if (deint == "opengldoubleratelinearblend")
    1659         msg = kLinearBlendMsg + " " +  kDoubleRateMsg + " " + kUsingGPU;
     1719        msg = kLinearBlendMsg + " " +  kDoubleRateMsg + " " + kUsingGL;
    16601720    else if (deint == "opengldoubleratekerneldeint")
    1661         msg = kKernelMsg + " " +  kDoubleRateMsg + " " + kUsingGPU;
     1721        msg = kKernelMsg + " " +  kDoubleRateMsg + " " + kUsingGL;
    16621722    else if (deint == "opengldoubleratefieldorder")
    1663         msg = kFieldOrderMsg + " " +  kDoubleRateMsg  + " " + kUsingGPU;
     1723        msg = kFieldOrderMsg + " " +  kDoubleRateMsg  + " " + kUsingGL;
    16641724    else if (deint == "greedyhdeint")
    16651725        msg = kGreedyHMsg;
    16661726    else if (deint == "greedyhdoubleprocessdeint")
    QString VideoDisplayProfile::GetDeinterlacerHelp(const QString &deint) 
    16871747        msg = kOneFieldMsg + " " + kUsingGPU;
    16881748    else if (deint == "vaapibobdeint")
    16891749        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;
    16901771    else
    16911772        msg = QObject::tr("'%1' has not been documented yet.").arg(deint);
    16921773
  • 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, 
    4040        (*opts.safe_renderers)["openmax"].append("opengl");
    4141    if (opts.decoders->contains("mediacodec"))
    4242        (*opts.safe_renderers)["mediacodec"].append("opengl");
     43    if (opts.decoders->contains("vaapi2"))
     44        (*opts.safe_renderers)["vaapi2"].append("opengl");
    4345    opts.priorities->insert("opengl", 65);
    4446
    4547    // lite profile - no colourspace control, GPU deinterlacing
    bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf, 
    270272        StopEmbedding();
    271273    }
    272274
    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))
    274278    {
    275279        LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported.");
    276280        errorState = kError_Unknown;
    QStringList VideoOutputOpenGL::GetAllowedRenderers( 
    741745    {
    742746        list << "opengl" << "opengl-lite";
    743747    }
    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"))
    745750    {
    746751        list << "opengl";
    747752    }
    bool VideoOutputOpenGL::SetupDeinterlace( 
    812817    if (db_vdisp_profile)
    813818        m_deintfiltername = db_vdisp_profile->GetFilteredDeint(overridefilter);
    814819
     820    if (m_deintfiltername.startsWith("vaapi2"))
     821        return false;
     822
    815823    if (!m_deintfiltername.contains("opengl"))
    816824    {
    817825        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, 
    122122        (*opts.safe_renderers)["crystalhd"].append("xshm");
    123123        (*opts.safe_renderers)["crystalhd"].append("xv-blit");
    124124    }
     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
    125134}
    126135
    127136/** \class  VideoOutputXv
    static QStringList allowed_video_renderers( 
    20902099
    20912100    QStringList list;
    20922101    if (codec_is_std(myth_codec_id))
     2102    // this needs some work
     2103    //  || codec_is_vaapi2(myth_codec_id))
    20932104    {
    20942105        if (xv)
    20952106            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, 
    607607        else
    608608            m_deintfiltername = "";
    609609
    610         m_deintFiltMan = new FilterManager;
    611610        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;
    612620
    613621        if (!m_deintfiltername.isEmpty())
    614622        {
  • 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 
    7676    virtual void PrepareFrame(VideoFrame *buffer, FrameScanType,
    7777                              OSD *osd) = 0;
    7878    virtual void Show(FrameScanType) = 0;
     79    VideoDisplayProfile *GetProfile() { return db_vdisp_profile; }
     80
    7981
    8082    virtual void WindowResized(const QSize &) {}
    8183
  • 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  
    3838#include "mythuihelper.h"
    3939#include "mythuidefines.h"
    4040#include "langsettings.h"
     41#include "mythcodeccontext.h"
    4142
    4243#ifdef USING_AIRPLAY
    4344#include "AirPlay/mythraopconnection.h"
    static HostSpinBoxSetting *AudioReadAhead() 
    6667    return gc;
    6768}
    6869
     70#ifdef USING_VAAPI2
     71static 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
    6989#if CONFIG_DEBUGTYPE
    7090static HostCheckBoxSetting *FFmpegDemuxer()
    7191{
    void PlaybackProfileItemConfig::decoderChanged(const QString &dec) 
    937957
    938958    decoder->setHelpText(VideoDisplayProfile::GetDecoderHelp(dec));
    939959
     960    QString vrenderer2 = vidrend->getValue();
     961    vrenderChanged(vrenderer2);
     962
    940963    InitLabel();
    941964}
    942965
    void PlaybackProfileItemConfig::vrenderChanged(const QString &renderer) 
    944967{
    945968    QStringList osds    = VideoDisplayProfile::GetOSDs(renderer);
    946969    QStringList deints  = VideoDisplayProfile::GetDeinterlacers(renderer);
     970    QString decodername = decoder->getValue();
     971    QStringList decoderdeints  = MythCodecContext::GetDeinterlacers(decodername);
     972    deints.append(decoderdeints);
    947973    QString     losd    = osdrend->getValue();
    948974    QString     ldeint0 = deint0->getValue();
    949975    QString     ldeint1 = deint1->getValue();
    void PlaybackSettings::Load(void) 
    39583984    GroupSetting* general = new GroupSetting();
    39593985    general->setLabel(tr("General Playback"));
    39603986    general->addChild(RealtimePriority());
     3987#ifdef USING_VAAPI2
     3988    general->addChild(VAAPIDevice());
     3989#endif
    39613990    general->addChild(AudioReadAhead());
    39623991    general->addChild(JumpToProgramOSD());
    39633992    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 
    116116using_opengl_video:DEFINES += USING_OPENGL_VIDEO
    117117using_vdpau:DEFINES += USING_VDPAU
    118118using_vaapi:using_opengl_video:DEFINES += USING_GLVAAPI
     119using_vaapi2:DEFINES += USING_VAAPI2
    119120
    120121using_pulse:DEFINES += USING_PULSE
    121122using_pulseoutput: DEFINES += USING_PULSEOUTPUT