Пример #1
0
mfxStatus CQuickSyncDecoder::InitFrameAllocator(mfxVideoParam* pVideoParams, mfxU32 nPitch)
{
    MSDK_TRACE("QsDecoder: InitFrameAllocator\n");
    // Already initialized
    if (m_pFrameSurfaces)
    {
        return MFX_ERR_NONE;
    }

    MSDK_CHECK_POINTER(m_pmfxDEC, MFX_ERR_NOT_INITIALIZED);
    mfxStatus sts = MFX_ERR_NONE;

    // Initialize frame allocator (if needed)
    sts = CreateAllocator();
    MSDK_CHECK_NOT_EQUAL(sts, MFX_ERR_NONE, sts);

    // Find how many surfaces are needed
    mfxFrameAllocRequest allocRequest;
    MSDK_ZERO_VAR(allocRequest);
    sts = m_pmfxDEC->QueryIOSurf(pVideoParams, &allocRequest);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
    MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
    MSDK_CHECK_RESULT_P_RET(sts, MFX_ERR_NONE);
    allocRequest.NumFrameSuggested = (mfxU16)m_nAuxFrameCount + allocRequest.NumFrameSuggested;
    allocRequest.NumFrameMin = allocRequest.NumFrameSuggested;

    // Decide memory type
    allocRequest.Type = MFX_MEMTYPE_EXTERNAL_FRAME | MFX_MEMTYPE_FROM_DECODE;
    allocRequest.Type |= (m_bUseD3DAlloc) ?
       MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET : MFX_MEMTYPE_SYSTEM_MEMORY;

    memcpy(&allocRequest.Info, &pVideoParams->mfx.FrameInfo, sizeof(mfxFrameInfo));

    // Allocate frames with H aligned at 32 for both progressive and interlaced content
    allocRequest.Info.Height = MSDK_ALIGN32(allocRequest.Info.Height); 
    allocRequest.Info.Width = (mfxU16)nPitch;

    // Perform allocation call. result is saved in m_AllocResponse
    sts = m_pFrameAllocator->Alloc(m_pFrameAllocator->pthis, &allocRequest, &m_AllocResponse);
    MSDK_CHECK_RESULT_P_RET(sts, MFX_ERR_NONE);

    m_nRequiredFramesNum = m_AllocResponse.NumFrameActual;
    ASSERT(m_nRequiredFramesNum == allocRequest.NumFrameSuggested);
    m_pFrameSurfaces = new mfxFrameSurface1[m_nRequiredFramesNum];
    MSDK_CHECK_POINTER(m_pFrameSurfaces, MFX_ERR_MEMORY_ALLOC);
    MSDK_ZERO_MEMORY(m_pFrameSurfaces, sizeof(mfxFrameSurface1) * m_nRequiredFramesNum);

    // Allocate decoder work & output surfaces
    for (mfxU32 i = 0; i < m_nRequiredFramesNum; ++i)
    {
        // Copy frame info
        memcpy(&(m_pFrameSurfaces[i].Info), &pVideoParams->mfx.FrameInfo, sizeof(mfxFrameInfo));

        // Save pointer to allocator specific surface object (mid)
        m_pFrameSurfaces[i].Data.MemId  = m_AllocResponse.mids[i];
        m_pFrameSurfaces[i].Data.Pitch  = (mfxU16)nPitch;
    }

    return sts;
}
Пример #2
0
mfxStatus GeneralAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
{
    mfxStatus sts;
    if ((request->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET || request->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) && m_D3DAllocator.get())
    {
        sts = m_D3DAllocator.get()->Alloc(m_D3DAllocator.get(), request, response);
        MSDK_CHECK_NOT_EQUAL(MFX_ERR_NONE, sts, sts);
        StoreFrameMids(true, response);
    }
    else
    {
        sts = m_SYSAllocator.get()->Alloc(m_SYSAllocator.get(), request, response);
        MSDK_CHECK_NOT_EQUAL(MFX_ERR_NONE, sts, sts);
        StoreFrameMids(false, response);
    }
    return sts;
}
Пример #3
0
mfxStatus D3D11FrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
{
    HRESULT hRes;
    DXGI_FORMAT colorFormat = ConverColortFormat(request->Info.FourCC);

    // Only support NV12
    MSDK_CHECK_NOT_EQUAL(colorFormat, DXGI_FORMAT_NV12, MFX_ERR_UNSUPPORTED);

    TextureResource newTexture;

    D3D11_TEXTURE2D_DESC desc = {0};

    desc.Width  = request->Info.Width;
    desc.Height = request->Info.Height;

    desc.MipLevels = 1;
    //number of subresources is 1 in case of not single texture
    desc.ArraySize = m_initParams.bUseSingleTexture ? request->NumFrameSuggested : 1;
    desc.Format = ConverColortFormat(request->Info.FourCC);
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.MiscFlags = m_initParams.uncompressedResourceMiscFlags;
    desc.BindFlags = D3D11_BIND_DECODER;

    if ( (MFX_MEMTYPE_FROM_VPPIN & request->Type) && (DXGI_FORMAT_YUY2 == desc.Format) || 
        (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) )
    {
        desc.BindFlags = D3D11_BIND_RENDER_TARGET;
        if (desc.ArraySize > 2)
            return MFX_ERR_MEMORY_ALLOC;
    }

    if ( (MFX_MEMTYPE_FROM_VPPOUT & request->Type) ||
        (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & request->Type))
    {
        desc.BindFlags = D3D11_BIND_RENDER_TARGET;
        if (desc.ArraySize > 2)
            return MFX_ERR_MEMORY_ALLOC;       
    }

    if ( DXGI_FORMAT_P8 == desc.Format )
    {
        desc.BindFlags = 0;
    }

    ID3D11Texture2D* pTexture2D;

    for (size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; ++i)
    {
        hRes = m_initParams.pDevice->CreateTexture2D(&desc, NULL, &pTexture2D);

        if (FAILED(hRes))
        {
            MSDK_TRACE("CreateTexture2D(%d) failed, hr = 0x%lX\n", (int)i, hRes);
            return MFX_ERR_MEMORY_ALLOC;
        }
        newTexture.textures.push_back(pTexture2D);
    }

    desc.ArraySize = 1;
    desc.Usage = D3D11_USAGE_STAGING;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    desc.BindFlags = 0;
    desc.MiscFlags = 0;

    for (size_t i = 0; i < request->NumFrameSuggested; ++i)
    {
        hRes = m_initParams.pDevice->CreateTexture2D(&desc, NULL, &pTexture2D);

        if (FAILED(hRes))
        {        
            MSDK_TRACE("Create staging texture(%d) failed hr = 0x%lX\n", (int)i, hRes);
            return MFX_ERR_MEMORY_ALLOC;
        }
        newTexture.stagingTexture.push_back(pTexture2D);
    }
    
    // mapping to self created handles array, starting from zero or from last assigned handle + 1
    sequence<mfxHDL> seq_initializer(m_resourcesByRequest.empty() ? 0 :  m_resourcesByRequest.back().outerMids.back());

    //incrementing starting index
    //1. 0(NULL) is invalid memid
    //2. back is last index not new one
    seq_initializer();
    
    std::generate_n(std::back_inserter(newTexture.outerMids), request->NumFrameSuggested, seq_initializer);

    //saving texture resources
    m_resourcesByRequest.push_back(newTexture);

    //providing pointer to mids externally
    response->mids = &m_resourcesByRequest.back().outerMids.front();
    response->NumFrameActual = request->NumFrameSuggested;
    
    //iterator prior end()
    auto it_last = m_resourcesByRequest.end();
    //fill map
    std::fill_n(std::back_inserter(m_memIdMap), request->NumFrameSuggested, --it_last);

    return MFX_ERR_NONE;
}
Пример #4
0
mfxStatus D3D11FrameAllocator::LockFrame(mfxMemId mid, mfxFrameData *ptr)
{
    HRESULT hRes = S_OK;

    D3D11_TEXTURE2D_DESC desc = {0};
    D3D11_MAPPED_SUBRESOURCE lockedRect = {0};

    //check that texture exists
    TextureSubResource sr = GetResourceFromMid(mid);
    if (!sr.GetTexture())
        return MFX_ERR_LOCK_MEMORY;

    D3D11_MAP mapType = D3D11_MAP_READ;
    UINT mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
    {
        ASSERT(NULL != sr.GetStaging());
        sr.GetTexture()->GetDesc(&desc);

        if (DXGI_FORMAT_NV12 != desc.Format)
        {
            return MFX_ERR_LOCK_MEMORY;
        }

#ifdef D3D11_PARALLEL_COPY  
        // copy original frame to staging frame - CPU can't access original frame
        // parallel copy is a little faster
        D3D11_BOX box;
        MSDK_ZERO_VAR(box);
        D3D11_TEXTURE2D_DESC desc;
        sr.GetTexture()->GetDesc(&desc);
        box.right = desc.Width;
        box.bottom = desc.Height;

        int count = 2;
        ID3D11DeviceContext* pDeviceContext = m_pDeviceContext;
        Concurrency::parallel_for(0, count+1, [pDeviceContext, &sr, &box, count](int i)
        {
            int block = MSDK_ALIGN16(box.bottom / count);
            D3D11_BOX tmp_box = box;
            tmp_box.top    = i * block;
            tmp_box.bottom = (i == count) ? box.bottom : tmp_box.top + block;
            pDeviceContext->CopySubresourceRegion(sr.GetStaging(), 0, tmp_box.left, tmp_box.top, 0, sr.GetTexture(), sr.GetSubResource(), &tmp_box); 
        });
#else
        // Single threaded copy
        m_pDeviceContext->CopySubresourceRegion(sr.GetStaging(), 0, 0, 0, 0, sr.GetTexture(), sr.GetSubResource(), NULL); 
#endif
        do
        {
            hRes = m_pDeviceContext->Map(sr.GetStaging(), 0, mapType, mapFlags, &lockedRect);
            if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes)
            {
                MSDK_TRACE("ERROR: m_pDeviceContext->Map = 0x%lX\n", hRes);
            }
        }
        while (DXGI_ERROR_WAS_STILL_DRAWING == hRes);
    }

    if (FAILED(hRes))
        return MFX_ERR_LOCK_MEMORY;

    MSDK_CHECK_NOT_EQUAL(desc.Format, DXGI_FORMAT_NV12, MFX_ERR_LOCK_MEMORY);
    ptr->Pitch = (mfxU16)lockedRect.RowPitch;
    ptr->Y = (mfxU8 *)lockedRect.pData;
    ptr->U = (mfxU8 *)lockedRect.pData + desc.Height * lockedRect.RowPitch;
    ptr->V = ptr->U + 1;

    return MFX_ERR_NONE;
}
mfxStatus Rotate::Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task)
{
    MSDK_CHECK_POINTER(in, MFX_ERR_NULL_PTR);
    MSDK_CHECK_POINTER(out, MFX_ERR_NULL_PTR);
    MSDK_CHECK_POINTER(*in, MFX_ERR_NULL_PTR);
    MSDK_CHECK_POINTER(*out, MFX_ERR_NULL_PTR);
    MSDK_CHECK_POINTER(task, MFX_ERR_NULL_PTR);
    MSDK_CHECK_NOT_EQUAL(in_num, 1, MFX_ERR_UNSUPPORTED);
    MSDK_CHECK_NOT_EQUAL(out_num, 1, MFX_ERR_UNSUPPORTED);
    MSDK_CHECK_POINTER(m_pmfxCore, MFX_ERR_NOT_INITIALIZED);
    MSDK_CHECK_ERROR(m_bInited, false, MFX_ERR_NOT_INITIALIZED);

    mfxFrameSurface1 *surface_in = (mfxFrameSurface1 *)in[0];
    mfxFrameSurface1 *surface_out = (mfxFrameSurface1 *)out[0];
    mfxFrameSurface1 *real_surface_in = surface_in;
    mfxFrameSurface1 *real_surface_out = surface_out;

    mfxStatus sts = MFX_ERR_NONE;

    if (m_bIsInOpaque)
    {
        sts = m_pmfxCore->GetRealSurface(m_pmfxCore->pthis, surface_in, &real_surface_in);
        MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, MFX_ERR_MEMORY_ALLOC);
    }

    if (m_bIsOutOpaque)
    {
        sts = m_pmfxCore->GetRealSurface(m_pmfxCore->pthis, surface_out, &real_surface_out);
        MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, MFX_ERR_MEMORY_ALLOC);
    }

    // check validity of parameters
    sts = CheckInOutFrameInfo(&real_surface_in->Info, &real_surface_out->Info);
    MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

    mfxU32 ind = FindFreeTaskIdx();

    if (ind >= m_MaxNumTasks)
    {
        return MFX_WRN_DEVICE_BUSY; // currently there are no free tasks available
    }

    m_pmfxCore->IncreaseReference(m_pmfxCore->pthis, &(real_surface_in->Data));
    m_pmfxCore->IncreaseReference(m_pmfxCore->pthis, &(real_surface_out->Data));

    m_pTasks[ind].In = real_surface_in;
    m_pTasks[ind].Out = real_surface_out;
    m_pTasks[ind].bBusy = true;

    switch (m_Param.Angle)
    {
    case 180:
        if (m_bOpenCLSurfaceSharing)
        {
            m_pTasks[ind].pProcessor = new OpenCLFilterRotator180(m_OpenCLFilter.get());
        }
        else
        {
            m_pTasks[ind].pProcessor = new OpenCLRotator180(m_pOpenCLRotator180Context.get());
        }
        MSDK_CHECK_POINTER(m_pTasks[ind].pProcessor, MFX_ERR_MEMORY_ALLOC);
        break;
    default:
        return MFX_ERR_UNSUPPORTED;
    }

    m_pTasks[ind].pProcessor->SetAllocator(m_pAlloc);
    m_pTasks[ind].pProcessor->Init(real_surface_in, real_surface_out);

    *task = (mfxThreadTask)&m_pTasks[ind];

    return MFX_ERR_NONE;
}
Пример #6
0
mfxStatus CQuickSyncDecoder::CreateAllocator()
{
    if (m_pFrameAllocator != NULL)
        return MFX_ERR_NONE;

    MSDK_TRACE("QsDecoder: CreateAllocator\n");

    ASSERT(m_pVideoParams != NULL);
    if (NULL == m_pVideoParams)
        return MFX_ERR_NOT_INITIALIZED;

    std::auto_ptr<mfxAllocatorParams> pParam(NULL);
    mfxStatus sts = MFX_ERR_NONE;

    // Setup allocator - HW acceleration
    if (m_bUseD3DAlloc)
    {
        m_pVideoParams->IOPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY | MFX_IOPATTERN_IN_VIDEO_MEMORY;
        int nAdapterID = GetMSDKAdapterNumber(*m_mfxVideoSession);
        // D3D11 HW device
        if (m_bUseD3D11Alloc)
        {
#if MFX_D3D11_SUPPORT
            // HW device must be initialized early - within session init.
            // If a call to DecodeHeader was called before session->SetHandle, SetHandle would fail.
            ASSERT(m_HwDevice);
            MSDK_CHECK_POINTER(m_HwDevice, MFX_ERR_NULL_PTR);

            D3D11AllocatorParams* p = new D3D11AllocatorParams;
            p->pDevice = (ID3D11Device*)m_HwDevice->GetHandle(MFX_HANDLE_D3D11_DEVICE);
            pParam.reset(p);
            m_pFrameAllocator = new D3D11FrameAllocator();
#endif
        }
        // D3D9 HW device
        else
        {
            // Having the D3D9 device manager from the renderer allows working in full screen exclusive mode
            // This parameter can be NULL for other usages
            m_HwDevice = new CD3D9Device(m_pRendererD3dDeviceManager);
            if (MSDK_FAILED(sts = m_HwDevice->Init(nAdapterID)))
            {
                MSDK_TRACE("QsDecoder: D3D9 init have failed!\n");
                MSDK_SAFE_DELETE(m_HwDevice);
                return sts;
            }

            // Set the pointer to the HW device (or device manager) to the session
            mfxHDL h = m_HwDevice->GetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER);
            sts = m_mfxVideoSession->SetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, h);
            MSDK_CHECK_NOT_EQUAL(sts, MFX_ERR_NONE, sts);

            D3DAllocatorParams* p = new D3DAllocatorParams;
            p->pManager = (IDirect3DDeviceManager9*)h;
            pParam.reset(p);
            m_pFrameAllocator = new D3DFrameAllocator();
        }
    }
    // Setup allocator - No HW acceleration
    else
    {
        m_bUseD3DAlloc = false;
        m_pVideoParams->IOPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY | MFX_IOPATTERN_IN_SYSTEM_MEMORY;
        m_pFrameAllocator = new SysMemFrameAllocator();
    }

    sts = m_pFrameAllocator->Init(pParam.get());
    if (MSDK_SUCCEEDED(sts))
    {
        // Note - setting the session allocator can be done only once per session!
        sts = m_mfxVideoSession->SetFrameAllocator(m_pFrameAllocator);
        if (MSDK_FAILED(sts))
        {
            MSDK_TRACE("QsDecoder: Session SetFrameAllocator failed!\n");    
        }
    }
    else
    // Allocator failed to initialize
    {
        MSDK_TRACE("QsDecoder: Allocator Init failed!\n");

        MSDK_SAFE_DELETE(m_pFrameAllocator);
        ASSERT(false);
    }

    return sts;
}