Path: blob/master/modules/videoio/src/cap_mfx_common.hpp
16354 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html34#ifndef MFXHELPER_H5#define MFXHELPER_H67#include "opencv2/core.hpp"89#include <iostream>10#include <fstream>11#include <sstream>1213#include <mfxcommon.h>14#include <mfxstructures.h>15#include <mfxvideo++.h>16#include <mfxvp8.h>17#include <mfxjpeg.h>18#include <mfxplugin++.h>1920// //21// Debug helpers //22// //2324#if 025# define DBG(i) i26#else27# define DBG(i)28#endif2930#if 131# define MSG(i) i32#else33# define MSG(i)34#endif3536template <typename T>37struct HexWrap {38HexWrap(T val_) : val(val_) {}39T val;40};4142template <typename T>43inline std::ostream & operator<<(std::ostream &out, const HexWrap<T> &wrap) {44std::ios_base::fmtflags flags = out.flags(std::ios::hex | std::ios::showbase);45out << wrap.val;46out.flags(flags);47return out;48}4950template <typename T>51inline ::HexWrap<T> asHex(const T & val) {52return ::HexWrap<T>(val);53}5455struct FourCC56{57FourCC(uint val) : val32(val) {}58FourCC(char a, char b, char c, char d) { val8[0] = a; val8[1] = b; val8[2] = c; val8[3] = d; }59union {60uint val32;61int vali32;62uchar val8[4];63};64};6566inline std::ostream & operator<<(std::ostream &out, FourCC cc) {67for (size_t i = 0; i < 4; out << cc.val8[i++]) {}68out << " (" << asHex(cc.val32) << ")";69return out;70}7172inline std::string mfxStatusToString(mfxStatus s) {73switch (s)74{75case MFX_ERR_NONE: return "MFX_ERR_NONE";76case MFX_ERR_UNKNOWN: return "MFX_ERR_UNKNOWN";77case MFX_ERR_NULL_PTR: return "MFX_ERR_NULL_PTR";78case MFX_ERR_UNSUPPORTED: return "MFX_ERR_UNSUPPORTED";79case MFX_ERR_MEMORY_ALLOC: return "MFX_ERR_MEMORY_ALLOC";80case MFX_ERR_NOT_ENOUGH_BUFFER: return "MFX_ERR_NOT_ENOUGH_BUFFER";81case MFX_ERR_INVALID_HANDLE: return "MFX_ERR_INVALID_HANDLE";82case MFX_ERR_LOCK_MEMORY: return "MFX_ERR_LOCK_MEMORY";83case MFX_ERR_NOT_INITIALIZED: return "MFX_ERR_NOT_INITIALIZED";84case MFX_ERR_NOT_FOUND: return "MFX_ERR_NOT_FOUND";85case MFX_ERR_MORE_DATA: return "MFX_ERR_MORE_DATA";86case MFX_ERR_MORE_SURFACE: return "MFX_ERR_MORE_SURFACE";87case MFX_ERR_ABORTED: return "MFX_ERR_ABORTED";88case MFX_ERR_DEVICE_LOST: return "MFX_ERR_DEVICE_LOST";89case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: return "MFX_ERR_INCOMPATIBLE_VIDEO_PARAM";90case MFX_ERR_INVALID_VIDEO_PARAM: return "MFX_ERR_INVALID_VIDEO_PARAM";91case MFX_ERR_UNDEFINED_BEHAVIOR: return "MFX_ERR_UNDEFINED_BEHAVIOR";92case MFX_ERR_DEVICE_FAILED: return "MFX_ERR_DEVICE_FAILED";93case MFX_ERR_MORE_BITSTREAM: return "MFX_ERR_MORE_BITSTREAM";94case MFX_ERR_INCOMPATIBLE_AUDIO_PARAM: return "MFX_ERR_INCOMPATIBLE_AUDIO_PARAM";95case MFX_ERR_INVALID_AUDIO_PARAM: return "MFX_ERR_INVALID_AUDIO_PARAM";96case MFX_ERR_GPU_HANG: return "MFX_ERR_GPU_HANG";97case MFX_ERR_REALLOC_SURFACE: return "MFX_ERR_REALLOC_SURFACE";98case MFX_WRN_IN_EXECUTION: return "MFX_WRN_IN_EXECUTION";99case MFX_WRN_DEVICE_BUSY: return "MFX_WRN_DEVICE_BUSY";100case MFX_WRN_VIDEO_PARAM_CHANGED: return "MFX_WRN_VIDEO_PARAM_CHANGED";101case MFX_WRN_PARTIAL_ACCELERATION: return "MFX_WRN_PARTIAL_ACCELERATION";102case MFX_WRN_INCOMPATIBLE_VIDEO_PARAM: return "MFX_WRN_INCOMPATIBLE_VIDEO_PARAM";103case MFX_WRN_VALUE_NOT_CHANGED: return "MFX_WRN_VALUE_NOT_CHANGED";104case MFX_WRN_OUT_OF_RANGE: return "MFX_WRN_OUT_OF_RANGE";105case MFX_WRN_FILTER_SKIPPED: return "MFX_WRN_FILTER_SKIPPED";106case MFX_WRN_INCOMPATIBLE_AUDIO_PARAM: return "MFX_WRN_INCOMPATIBLE_AUDIO_PARAM";107default: return "<Invalid mfxStatus>";108}109}110111inline std::ostream & operator<<(std::ostream &out, mfxStatus s) {112out << mfxStatusToString(s) << " (" << (int)s << ")"; return out;113}114115inline std::ostream & operator<<(std::ostream &out, const mfxInfoMFX &info) {116out << "InfoMFX:" << std::endl117<< "| Codec: " << FourCC(info.CodecId) << " / " << info.CodecProfile << " / " << info.CodecLevel << std::endl118<< "| DecodedOrder: " << info.DecodedOrder << std::endl119<< "| TimeStampCalc: " << info.TimeStampCalc << std::endl120;121return out;122}123124inline std::ostream & operator<<(std::ostream & out, const mfxFrameInfo & info) {125out << "FrameInfo: " << std::endl126<< "| FourCC: " << FourCC(info.FourCC) << std::endl127<< "| Size: " << info.Width << "x" << info.Height << std::endl128<< "| ROI: " << "(" << info.CropX << ";" << info.CropY << ") " << info.CropW << "x" << info.CropH << std::endl129<< "| BitDepth(L/C): " << info.BitDepthLuma << " / " << info.BitDepthChroma << std::endl130<< "| Shift: " << info.Shift << std::endl131<< "| TemporalID: " << info.FrameId.TemporalId << std::endl132<< "| FrameRate: " << info.FrameRateExtN << "/" << info.FrameRateExtD << std::endl133<< "| AspectRatio: " << info.AspectRatioW << "x" << info.AspectRatioH << std::endl134<< "| PicStruct: " << info.PicStruct << std::endl135<< "| ChromaFormat: " << info.ChromaFormat << std::endl136;137return out;138}139140inline std::ostream & operator<<(std::ostream &out, const mfxFrameData &data) {141out << "FrameData:" << std::endl142<< "| NumExtParam: " << data.NumExtParam << std::endl143<< "| MemType: " << data.MemType << std::endl144<< "| PitchHigh: " << data.PitchHigh << std::endl145<< "| TimeStamp: " << data.TimeStamp << std::endl146<< "| FrameOrder: " << data.FrameOrder << std::endl147<< "| Locked: " << data.Locked << std::endl148<< "| Pitch: " << data.PitchHigh << ", " << data.PitchLow << std::endl149<< "| Y: " << (void*)data.Y << std::endl150<< "| U: " << (void*)data.U << std::endl151<< "| V: " << (void*)data.V << std::endl152;153return out;154}155156//==================================================================================================157158template <typename T>159inline void cleanup(T * &ptr)160{161if (ptr)162{163delete ptr;164ptr = 0;165}166}167168//==================================================================================================169170class Plugin171{172public:173static Plugin * loadEncoderPlugin(MFXVideoSession &session, mfxU32 codecId)174{175static const mfxPluginUID hevc_enc_uid = { 0x6f, 0xad, 0xc7, 0x91, 0xa0, 0xc2, 0xeb, 0x47, 0x9a, 0xb6, 0xdc, 0xd5, 0xea, 0x9d, 0xa3, 0x47 };176if (codecId == MFX_CODEC_HEVC)177return new Plugin(session, hevc_enc_uid);178return 0;179}180static Plugin * loadDecoderPlugin(MFXVideoSession &session, mfxU32 codecId)181{182static const mfxPluginUID hevc_dec_uid = { 0x33, 0xa6, 0x1c, 0x0b, 0x4c, 0x27, 0x45, 0x4c, 0xa8, 0xd8, 0x5d, 0xde, 0x75, 0x7c, 0x6f, 0x8e };183if (codecId == MFX_CODEC_HEVC)184return new Plugin(session, hevc_dec_uid);185return 0;186}187~Plugin()188{189if (isGood())190MFXVideoUSER_UnLoad(session, &uid);191}192bool isGood() const { return res >= MFX_ERR_NONE; }193private:194MFXVideoSession &session;195mfxPluginUID uid;196mfxStatus res;197private:198Plugin(MFXVideoSession &_session, mfxPluginUID _uid) : session(_session), uid(_uid)199{200res = MFXVideoUSER_Load(session, &uid, 1);201}202Plugin(const Plugin &);203Plugin &operator=(const Plugin &);204};205206//==================================================================================================207208class ReadBitstream209{210public:211ReadBitstream(const char * filename, size_t maxSize = 10 * 1024 * 1024);212~ReadBitstream();213bool isOpened() const;214bool isDone() const;215bool read();216private:217ReadBitstream(const ReadBitstream &);218ReadBitstream &operator=(const ReadBitstream &);219public:220std::fstream input;221mfxBitstream stream;222bool drain;223};224225//==================================================================================================226227class WriteBitstream228{229public:230WriteBitstream(const char * filename, size_t maxSize);231~WriteBitstream();232bool write();233bool isOpened() const;234private:235WriteBitstream(const WriteBitstream &);236WriteBitstream &operator=(const WriteBitstream &);237public:238std::fstream output;239mfxBitstream stream;240};241242//==================================================================================================243244class SurfacePool245{246public:247SurfacePool(ushort width_, ushort height_, ushort count, const mfxFrameInfo & frameInfo, uchar bpp = 12);248~SurfacePool();249mfxFrameSurface1 *getFreeSurface();250251template <typename T>252static SurfacePool * create(T * instance, mfxVideoParam ¶ms)253{254CV_Assert(instance);255mfxFrameAllocRequest request;256memset(&request, 0, sizeof(request));257mfxStatus res = instance->QueryIOSurf(¶ms, &request);258DBG(std::cout << "MFX QueryIOSurf: " << res << std::endl);259if (res < MFX_ERR_NONE)260return 0;261return new SurfacePool(request.Info.Width,262request.Info.Height,263request.NumFrameSuggested,264params.mfx.FrameInfo);265}266private:267SurfacePool(const SurfacePool &);268SurfacePool &operator=(const SurfacePool &);269public:270size_t width, height;271size_t oneSize;272cv::AutoBuffer<uchar, 0> buffers;273std::vector<mfxFrameSurface1> surfaces;274};275276//==================================================================================================277278class DeviceHandler {279public:280virtual ~DeviceHandler() {}281bool init(MFXVideoSession &session);282protected:283virtual bool initDeviceSession(MFXVideoSession &session) = 0;284};285286287// Linux specific288#ifdef __linux__289290#include <unistd.h>291#include <va/va_drm.h>292293class VAHandle : public DeviceHandler {294public:295VAHandle();296~VAHandle();297private:298VAHandle(const VAHandle &);299VAHandle &operator=(const VAHandle &);300virtual bool initDeviceSession(MFXVideoSession &session);301private:302VADisplay display;303int file;304};305306#endif // __linux__307308// Windows specific309#ifdef _WIN32310311#include <Windows.h>312inline void sleep(unsigned long sec) { Sleep(1000 * sec); }313314class DXHandle : public DeviceHandler {315public:316DXHandle() {}317~DXHandle() {}318private:319DXHandle(const DXHandle &);320DXHandle &operator=(const DXHandle &);321virtual bool initDeviceSession(MFXVideoSession &) { return true; }322};323324#endif // _WIN32325326DeviceHandler * createDeviceHandler();327328#endif // MFXHELPER_H329330331