Вот что я уже нашел
http://www.avidemux.org/admWiki/doku.php?id=tutorial:writing_your_own_filter
http://www.avidemux.org/admWiki/doku.php?id=using:video_filters
Написал такой код
bilateralFilter.cpp:
#include <opencv2/opencv.hpp>
#include "ADM_coreVideoFilter.h"
#include <QDialog>
#include <QLineEdit>
#include <QLabel>
typedef struct bilateralFilterParam {
int d;
double sigmaColor;
double sigmaSpace;
} bilateralFilterParam;
class BilateralFilter : public AVDMGenericVideoStream {
public:
BilateralFilter(AVDMGenericVideoStream *in, CONFcouple *couples);
~BilateralFilter();
char *printConf();
uint8_t getCoupledConf(CONFcouple **couples);
uint8_t configure(AVDMGenericVideoStream *in);
uint8_t getFrameNumberNoAlloc(uint32_t inframe, uint32_t *len, ADMImage *data, uint32_t *flags);
private:
bilateralFilterParam *_param;
QDialog *dialog;
QLineEdit *dEdit;
QLineEdit *sigmaColorEdit;
QLineEdit *sigmaSpaceEdit;
};
BilateralFilter::BilateralFilter(AVDMGenericVideoStream *in, CONFcouple *couples) {
_in = in;
_param = new bilateralFilterParam;
GET(_param->d);
GET(_param->sigmaColor);
GET(_param->sigmaSpace);
_info = _in->getInfo();
dialog = new QDialog();
QLabel *dLabel = new QLabel("d:");
dEdit = new QLineEdit(QString::number(_param->d));
QLabel *sigmaColorLabel = new QLabel("Sigma Color:");
sigmaColorEdit = new QLineEdit(QString::number(_param->sigmaColor));
QLabel *sigmaSpaceLabel = new QLabel("Sigma Space:");
sigmaSpaceEdit = new QLineEdit(QString::number(_param->sigmaSpace));
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(dLabel);
layout->addWidget(dEdit);
layout->addWidget(sigmaColorLabel);
layout->addWidget(sigmaColorEdit);
layout->addWidget(sigmaSpaceLabel);
layout->addWidget(sigmaSpaceEdit);
dialog->setLayout(layout);
}
char *BilateralFilter::printConf() {
static char buf[50];
sprintf((char *)buf, "Bilateral filter, d : %d, sigmaColor : %.2f, sigmaSpace : %.2f", _param->d, _param->sigmaColor, _param->sigmaSpace);
return buf;
}
uint8_t BilateralFilter::getCoupledConf(CONFcouple **couples) {
ADM_assert(_param);
*couples = new CONFcouple(3);
#undef CSET
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
CSET(d);
CSET(sigmaColor);
CSET(sigmaSpace);
return 1;
}
uint8_t BilateralFilter::configure(AVDMGenericVideoStream *in) {
_in = in;
// Return 1 to indicate that the filter chain might have to be rebuilt
return 1;
}
//Implement the getFrameNumberNoAlloc method. This is the central method where the work will be done.
uint8_t BilateralFilter::getFrameNumberNoAlloc(uint32_t inframe, uint32_t *len, ADMImage *data, uint32_t *flags) {
ADM_assert(inframe < _info.nb_frames); // Make sure we don't go out of bounds
// Read frames for the previous
ADM_assert(_in->getFrameNumberNoAlloc(inframe, len, _uncompressed, flags));
// Apply the bilateral filter
cv::Mat src(_uncompressed->height, _uncompressed->width, CV_8UC3, _uncompressed->planes[0], _uncompressed->pitches[0]);
cv::Mat dst;
cv::bilateralFilter(src, dst, _param->d, _param->sigmaColor, _param->sigmaSpace);
// Copy the result to data
memcpy(data->planes[0], dst.data, len[0]);
return 1; // ok
}
extern "C" {
SCRIPT_CREATE(FILTER_create_fromscript, BilateralFilter, bilateralFilterParam);
BUILD_CREATE(FILTER_create, BilateralFilter);
char *FILTER_getName(void) {
return "BilateralFilter";
}
char *FILTER_getDesc(void) {
return "Applies a bilateral filter to the video";
}
uint32_t FILTER_getVersion(void) {
return 1;
}
uint32_t FILTER_getAPIVersion(void) {
return ADM_FILTER_API_VERSION;
}
}
CXX = g++
CXXFLAGS = -Wall -fPIC
INCLUDES := -I/opt/qt/5.8/gcc_64/include -I/opt/qt/5.8/gcc_64/include/QtWidgets -I/opt/qt/5.8/gcc_64/include/QtGui -I/opt/qt/5.8/gcc_64/include/QtCore $(shell echo -n ""; for d in ./avidemux_2.7.1/avidemux_core/*/include; do echo -n "-I$$d "; done) -I./avidemux_2.7.1/addons/fontGen -I./avidemux_2.7.1/avidemux_core/ADM_coreDemuxer/include/unix
LIBS = -L/opt/qt/gcc_64/lib -L/usr/lib -lQtCore -lQtGui -lADM_coreVideoFilter6 -lopencv_core -lopencv_imgproc
all: bilateralFilter.so
bilateralFilter.so: bilateralFilter.o
$(CXX) -shared -o $@ $^ $(LIBS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
clean:
rm -f *.o bilateralFilter.so
apt install libopencv-dev
make
g++ -Wall -fPIC -I/opt/qt/5.8/gcc_64/include -I/opt/qt/5.8/gcc_64/include/QtWidgets -I/opt/qt/5.8/gcc_64/include/QtGui -I/opt/qt/5.8/gcc_64/include/QtCore -I./avidemux_2.7.1/avidemux_core/ADM_core/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudio/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudioCodec/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudioDevice/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudioEncoder/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudioFilter/include -I./avidemux_2.7.1/avidemux_core/ADM_coreAudioParser/include -I./avidemux_2.7.1/avidemux_core/ADM_coreDemuxer/include -I./avidemux_2.7.1/avidemux_core/ADM_coreDemuxerMpeg/include -I./avidemux_2.7.1/avidemux_core/ADM_coreImage/include -I./avidemux_2.7.1/avidemux_core/ADM_coreImageLoader/include -I./avidemux_2.7.1/avidemux_core/ADM_coreJobs/include -I./avidemux_2.7.1/avidemux_core/ADM_coreMuxer/include -I./avidemux_2.7.1/avidemux_core/ADM_coreScript/include -I./avidemux_2.7.1/avidemux_core/ADM_coreSocket/include -I./avidemux_2.7.1/avidemux_core/ADM_coreSqlLight3/include -I./avidemux_2.7.1/avidemux_core/ADM_coreSubtitles/include -I./avidemux_2.7.1/avidemux_core/ADM_coreUI/include -I./avidemux_2.7.1/avidemux_core/ADM_coreUtils/include -I./avidemux_2.7.1/avidemux_core/ADM_coreVideoCodec/include -I./avidemux_2.7.1/avidemux_core/ADM_coreVideoEncoder/include -I./avidemux_2.7.1/avidemux_core/ADM_coreVideoFilter/include -I./avidemux_2.7.1/addons/fontGen -I./avidemux_2.7.1/avidemux_core/ADM_coreDemuxer/include/unix -c bilateralFilter.cpp -o bilateralFilter.o
bilateralFilter.cpp:13:55: error: expected class-name before ‘{’ token
class BilateralFilter : public AVDMGenericVideoStream {
^
bilateralFilter.cpp:15:44: error: expected ‘)’ before ‘*’ token
BilateralFilter(AVDMGenericVideoStream *in, CONFcouple *couples);
^
bilateralFilter.cpp:20:23: error: ‘AVDMGenericVideoStream’ has not been declared
uint8_t configure(AVDMGenericVideoStream *in);
^~~~~~~~~~~~~~~~~~~~~~
bilateralFilter.cpp:31:33: error: expected constructor, destructor, or type conversion before ‘(’ token
BilateralFilter::BilateralFilter(AVDMGenericVideoStream *in, CONFcouple *couples) {
^
bilateralFilter.cpp: In member function ‘uint8_t BilateralFilter::getCoupledConf(CONFcouple**)’:
bilateralFilter.cpp:67:33: error: ‘class CONFcouple’ has no member named ‘setCouple’; did you mean ‘CONFcouple’?
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^
bilateralFilter.cpp:67:33: note: in definition of macro ‘CSET’
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^~~~~~~~~
bilateralFilter.cpp:67:33: error: ‘class CONFcouple’ has no member named ‘setCouple’; did you mean ‘CONFcouple’?
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^
bilateralFilter.cpp:67:33: note: in definition of macro ‘CSET’
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^~~~~~~~~
bilateralFilter.cpp:67:33: error: ‘class CONFcouple’ has no member named ‘setCouple’; did you mean ‘CONFcouple’?
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^
bilateralFilter.cpp:67:33: note: in definition of macro ‘CSET’
#define CSET(x) (*couples)->setCouple(#x,(_param->x))
^~~~~~~~~
bilateralFilter.cpp: At global scope:
bilateralFilter.cpp:74:36: error: ‘uint8_t BilateralFilter::configure’ is not a static data member of ‘class BilateralFilter’
uint8_t BilateralFilter::configure(AVDMGenericVideoStream *in) {
^~~~~~~~~~~~~~~~~~~~~~
bilateralFilter.cpp:74:36: error: ‘AVDMGenericVideoStream’ was not declared in this scope
bilateralFilter.cpp:74:60: error: ‘in’ was not declared in this scope
uint8_t BilateralFilter::configure(AVDMGenericVideoStream *in) {
^~
bilateralFilter.cpp:74:60: note: suggested alternative: ‘yn’
uint8_t BilateralFilter::configure(AVDMGenericVideoStream *in) {
^~
yn
In file included from ./avidemux_2.7.1/avidemux_core/ADM_coreImage/include/ADM_image.h:30:0,
from ./avidemux_2.7.1/avidemux_core/ADM_coreVideoFilter/include/ADM_coreVideoFilter.h:22,
from bilateralFilter.cpp:2:
bilateralFilter.cpp: In member function ‘uint8_t BilateralFilter::getFrameNumberNoAlloc(uint32_t, uint32_t*, ADMImage*, uint32_t*)’:
bilateralFilter.cpp:83:26: error: ‘_info’ was not declared in this scope
ADM_assert(inframe < _info.nb_frames); // Make sure we don't go out of bounds
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:83:26: note: suggested alternative: ‘sinf’
ADM_assert(inframe < _info.nb_frames); // Make sure we don't go out of bounds
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:86:16: error: ‘_in’ was not declared in this scope
ADM_assert(_in->getFrameNumberNoAlloc(inframe, len, _uncompressed, flags));
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:86:16: note: suggested alternative: ‘sin’
ADM_assert(_in->getFrameNumberNoAlloc(inframe, len, _uncompressed, flags));
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:86:57: error: ‘_uncompressed’ was not declared in this scope
ADM_assert(_in->getFrameNumberNoAlloc(inframe, len, _uncompressed, flags));
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:86:57: note: suggested alternative: ‘qUncompress’
ADM_assert(_in->getFrameNumberNoAlloc(inframe, len, _uncompressed, flags));
^
./avidemux_2.7.1/avidemux_core/ADM_core/include/ADM_assert.h:30:30: note: in definition of macro ‘ADM_assert’
#define ADM_assert(x) { if(!(x)) {ADM_backTrack("Assert failed :"#x,__LINE__,__FILE__); }}
^
bilateralFilter.cpp:89:17: error: ‘_uncompressed’ was not declared in this scope
cv::Mat src(_uncompressed->height, _uncompressed->width, CV_8UC3, _uncompressed->planes[0], _uncompressed->pitches[0]);
^~~~~~~~~~~~~
bilateralFilter.cpp:89:17: note: suggested alternative: ‘qUncompress’
cv::Mat src(_uncompressed->height, _uncompressed->width, CV_8UC3, _uncompressed->planes[0], _uncompressed->pitches[0]);
^~~~~~~~~~~~~
qUncompress
bilateralFilter.cpp:94:18: error: ‘class ADMImage’ has no member named ‘planes’; did you mean ‘_planes’?
memcpy(data->planes[0], dst.data, len[0]);
^~~~~~
_planes
bilateralFilter.cpp: At global scope:
bilateralFilter.cpp:100:18: error: expected constructor, destructor, or type conversion before ‘(’ token
SCRIPT_CREATE(FILTER_create_fromscript, BilateralFilter, bilateralFilterParam);
^
bilateralFilter.cpp:101:17: error: expected constructor, destructor, or type conversion before ‘(’ token
BUILD_CREATE(FILTER_create, BilateralFilter);
^
bilateralFilter.cpp: In function ‘char* FILTER_getName()’:
bilateralFilter.cpp:103:16: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
return "BilateralFilter";
^~~~~~~~~~~~~~~~~
bilateralFilter.cpp: In function ‘char* FILTER_getDesc()’:
bilateralFilter.cpp:106:16: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
return "Applies a bilateral filter to the video";
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bilateralFilter.cpp: In function ‘uint32_t FILTER_getAPIVersion()’:
bilateralFilter.cpp:112:16: error: ‘ADM_FILTER_API_VERSION’ was not declared in this scope
return ADM_FILTER_API_VERSION;
^~~~~~~~~~~~~~~~~~~~~~
bilateralFilter.cpp:112:16: note: suggested alternative: ‘VF_API_VERSION’
return ADM_FILTER_API_VERSION;
^~~~~~~~~~~~~~~~~~~~~~
VF_API_VERSION
bilateralFilter.cpp: In member function ‘char* BilateralFilter::printConf()’:
bilateralFilter.cpp:57:7: warning: ‘, sigmaSpace : ’ directive writing 15 bytes into a region of size between 0 and 8 [-Wformat-overflow=]
char *BilateralFilter::printConf() {
^~~~~~~~~~~~~~~
bilateralFilter.cpp:59:12: note: ‘sprintf’ output between 62 and 690 bytes into a destination of size 50
sprintf((char *)buf, "Bilateral filter, d : %d, sigmaColor : %.2f, sigmaSpace : %.2f", _param->d, _param->sigmaColor, _param->sigmaSpace);
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Makefile:12: recipe for target 'bilateralFilter.o' failed
make: *** [bilateralFilter.o] Error 1
UPD
Попробовал применить другой базовый класс, сейчас код собирается и запускается, но требует дебага и выполняется без падений.