// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include #include #include "videoEncoder.hpp" #include "amfIncludes.hpp" extern "C" { #if defined(_WIN32) #include "x264.h" #include #else #include #include #include #define INFINITE 0xFFFFFFFF #endif } #include "mfxvideo++.h" #define MFX_IMPL_VIA_MASK(x) (0x0f00 & (x)) #define MSDK_ALIGN16(value) (((value + 15) >> 4) << 4) // round up to a multiple of 16 #define MSDK_ALIGN32(value) (((value + 31) >> 5) << 5) // round up to a multiple of 32 #if defined(WIN32) || defined(WIN64) #define D3D_SURFACES_SUPPORT 1 #else #define LIBVA_SUPPORT 1 #define LIBVA_X11_SUPPORT 1 #endif #if defined(_WIN32) && !defined(MFX_D3D11_SUPPORT) #include #if (NTDDI_VERSION >= NTDDI_VERSION_FROM_WIN32_WINNT2(0x0602)) // >= _WIN32_WINNT_WIN8 #define MFX_D3D11_SUPPORT 1 // Enable D3D11 support if SDK allows #else #define MFX_D3D11_SUPPORT 0 #endif #endif // #if defined(WIN32) || defined(WIN64) #if D3D_SURFACES_SUPPORT #include "d3dAllocator.hpp" #include "d3d11Allocator.hpp" #include "d3dDevice.hpp" #include "d3d11Device.hpp" #endif #ifdef LIBVA_SUPPORT #include "vaapiAllocator.hpp" #include "vaapiDevice.hpp" #endif #include "sysMemAllocator.hpp" namespace VideoStitch { namespace Output { enum MemType { SYSTEM_MEMORY = 0x00, D3D9_MEMORY = 0x01, D3D11_MEMORY = 0x02, }; class QSVEncoder : public VideoEncoder { public: QSVEncoder() : session(nullptr), encoder(nullptr), hwdev(nullptr), allocator(nullptr), allocatorParams(nullptr), memType(SYSTEM_MEMORY), externalAlloc(false), encSurfaces(nullptr), bitRate(0) {} ~QSVEncoder() { // release all surfaces delete session; } static Potential createQSVEncoder(const Ptv::Value& config, int width, int height, FrameRate framerate); static void supportedEncoders(std::vector& codecs); mfxStatus init(int width, int height, FrameRate framerate, mfxU16 profile, mfxU16 level, int bitRate, mfxU16 targetUsage, mfxU16 rateControlMethod, mfxU16 numSlice, int gop, MemType memType); bool encode(const Frame& videoFrame, std::vector& packets) override; int getBitRate() const override { return bitRate; } bool setBitRate(uint32_t /*maxBitrate*/, uint32_t /*bufferSize*/) { return false; } bool dynamicBitrateSupported() const override { return false; } char* metadata(char* enc, char* pend) override; private: static const AVal av_videocodecid; static const AVal av_videodatarate; static const AVal av_framerate; static const std::unordered_map profileMap; static const std::unordered_set levelSet; static const std::unordered_map rcmodeMap; static const std::unordered_map memMap; static mfxStatus initSession(MFXVideoSession* session, const MemType memType); static mfxU16 profileParser(std::string profile); static mfxU16 levelParser(std::string level); static mfxU16 rcmodeParser(std::string rcmode); static MemType memTypeParser(std::string memtype); mfxU16 getFreeSurface(mfxFrameSurface1* surfacesPool, mfxU16 poolSize); mfxU16 getFreeSurfaceIndex(mfxFrameSurface1* surfacesPool, mfxU16 poolSize); void initEncoderParams(int width, int height, FrameRate framerate, mfxU16 profile, mfxU16 level, int bitRate, mfxU16 targetUsage, mfxU16 rateControlMethod, mfxU16 numSlice, int gop); mfxStatus createHWDevice(); mfxStatus resetDevice(); void deleteHWDevice() { delete hwdev; } mfxStatus createAllocator(); void deleteAllocator(); mfxStatus allocFrames(); void deleteFrames(); // -------------------------------- MFXVideoSession* session; MFXVideoENCODE* encoder; mfxVideoParam params; CHWDevice* hwdev; MFXFrameAllocator* allocator; mfxAllocatorParams* allocatorParams; MemType memType; bool externalAlloc; // use memory allocator as external for Media SDK mfxFrameSurface1* encSurfaces; // frames array for encoder input mfxFrameAllocRequest req; mfxFrameAllocResponse resp; mfxBitstream bits; int bitRate; FrameRate framerate; }; } // namespace Output } // namespace VideoStitch