mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge pull request #17228 from mshabunin:mfx-surface-pool-34
This commit is contained in:
commit
6856cc7253
@ -14,10 +14,30 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
static mfxIMPL getImpl()
|
||||||
|
{
|
||||||
|
static const size_t res = utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_MFX_IMPL", MFX_IMPL_AUTO_ANY);
|
||||||
|
return (mfxIMPL)res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t getExtraSurfaceNum()
|
||||||
|
{
|
||||||
|
static const size_t res = cv::utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_MFX_EXTRA_SURFACE_NUM", 1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t getPoolTimeoutSec()
|
||||||
|
{
|
||||||
|
static const size_t res = utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_MFX_POOL_TIMEOUT", 1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
bool DeviceHandler::init(MFXVideoSession &session)
|
bool DeviceHandler::init(MFXVideoSession &session)
|
||||||
{
|
{
|
||||||
mfxStatus res = MFX_ERR_NONE;
|
mfxStatus res = MFX_ERR_NONE;
|
||||||
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
|
mfxIMPL impl = getImpl();
|
||||||
mfxVersion ver = { {19, 1} };
|
mfxVersion ver = { {19, 1} };
|
||||||
|
|
||||||
res = session.Init(impl, &ver);
|
res = session.Init(impl, &ver);
|
||||||
@ -114,11 +134,26 @@ SurfacePool::~SurfacePool()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SurfacePool * SurfacePool::_create(const mfxFrameAllocRequest &request, const mfxVideoParam ¶ms)
|
||||||
|
{
|
||||||
|
return new SurfacePool(request.Info.Width,
|
||||||
|
request.Info.Height,
|
||||||
|
saturate_cast<ushort>((size_t)request.NumFrameSuggested + getExtraSurfaceNum()),
|
||||||
|
params.mfx.FrameInfo);
|
||||||
|
}
|
||||||
|
|
||||||
mfxFrameSurface1 *SurfacePool::getFreeSurface()
|
mfxFrameSurface1 *SurfacePool::getFreeSurface()
|
||||||
{
|
{
|
||||||
for(std::vector<mfxFrameSurface1>::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
|
const int64 start = cv::getTickCount();
|
||||||
if (!i->Data.Locked)
|
do
|
||||||
return &(*i);
|
{
|
||||||
|
for(std::vector<mfxFrameSurface1>::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
|
||||||
|
if (!i->Data.Locked)
|
||||||
|
return &(*i);
|
||||||
|
sleep_ms(10);
|
||||||
|
}
|
||||||
|
while((cv::getTickCount() - start) / cv::getTickFrequency() < getPoolTimeoutSec()); // seconds
|
||||||
|
DBG(cout << "No free surface!" << std::endl);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define MFXHELPER_H
|
#define MFXHELPER_H
|
||||||
|
|
||||||
#include "opencv2/core.hpp"
|
#include "opencv2/core.hpp"
|
||||||
|
#include "opencv2/core/utils/configuration.private.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -259,11 +260,10 @@ public:
|
|||||||
DBG(std::cout << "MFX QueryIOSurf: " << res << std::endl);
|
DBG(std::cout << "MFX QueryIOSurf: " << res << std::endl);
|
||||||
if (res < MFX_ERR_NONE)
|
if (res < MFX_ERR_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
return new SurfacePool(request.Info.Width,
|
return _create(request, params);
|
||||||
request.Info.Height,
|
|
||||||
request.NumFrameSuggested,
|
|
||||||
params.mfx.FrameInfo);
|
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
static SurfacePool* _create(const mfxFrameAllocRequest& request, const mfxVideoParam& params);
|
||||||
private:
|
private:
|
||||||
SurfacePool(const SurfacePool &);
|
SurfacePool(const SurfacePool &);
|
||||||
SurfacePool &operator=(const SurfacePool &);
|
SurfacePool &operator=(const SurfacePool &);
|
||||||
@ -285,6 +285,29 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: move to core::util?
|
||||||
|
#ifdef CV_CXX11
|
||||||
|
#include <thread>
|
||||||
|
static void sleep_ms(int64 ms)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||||
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <time.h>
|
||||||
|
static void sleep_ms(int64 ms)
|
||||||
|
{
|
||||||
|
nanosleep(ms * 1000 * 1000);
|
||||||
|
}
|
||||||
|
#elif defined _WIN32
|
||||||
|
static void sleep_ms(int64 ms)
|
||||||
|
{
|
||||||
|
Sleep(ms);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Can not detect sleep_ms() implementation"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Linux specific
|
// Linux specific
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
@ -310,7 +333,6 @@ private:
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
inline void sleep(unsigned long sec) { Sleep(1000 * sec); }
|
|
||||||
|
|
||||||
class DXHandle : public DeviceHandler {
|
class DXHandle : public DeviceHandler {
|
||||||
public:
|
public:
|
||||||
|
@ -214,7 +214,7 @@ bool VideoCapture_IntelMFX::grabFrame()
|
|||||||
else if (res == MFX_WRN_DEVICE_BUSY)
|
else if (res == MFX_WRN_DEVICE_BUSY)
|
||||||
{
|
{
|
||||||
DBG(cout << "Waiting for device" << endl);
|
DBG(cout << "Waiting for device" << endl);
|
||||||
sleep(1);
|
sleep_ms(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (res == MFX_WRN_VIDEO_PARAM_CHANGED)
|
else if (res == MFX_WRN_VIDEO_PARAM_CHANGED)
|
||||||
|
@ -10,6 +10,18 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
static size_t getBitrateDivisor()
|
||||||
|
{
|
||||||
|
static const size_t res = utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_MFX_BITRATE_DIVISOR", 300);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mfxU32 getWriterTimeoutMS()
|
||||||
|
{
|
||||||
|
static const size_t res = utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_MFX_WRITER_TIMEOUT", 1);
|
||||||
|
return saturate_cast<mfxU32>(res * 1000); // convert from seconds
|
||||||
|
}
|
||||||
|
|
||||||
inline mfxU32 codecIdByFourCC(int fourcc)
|
inline mfxU32 codecIdByFourCC(int fourcc)
|
||||||
{
|
{
|
||||||
const int CC_MPG2 = FourCC('M', 'P', 'G', '2').vali32;
|
const int CC_MPG2 = FourCC('M', 'P', 'G', '2').vali32;
|
||||||
@ -77,7 +89,7 @@ VideoWriter_IntelMFX::VideoWriter_IntelMFX(const String &filename, int _fourcc,
|
|||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.mfx.CodecId = codecId;
|
params.mfx.CodecId = codecId;
|
||||||
params.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED;
|
params.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED;
|
||||||
params.mfx.TargetKbps = (mfxU16)cvRound(frameSize.area() * fps / 500); // TODO: set in options
|
params.mfx.TargetKbps = saturate_cast<mfxU16>((frameSize.area() * fps) / (42.6666 * getBitrateDivisor())); // TODO: set in options
|
||||||
params.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
|
params.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
|
||||||
params.mfx.FrameInfo.FrameRateExtN = cvRound(fps * 1000);
|
params.mfx.FrameInfo.FrameRateExtN = cvRound(fps * 1000);
|
||||||
params.mfx.FrameInfo.FrameRateExtD = 1000;
|
params.mfx.FrameInfo.FrameRateExtD = 1000;
|
||||||
@ -210,7 +222,7 @@ bool VideoWriter_IntelMFX::write_one(cv::InputArray bgr)
|
|||||||
res = encoder->EncodeFrameAsync(NULL, workSurface, &bs->stream, &sync);
|
res = encoder->EncodeFrameAsync(NULL, workSurface, &bs->stream, &sync);
|
||||||
if (res == MFX_ERR_NONE)
|
if (res == MFX_ERR_NONE)
|
||||||
{
|
{
|
||||||
res = session->SyncOperation(sync, 1000); // 1 sec, TODO: provide interface to modify timeout
|
res = session->SyncOperation(sync, getWriterTimeoutMS()); // TODO: provide interface to modify timeout
|
||||||
if (res == MFX_ERR_NONE)
|
if (res == MFX_ERR_NONE)
|
||||||
{
|
{
|
||||||
// ready to write
|
// ready to write
|
||||||
@ -239,7 +251,7 @@ bool VideoWriter_IntelMFX::write_one(cv::InputArray bgr)
|
|||||||
else if (res == MFX_WRN_DEVICE_BUSY)
|
else if (res == MFX_WRN_DEVICE_BUSY)
|
||||||
{
|
{
|
||||||
DBG(cout << "Waiting for device" << endl);
|
DBG(cout << "Waiting for device" << endl);
|
||||||
sleep(1);
|
sleep_ms(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user