Intel-Media-SDK / MediaSDK

The Intel® Media SDK
MIT License
927 stars 457 forks source link

Want two output from vpp for Sample_decode test #2813

Open APrashant opened 2 years ago

APrashant commented 2 years ago

Hi,

I am able to run Sample_decode code and getting proper output on display. Now i want to modify it to get 2 output from VPP and need to give 1 output to Display and another to Encoder.

Please help me to identify APIs through which i can achieve my requirement.

Regards, Prashant

dmitryermilov commented 2 years ago

You can rely on this commit which shows example of decode->two VPPs: https://github.com/dmitryermilov/MediaSDK/commit/d5430f799e28ad1862fb4ff15acb605d5596d952

You need to add encoder after 2nd VPP:

APrashant commented 2 years ago

Thank you dmitry for prompt response.

APrashant commented 2 years ago

Hi,

By referring this https://github.com/dmitryermilov/MediaSDK/commit/d5430f799e28ad1862fb4ff15acb605d5596d952 I have created one more VPP with new session id.

Aim is to create one more vpp pipeline with same decoder output ie., current pipeline - file -- decoder -- vpp1 -- display second vpp pipeline ''(same decoder)" -- vpp2 -- encoder -- file dump

so I have created new VPP with vpp parameters and tried to allocate surface memory with generalAllocator - it fails (getting segmentation fault) the same tried with mfxFrameAllocator - that also fails

Code: of AllocFrames function

mfxStatus CDecodingPipeline::AllocFrames() { MSDK_CHECK_POINTER(m_pmfxDEC, MFX_ERR_NULL_PTR);

mfxStatus sts = MFX_ERR_NONE;

mfxFrameAllocRequest Request;
mfxFrameAllocRequest VppRequest[2];
mfxFrameAllocRequest VppRequest1[2];

mfxU16 nSurfNum = 0; // number of surfaces for decoder
mfxU16 nVppSurfNum = 0; // number of surfaces for vpp
mfxU16 nVppSurfNum1 = 0;

MSDK_ZERO_MEMORY(Request);

MSDK_ZERO_MEMORY(VppRequest[0]);
MSDK_ZERO_MEMORY(VppRequest[1]);

MSDK_ZERO_MEMORY(VppRequest1[0]);
MSDK_ZERO_MEMORY(VppRequest1[1]);

sts = m_pmfxDEC->Query(&m_mfxVideoParams, &m_mfxVideoParams);
MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
MSDK_CHECK_STATUS(sts, "m_pmfxDEC->Query failed");

// calculate number of surfaces required for decoder
sts = m_pmfxDEC->QueryIOSurf(&m_mfxVideoParams, &Request);
if (MFX_WRN_PARTIAL_ACCELERATION == sts)
{
    msdk_printf(MSDK_STRING("WARNING: partial acceleration\n"));
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
    m_bDecOutSysmem = true;
}
MSDK_CHECK_STATUS(sts, "m_pmfxDEC->QueryIOSurf failed");

if (m_eWorkMode == MODE_RENDERING)
{
    // Add surfaces for rendering smoothness
    Request.NumFrameSuggested += m_nMaxFps / 3;
}

if (m_bVppIsUsed)
{
    // respecify memory type between Decoder and VPP
    m_mfxVideoParams.IOPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;

    // recalculate number of surfaces required for decoder
    sts = m_pmfxDEC->QueryIOSurf(&m_mfxVideoParams, &Request);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
    MSDK_CHECK_STATUS(sts, "m_pmfxDEC->QueryIOSurf failed");

    sts = InitVppParams();
    MSDK_CHECK_STATUS(sts, "InitVppParams failed");

    sts = m_pmfxVPP->Query(&m_mfxVppVideoParams, &m_mfxVppVideoParams);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
    MSDK_CHECK_STATUS(sts, "m_pmfxVPP->Query failed");

    sts = InitVppParams();
    MSDK_CHECK_STATUS(sts, "InitVppParams failed");

    sts = m_pmfxVPP->Query(&m_mfxVppVideoParams, &m_mfxVppVideoParams);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
    MSDK_CHECK_STATUS(sts, "m_pmfxVPP->Query failed");

    sts = m_pmfxVPP1->Query(&m_mfxVppVideoParams1, &m_mfxVppVideoParams1);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
    MSDK_CHECK_STATUS(sts, "m_pmfxVPP->Query failed");

    // VppRequest[0] for input frames request, VppRequest[1] for output frames request
    sts = m_pmfxVPP->QueryIOSurf(&m_mfxVppVideoParams, VppRequest);
    if (MFX_WRN_PARTIAL_ACCELERATION == sts) {
        msdk_printf(MSDK_STRING("WARNING: partial acceleration\n"));
        MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
    }
    MSDK_CHECK_STATUS(sts, "m_pmfxVPP->QueryIOSurf failed");

    sts = m_pmfxVPP1->QueryIOSurf(&m_mfxVppVideoParams1, VppRequest1);
    if (MFX_WRN_PARTIAL_ACCELERATION == sts) {
        msdk_printf(MSDK_STRING("WARNING: partial acceleration\n"));
        MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
    }
    MSDK_CHECK_STATUS(sts, "m_pmfxVPP->QueryIOSurf failed");

    if ((VppRequest[0].NumFrameSuggested < m_mfxVppVideoParams.AsyncDepth) ||
        (VppRequest[1].NumFrameSuggested < m_mfxVppVideoParams.AsyncDepth))
        return MFX_ERR_MEMORY_ALLOC;

    if ((VppRequest1[0].NumFrameSuggested < m_mfxVppVideoParams1.AsyncDepth) ||
        (VppRequest1[1].NumFrameSuggested < m_mfxVppVideoParams1.AsyncDepth))
        return MFX_ERR_MEMORY_ALLOC;

/doubt/ // If surfaces are shared by 2 components, c1 and c2. NumSurf = c1_out + c2_in - AsyncDepth + 1 // The number of surfaces shared by vpp input and decode output nSurfNum = Request.NumFrameSuggested + VppRequest[0].NumFrameSuggested - m_mfxVideoParams.AsyncDepth + 1;

    // The number of surfaces for vpp output.
    // Need to add one more surface in render mode if AsyncDepth == 1
    nVppSurfNum = VppRequest[1].NumFrameSuggested +
                  (m_eWorkMode == MODE_RENDERING ? m_mfxVideoParams.AsyncDepth == 1 : 0);

    nVppSurfNum1 = VppRequest1[1].NumFrameSuggested + 0; // since vpp1 is not for rendering
                  //(m_eWorkMode == MODE_RENDERING ? m_mfxVideoParams.AsyncDepth == 1 : 0);

    // prepare allocation request
    Request.NumFrameSuggested = Request.NumFrameMin = nSurfNum;

    // surfaces are shared between vpp input and decode output
    Request.Type |= MFX_MEMTYPE_EXTERNAL_FRAME | MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_VPPIN;
}

if ((Request.NumFrameSuggested < m_mfxVideoParams.AsyncDepth) &&
    (m_impl & MFX_IMPL_HARDWARE_ANY))
    return MFX_ERR_MEMORY_ALLOC;

Request.Type |= (m_bDecOutSysmem) ?
    MFX_MEMTYPE_SYSTEM_MEMORY
    : MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;

ifdef LIBVA_SUPPORT

if (!m_bVppIsUsed &&
    (m_export_mode != vaapiAllocatorParams::DONOT_EXPORT))
{
    Request.Type |= MFX_MEMTYPE_EXPORT_FRAME;
}

endif

// alloc frames for decoder
sts = m_pGeneralAllocator->Alloc(m_pGeneralAllocator->pthis, &Request, &m_mfxResponse);
MSDK_CHECK_STATUS(sts, "m_pGeneralAllocator->Alloc failed");

if (m_bVppIsUsed)
{
    // alloc frames for VPP

ifdef LIBVA_SUPPORT

    if (m_export_mode != vaapiAllocatorParams::DONOT_EXPORT)
    {
        VppRequest[1].Type |= MFX_MEMTYPE_EXPORT_FRAME;
        VppRequest1[1].Type |= MFX_MEMTYPE_EXPORT_FRAME;
    }

endif

    VppRequest[1].NumFrameSuggested = VppRequest[1].NumFrameMin = nVppSurfNum;
    VppRequest1[1].NumFrameSuggested = VppRequest1[1].NumFrameMin = nVppSurfNum1;
    MSDK_MEMCPY_VAR(VppRequest[1].Info, &(m_mfxVppVideoParams.vpp.Out), sizeof(mfxFrameInfo));
    MSDK_MEMCPY_VAR(VppRequest1[1].Info, &(m_mfxVppVideoParams1.vpp.Out), sizeof(mfxFrameInfo));

    sts = m_pGeneralAllocator->Alloc(m_pGeneralAllocator->pthis, &VppRequest[1], &m_mfxVppResponse);
    MSDK_CHECK_STATUS(sts, "m_pGeneralAllocator->Alloc failed");

    **sts = m_pMFXAllocator->Alloc(m_pMFXAllocator->pthis, &VppRequest1[1], &m_mfxVppResponse1);
    MSDK_CHECK_STATUS(sts, "m_pGeneralAllocator1->Alloc failed");**    ------- fails here with segmentation fault error

    // prepare mfxFrameSurface1 array for decoder
    nVppSurfNum = m_mfxVppResponse.NumFrameActual;
    nVppSurfNum1 = m_mfxVppResponse1.NumFrameActual;
    // AllocVppBuffers should call before AllocBuffers to set the value of m_OutputSurfacesNumber
    sts = AllocVppBuffers(nVppSurfNum);
    MSDK_CHECK_STATUS(sts, "AllocVppBuffers failed");
    sts = AllocVppBuffers(nVppSurfNum1);
    MSDK_CHECK_STATUS(sts, "AllocVppBuffers1 failed");
}

Error Iam getting CreateHWDevice : CreatingVAAPIDevice__ libva info: VA-API version 1.13.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so libva info: Found init function vaDriverInit_1_13 libva info: va_openDriver() returns 0 drmrender: trying connection: DisplayPort drmrender: selected crtc already attached to connector drmrender: succeeded... drmrender: connected via DisplayPort to 1920x1080@60 capable display CreateHWDevice : Done CreatingVAAPIDevice__ CreateHWDevice : CreatingVaapi device for second pipeline libva info: VA-API version 1.13.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so libva info: Found init function vaDriverInit_1_13 libva info: va_openDriver() returns 0 pretending that stream is 30fps one pretending that aspect ratio is 1:1 Segmentation fault (core dumped)

Can you suggest what may be reason for this memory allocation issue and also can you explain the difference between generalAllocator and mfxFrameAllocator. (In sample_decode sample only they used generalAllocator and in encoder and other samples they have used mfxFrameAllocator)

Thanks in advance.

KalaipriyaRajesh commented 2 years ago

Hi @dmitryermilov

Could you please help out on this issue. If any update can you please write it.

Thanks