Ejemplo n.º 1
0
bool VideoOutputVDPAU::Init(int width, int height, float aspect,
                            WId winid, const QRect &win_rect,
                            MythCodecID codec_id)
{
    // Attempt to free up as much video memory as possible
    // only works when using the VDPAU painter for the UI
    MythPainter *painter = GetMythPainter();
    if (painter)
        painter->FreeResources();

    m_win = winid;
    QMutexLocker locker(&m_lock);
    window.SetNeedRepaint(true);
    bool ok = VideoOutput::Init(width, height, aspect, winid, win_rect,codec_id);
    if (db_vdisp_profile)
        db_vdisp_profile->SetVideoRenderer("vdpau");

    InitDisplayMeasurements(width, height, true);
    ParseOptions();
    if (ok) ok = InitRender();
    if (ok) ok = InitBuffers();
    if (!ok)
    {
        TearDown();
        return ok;
    }

    InitPictureAttributes();
    MoveResize();
    LOG(VB_PLAYBACK, LOG_INFO, LOC +
        QString("Created VDPAU context (%1 decode)")
            .arg(codec_is_std(video_codec_id) ? "software" : "GPU"));

    return ok;
}
Ejemplo n.º 2
0
QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers(
    MythCodecID myth_codec_id, const QSize &video_dim)
{
    (void) video_dim;
    QStringList list;
    if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) &&
         !getenv("NO_VAAPI"))
    {
        list += "openglvaapi";
    }
    return list;
}
Ejemplo n.º 3
0
QStringList VideoOutputOpenGL::GetAllowedRenderers(
    MythCodecID myth_codec_id, const QSize &video_dim)
{
    (void) video_dim;

    QStringList list;

    if (codec_is_std(myth_codec_id) && !getenv("NO_OPENGL"))
    {
        list << "opengl" << "opengl-lite";
    }

    return list;
}
Ejemplo n.º 4
0
void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd,
                                     FilterChain *filterList,
                                     const PIPMap &pipPlayers,
                                     FrameScanType scan)
{
    QMutexLocker locker(&gl_context_lock);
    if (!gl_context)
        return;

    bool sw_frame = codec_is_std(video_codec_id) && video_codec_id != kCodec_NONE;
    bool deint_proc = m_deinterlacing && (m_deintFilter != NULL);
    OpenGLLocker ctx_lock(gl_context);

    bool pauseframe = false;
    if (!frame)
    {
        frame = vbuffers.GetScratchFrame();
        CopyFrame(vbuffers.GetScratchFrame(), &av_pause_frame);
        pauseframe = true;
    }

    if (filterList && sw_frame)
        filterList->ProcessFrame(frame);

    bool safepauseframe = pauseframe && !IsBobDeint();
    if (sw_frame && deint_proc && m_deinterlaceBeforeOSD &&
       (!pauseframe || safepauseframe))
    {
        m_deintFilter->ProcessFrame(frame, scan);
    }

    if (!window.IsEmbedding())
    {
        gl_pipchain_active = NULL;
        ShowPIPs(frame, pipPlayers);
    }

    if (sw_frame && (!pauseframe || safepauseframe) &&
        deint_proc && !m_deinterlaceBeforeOSD)
    {
        m_deintFilter->ProcessFrame(frame, scan);
    }

    if (gl_videochain && sw_frame)
    {
        bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint");
        gl_videochain->UpdateInputFrame(frame, soft_bob);
    }
}
Ejemplo n.º 5
0
bool VideoOutputOpenGL::SetupOpenGL(void)
{
    if (!gl_context)
        return false;

    const QRect dvr = window.GetDisplayVisibleRect();

    if (video_codec_id == kCodec_NONE)
    {
        gl_context->SetViewPort(QRect(QPoint(),dvr.size()));
        return true;
    }

    if (window.GetPIPState() >= kPIPStandAlone)
    {
        QRect tmprect = QRect(QPoint(0,0), dvr.size());
        ResizeDisplayWindow(tmprect, true);
    }
    bool success = false;
    OpenGLLocker ctx_lock(gl_context);
    gl_videochain = new OpenGLVideo();
    QString options = GetFilters();
    if (gl_opengl_lite)
        options += " preferycbcr";
    success = gl_videochain->Init(gl_context, &videoColourSpace,
                                  window.GetVideoDim(),
                                  window.GetVideoDispDim(), dvr,
                                  window.GetDisplayVideoRect(),
                                  window.GetVideoRect(), true,
                                  options, !codec_is_std(video_codec_id));
    if (success)
    {
        bool temp_deinterlacing = m_deinterlacing;
        if (!m_deintfiltername.isEmpty() &&
            !m_deintfiltername.contains("opengl"))
        {
            gl_videochain->SetSoftwareDeinterlacer(m_deintfiltername);
        }
        SetDeinterlacingEnabled(true);
        if (!temp_deinterlacing)
        {
            SetDeinterlacingEnabled(false);
        }
    }

    return success;
}
Ejemplo n.º 6
0
void VideoOutputOpenGLVAAPI::UpdatePauseFrame(int64_t &disp_timecode)
{
    if (codec_is_std(video_codec_id))
    {
        VideoOutputOpenGL::UpdatePauseFrame(disp_timecode);
        return;
    }

    vbuffers.begin_lock(kVideoBuffer_used);
    if (vbuffers.size(kVideoBuffer_used))
    {
        VideoFrame *frame = vbuffers.head(kVideoBuffer_used);
        m_pauseBuffer = frame->buf;
        disp_timecode = frame->disp_timecode;
    }
    else
        LOG(VB_PLAYBACK, LOG_WARNING, LOC +
            "Could not update pause frame - no used frames.");

    vbuffers.end_lock();
}
Ejemplo n.º 7
0
bool VideoOutputVDPAU::CreateVideoSurfaces(uint num)
{
    if (!m_render || num < 1)
        return false;

    bool ret = true;
    const QSize size = codec_is_std(video_codec_id) ?
                       window.GetVideoDim() : window.GetActualVideoDim();
    for (uint i = 0; i < num; i++)
    {
        uint tmp = m_render->CreateVideoSurface(size);
        if (tmp)
        {
            m_video_surfaces.push_back(tmp);
            m_render->ClearVideoSurface(tmp);
        }
        else
        {
            ret = false;
            break;
        }
    }
    return ret;
}
Ejemplo n.º 8
0
bool VideoOutputVDPAU::InitBuffers(void)
{
    QMutexLocker locker(&m_lock);
    if (!m_render)
        return false;

    uint buffer_size = m_decoder_buffer_size + m_process_buffer_size;
    const QSize video_dim = codec_is_std(video_codec_id) ?
                            window.GetVideoDim() : window.GetActualVideoDim();

    vbuffers.Init(buffer_size, false, 2, 1, 4, 1);

    bool ok = false;
    if (codec_is_vdpau(video_codec_id))
    {
        ok = CreateVideoSurfaces(buffer_size);
        if (ok)
        {
            for (int i = 0; i < m_video_surfaces.size(); i++)
                ok &= vbuffers.CreateBuffer(video_dim.width(),
                                    video_dim.height(), i,
                                    m_render->GetRender(m_video_surfaces[i]),
                                    FMT_VDPAU);
        }
    }
    else if (codec_is_std(video_codec_id))
    {
        ok = CreateVideoSurfaces(NUM_REFERENCE_FRAMES);
        if (ok)
            ok = vbuffers.CreateBuffers(FMT_YV12,
                                        video_dim.width(), video_dim.height());
    }

    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create VDPAU buffers");
    }
    else
    {
        m_video_mixer = m_render->CreateVideoMixer(video_dim, 2,
                                                   m_mixer_features);
        ok = m_video_mixer;
        m_pause_surface = m_video_surfaces[0];

        if (ok && (m_mixer_features & kVDPFeatSharpness))
            m_render->SetMixerAttribute(m_video_mixer,
                                        kVDPAttribSharpness,
                                        m_sharpen);
        if (ok && (m_mixer_features & kVDPFeatDenoise))
            m_render->SetMixerAttribute(m_video_mixer,
                                        kVDPAttribNoiseReduction,
                                        m_denoise);
        if (ok && m_skip_chroma)
            m_render->SetMixerAttribute(m_video_mixer,
                                        kVDPAttribSkipChroma, 1);

        if (ok && (db_letterbox_colour == kLetterBoxColour_Gray25))
            m_render->SetMixerAttribute(m_video_mixer,
                                        kVDPAttribBackground, 0x7F7F7FFF);
    }

    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create VDPAU mixer");
        DeleteBuffers();
    }

    return ok;
}
Ejemplo n.º 9
0
bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf,
                                     const QSize &video_dim_disp,
                                     float        aspect,
                                     MythCodecID  av_codec_id,
                                     void        */*codec_private*/,
                                     bool        &aspect_only)
{
    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
            .arg(video_dim_disp.width()).arg(video_dim_disp.height())
            .arg(aspect)
            .arg(toString(video_codec_id)).arg(toString(av_codec_id)));

    QMutexLocker locker(&gl_context_lock);

    // Ensure we don't lose embedding through program changes. This duplicates
    // code in VideoOutput::Init but we need start here otherwise the embedding
    // is lost during window re-initialistion.
    bool wasembedding = window.IsEmbedding();
    QRect oldrect;
    if (wasembedding)
    {
        oldrect = window.GetEmbeddingRect();
        StopEmbedding();
    }

    if (!codec_is_std(av_codec_id)
        && !codec_is_mediacodec(av_codec_id)
        && !codec_is_vaapi2(av_codec_id))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported.");
        errorState = kError_Unknown;
        return false;
    }

    bool cid_changed = (video_codec_id != av_codec_id);
    bool res_changed = video_dim_disp != window.GetActualVideoDim();
    bool asp_changed = aspect      != window.GetVideoAspect();

    if (!res_changed && !cid_changed)
    {
        if (asp_changed)
        {
            aspect_only = true;
            VideoAspectRatioChanged(aspect);
            MoveResize();
        }
        if (wasembedding)
            EmbedInWidget(oldrect);
        return true;
    }

    if (gCoreContext->IsUIThread())
        TearDown();
    else
        DestroyCPUResources();

    QRect disp = window.GetDisplayVisibleRect();
    if (Init(video_dim_buf, video_dim_disp,
             aspect, gl_parent_win, disp, av_codec_id))
    {
        if (wasembedding)
            EmbedInWidget(oldrect);
        if (gCoreContext->IsUIThread())
            BestDeint();
        return true;
    }

    LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
    errorState = kError_Unknown;

    return false;
}
Ejemplo n.º 10
0
void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd,
                                     FilterChain *filterList,
                                     const PIPMap &pipPlayers,
                                     FrameScanType scan)
{
    QMutexLocker locker(&gl_context_lock);

    if (!gl_context)
        return;

    if (!gl_valid)
    {
        if (!gCoreContext->IsUIThread())
        {
            LOG(VB_GENERAL, LOG_ERR, LOC +
                "ProcessFrame called from wrong thread");
        }
        QSize size = window.GetActualVideoDim();
        InitDisplayMeasurements(size.width(), size.height(), false);
        DestroyVideoResources();
        CreateVideoResources();
        BestDeint();
        gl_valid = true;
    }

    bool sw_frame = codec_is_std(video_codec_id) &&
                    video_codec_id != kCodec_NONE;
    bool deint_proc = m_deinterlacing && (m_deintFilter != NULL);
    OpenGLLocker ctx_lock(gl_context);

    bool pauseframe = false;
    if (!frame)
    {
        frame = vbuffers.GetScratchFrame();
        CopyFrame(vbuffers.GetScratchFrame(), &av_pause_frame);
        pauseframe = true;
    }

    if (sw_frame)
    {
        CropToDisplay(frame);
    }

    bool dummy = frame->dummy;
    if (filterList && sw_frame && !dummy)
        filterList->ProcessFrame(frame);

    bool safepauseframe = pauseframe && !IsBobDeint();
    if (sw_frame && deint_proc && m_deinterlaceBeforeOSD &&
       (!pauseframe || safepauseframe) && !dummy)
    {
        m_deintFilter->ProcessFrame(frame, scan);
    }

    if (!window.IsEmbedding())
    {
        gl_pipchain_active = NULL;
        ShowPIPs(frame, pipPlayers);
    }

    if (sw_frame && (!pauseframe || safepauseframe) &&
        deint_proc && !m_deinterlaceBeforeOSD && !dummy)
    {
        m_deintFilter->ProcessFrame(frame, scan);
    }

    if (gl_videochain && sw_frame && !dummy)
    {
        bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint");
        gl_videochain->UpdateInputFrame(frame, soft_bob);
    }
}
Ejemplo n.º 11
0
bool VideoOutputOpenGL::InputChanged(const QSize &input_size,
                                     float        aspect,
                                     MythCodecID  av_codec_id,
                                     void        *codec_private,
                                     bool        &aspect_only)
{
    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
            .arg(toString(video_codec_id)).arg(toString(av_codec_id)));

    QMutexLocker locker(&gl_context_lock);

    // Ensure we don't lose embedding through program changes. This duplicates
    // code in VideoOutput::Init but we need start here otherwise the embedding
    // is lost during window re-initialistion.
    bool wasembedding = window.IsEmbedding();
    QRect oldrect;
    if (wasembedding)
    {
        oldrect = window.GetEmbeddingRect();
        StopEmbedding();
    }

    if (!codec_is_std(av_codec_id))
    {
        VERBOSE(VB_IMPORTANT, LOC_ERR +
            QString("New video codec is not supported."));
        errorState = kError_Unknown;
        return false;
    }

    if (input_size == window.GetActualVideoDim())
    {
        aspect_only = video_codec_id == av_codec_id;
        if (window.GetVideoAspect() != aspect)
        {
            VideoAspectRatioChanged(aspect);
            MoveResize();
            if (wasembedding)
                EmbedInWidget(oldrect);
        }
        return true;
    }

    TearDown();
    QRect disp = window.GetDisplayVisibleRect();
    if (Init(input_size.width(), input_size.height(),
             aspect, gl_parent_win, disp, av_codec_id))
    {
        if (wasembedding)
            EmbedInWidget(oldrect);
        BestDeint();
        return true;
    }

    VERBOSE(VB_IMPORTANT, LOC_ERR +
        QString("Failed to re-initialise video output."));
    errorState = kError_Unknown;

    return false;
}