videoio: HW decode/encode in FFMPEG backend; new properties with support in FFMPEG/GST/MSMF * HW acceleration in FFMPEG backend * fixes on Windows, remove D3D9 * HW acceleration in FFMPEG backend * fixes on Windows, remove D3D9 * improve va test * Copyright * check LIBAVUTIL_BUILD >= AV_VERSION_INT(55, 78, 100) // FFMPEG 3.4+ * CAP_MSMF test on .mp4 * .mp4 in test * improve va test * Copyright * check LIBAVUTIL_BUILD >= AV_VERSION_INT(55, 78, 100) // FFMPEG 3.4+ * CAP_MSMF test on .mp4 * .mp4 in test * .avi for GStreamer test * revert changes around seek() * cv_writer_open_with_params * params.warnUnusedParameters * VideoCaptureParameters in GStreamer * open_with_params * params->getUnused * Reduce PSNR threshold 33->32 (other tests use 30) * require FFMPEG 4.0+; PSNR 30 as in other tests * GStreamer AVI-demux plugin not installed in Ubuntu test environment? * fix build on very old ffmpeg * fix build on very old ffmpeg * fix build issues * fix build issues (static_cast) * FFMPEG built on Windows without H264 encoder? * fix for write_nothing test on VAAPI * fix warnings * fix cv_writer_get_prop in plugins * use avcodec_get_hw_frames_parameters; more robust fallback to SW codecs * internal function hw_check_device() for device check/logging * two separate tests for HW read and write * image size 640x480 in encode test * WITH_VA=ON (only .h headers used in OpenCV, no linkage dependency) * exception on VP9 SW encoder? * rebase master; refine info message * videoio: fix FFmpeg standalone plugin build * videoio(ffmpeg): eliminate MSVC build warnings * address review comments * videoio(hw): update videocapture_acceleration.read test - remove parallel decoding by SW code path - check PSNR against the original generated image * videoio: minor fixes * videoio(test): disable unsupported MSMF cases (SW and HW) * videoio(test): update PSNR thresholds for HW acceleration read * videoio(test): update debug messages * "hw_acceleration" whitelisting parameter * little optimization in test * D3D11VA supports decoders, doesn't support encoders * videoio(test): adjust PSNR threshold in write_read_position tests * videoio(ffmpeg): fix rejecting on acceleration device name mismatch * videoio(ffmpeg): fix compilation USE_AV_HW_CODECS=0, add more debug logging * videoio: rework VideoAccelerationType behavior - enum is not a bitset - default value is backend specific - only '_NONE' and '_ANY' may fallback on software processing - specific H/W acceleration doesn't fallback on software processing. It fails if there is no support for specified H/W acceleration. * videoio(test): fix for current FFmpeg wrapper Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
180 lines
6.6 KiB
C++
180 lines
6.6 KiB
C++
// This file is part of OpenCV project.
|
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
// of this distribution and at http://opencv.org/license.html.
|
|
|
|
#include "precomp.hpp"
|
|
|
|
#include "backend.hpp"
|
|
|
|
namespace cv {
|
|
|
|
|
|
void applyParametersFallback(const Ptr<IVideoCapture>& cap, const VideoCaptureParameters& params)
|
|
{
|
|
std::vector<int> props = params.getUnused();
|
|
CV_LOG_INFO(NULL, "VIDEOIO: Backend '" << videoio_registry::getBackendName((VideoCaptureAPIs)cap->getCaptureDomain()) <<
|
|
"' implementation doesn't support parameters in .open(). Applying " <<
|
|
props.size() << " properties through .setProperty()");
|
|
for (int prop : props)
|
|
{
|
|
double value = params.get<double>(prop, -1);
|
|
CV_LOG_INFO(NULL, "VIDEOIO: apply parameter: [" << prop << "]=" <<
|
|
cv::format("%g / %lld / 0x%016llx", value, (long long)value, (long long)value));
|
|
if (!cap->setProperty(prop, value))
|
|
{
|
|
if (prop != CAP_PROP_HW_ACCELERATION && prop != CAP_PROP_HW_DEVICE) { // optional parameters
|
|
CV_Error_(cv::Error::StsNotImplemented, ("VIDEOIO: Failed to apply invalid or unsupported parameter: [%d]=%g / %lld / 0x%08llx", prop, value, (long long)value, (long long)value));
|
|
}
|
|
}
|
|
}
|
|
// NB: there is no dedicated "commit" parameters event, implementations should commit after each property automatically
|
|
}
|
|
|
|
// Legacy API. Modern API with parameters is below
|
|
class StaticBackend: public IBackend
|
|
{
|
|
public:
|
|
FN_createCaptureFile fn_createCaptureFile_;
|
|
FN_createCaptureCamera fn_createCaptureCamera_;
|
|
FN_createWriter fn_createWriter_;
|
|
|
|
StaticBackend(FN_createCaptureFile fn_createCaptureFile, FN_createCaptureCamera fn_createCaptureCamera, FN_createWriter fn_createWriter)
|
|
: fn_createCaptureFile_(fn_createCaptureFile), fn_createCaptureCamera_(fn_createCaptureCamera), fn_createWriter_(fn_createWriter)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
~StaticBackend() CV_OVERRIDE {}
|
|
|
|
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createCaptureCamera_)
|
|
{
|
|
Ptr<IVideoCapture> cap = fn_createCaptureCamera_(camera);
|
|
if (cap && !params.empty())
|
|
{
|
|
applyParametersFallback(cap, params);
|
|
}
|
|
return cap;
|
|
}
|
|
return Ptr<IVideoCapture>();
|
|
}
|
|
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createCaptureFile_)
|
|
{
|
|
Ptr<IVideoCapture> cap = fn_createCaptureFile_(filename);
|
|
if (cap && !params.empty())
|
|
{
|
|
applyParametersFallback(cap, params);
|
|
}
|
|
return cap;
|
|
}
|
|
return Ptr<IVideoCapture>();
|
|
}
|
|
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
|
|
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createWriter_)
|
|
return fn_createWriter_(filename, fourcc, fps, sz, params);
|
|
return Ptr<IVideoWriter>();
|
|
}
|
|
}; // StaticBackend
|
|
|
|
class StaticBackendFactory : public IBackendFactory
|
|
{
|
|
protected:
|
|
Ptr<StaticBackend> backend;
|
|
|
|
public:
|
|
StaticBackendFactory(FN_createCaptureFile createCaptureFile, FN_createCaptureCamera createCaptureCamera, FN_createWriter createWriter)
|
|
: backend(makePtr<StaticBackend>(createCaptureFile, createCaptureCamera, createWriter))
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
~StaticBackendFactory() CV_OVERRIDE {}
|
|
|
|
Ptr<IBackend> getBackend() const CV_OVERRIDE
|
|
{
|
|
return backend.staticCast<IBackend>();
|
|
}
|
|
};
|
|
|
|
|
|
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile,
|
|
FN_createCaptureCamera createCaptureCamera,
|
|
FN_createWriter createWriter)
|
|
{
|
|
return makePtr<StaticBackendFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
|
|
}
|
|
|
|
|
|
|
|
class StaticBackendWithParams: public IBackend
|
|
{
|
|
public:
|
|
FN_createCaptureFileWithParams fn_createCaptureFile_;
|
|
FN_createCaptureCameraWithParams fn_createCaptureCamera_;
|
|
FN_createWriter fn_createWriter_;
|
|
|
|
StaticBackendWithParams(FN_createCaptureFileWithParams fn_createCaptureFile, FN_createCaptureCameraWithParams fn_createCaptureCamera, FN_createWriter fn_createWriter)
|
|
: fn_createCaptureFile_(fn_createCaptureFile), fn_createCaptureCamera_(fn_createCaptureCamera), fn_createWriter_(fn_createWriter)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
~StaticBackendWithParams() CV_OVERRIDE {}
|
|
|
|
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createCaptureCamera_)
|
|
return fn_createCaptureCamera_(camera, params);
|
|
return Ptr<IVideoCapture>();
|
|
}
|
|
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createCaptureFile_)
|
|
return fn_createCaptureFile_(filename, params);
|
|
return Ptr<IVideoCapture>();
|
|
}
|
|
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
|
|
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE
|
|
{
|
|
if (fn_createWriter_)
|
|
return fn_createWriter_(filename, fourcc, fps, sz, params);
|
|
return Ptr<IVideoWriter>();
|
|
}
|
|
}; // StaticBackendWithParams
|
|
|
|
class StaticBackendWithParamsFactory : public IBackendFactory
|
|
{
|
|
protected:
|
|
Ptr<StaticBackendWithParams> backend;
|
|
|
|
public:
|
|
StaticBackendWithParamsFactory(FN_createCaptureFileWithParams createCaptureFile, FN_createCaptureCameraWithParams createCaptureCamera, FN_createWriter createWriter)
|
|
: backend(makePtr<StaticBackendWithParams>(createCaptureFile, createCaptureCamera, createWriter))
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
~StaticBackendWithParamsFactory() CV_OVERRIDE {}
|
|
|
|
Ptr<IBackend> getBackend() const CV_OVERRIDE
|
|
{
|
|
return backend.staticCast<IBackend>();
|
|
}
|
|
};
|
|
|
|
|
|
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFileWithParams createCaptureFile,
|
|
FN_createCaptureCameraWithParams createCaptureCamera,
|
|
FN_createWriter createWriter)
|
|
{
|
|
return makePtr<StaticBackendWithParamsFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
|
|
}
|
|
|
|
|
|
} // namespace
|