LINUX.ORG.RU

Создать плагин для Avidemux

 ,


0

1

Вот что я уже нашел
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;
    }
}
Makefile:
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

Попробовал применить другой базовый класс, сейчас код собирается и запускается, но требует дебага и выполняется без падений.

★★★

Последнее исправление: damix9 (всего исправлений: 2)

bilateralFilter.cpp:20:23: error: ‘AVDMGenericVideoStream’ has not been declared uint8_t configure(AVDMGenericVideoStream *in);

чой-та? где декларируется вот эта фуета - AVDMGenericVideoStream?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)

Написано же

Declare a tag for your filter in ADM_filter/video_filters.h Register your filter in ADM_filter/filter_declaration.cpp using REGISTERX(«rotate»,«Rotate»,«Rotate the picture by 90, 180 or 270 degrees.»,VF_ROTATE,1,rotate_create,rotate_script); The first parameter is the internal name (must be unique). The second and 3rd parameters are the one used for display a,d brief. The fourth one is the tag you declared above. DON’T REUSE AN EXISTING TAG. You would have big problems, believe me. The 2 last ones must be the same as the function described below

Файл ADM_videoFilter/ADM_vidConvolution.hxx

IIIypuk ★★★★
()
Ответ на: комментарий от alysnix

Кто бы знал. В мануале написано этот класс использовать, часть плагинов в составе программы его используют, но в исходниках программы его не вижу.

IIIypuk пишет:

Declare a tag for your filter in ADM_filter/video_filters.h Register your filter in ADM_filter/filter_declaration.cpp using REGISTERX

Так это про «Bundled filter», это же требует пересборки Avidemux (или нет?), а я хочу «Plugin». Но это неважно, у меня не конпеляется даже.

damix9 ★★★
() автор топика
Ответ на: комментарий от alysnix

Его нет ни в каком хедере. Переписал код.

#include <opencv2/opencv.hpp>
#include "ADM_coreVideoFilter.h"
#include "ADM_vidMisc.h"
#include "ADM_default.h"
#include <QDialog>
#include <QLineEdit>
#include <QLabel>
#include <QHBoxLayout>
#include <QPushButton>
#include <QGridLayout>

typedef struct bilateralFilterParam {
    uint32_t d;
    double sigmaColor;
    double sigmaSpace;
} bilateralFilterParam;

const ADM_paramList bf_param[]={
 {"d",offsetof(bilateralFilterParam,d),"uint32_t",ADM_param_uint32_t},
 {"sigmaColor",offsetof(bilateralFilterParam,sigmaColor),"double",ADM_param_double},
 {"sigmaSpace",offsetof(bilateralFilterParam,sigmaSpace),"double",ADM_param_double},
 {NULL,0,NULL}
};

class BilateralFilter : public ADM_coreVideoFilter {
    protected:
        bilateralFilterParam *_param;
        QDialog *dialog;
        QLineEdit *dEdit;
        QLineEdit *sigmaColorEdit;
        QLineEdit *sigmaSpaceEdit;

    public:
        BilateralFilter(ADM_coreVideoFilter *previous, CONFcouple *conf);
        ~BilateralFilter();

        virtual const char *getConfiguration(void);
        virtual bool getNextFrame(uint32_t *fn, ADMImage *image);
        virtual bool getCoupledConf(CONFcouple **couples);
        virtual void setCoupledConf(CONFcouple *couples);
        virtual bool configure(void);
};

// Add the hook to make it valid plugin
DECLARE_VIDEO_FILTER_PARTIALIZABLE(   BilateralFilter,   // Class
                        1,0,0,              // Version
                        ADM_UI_ALL,         // UI
                        VF_MISC,            // Category
                        "bilateral",            // internal name (must be uniq!)
                        "Bilateral",            // Display name
                        "Bilateral filter - FIXME - add description" // Description
                    );

BilateralFilter::BilateralFilter(ADM_coreVideoFilter *previous, CONFcouple *conf) : ADM_coreVideoFilter(previous, conf) {
    _param = new bilateralFilterParam;
    if (!conf || !ADM_paramLoad(conf, bf_param, _param))
    {
        // default values
        _param->d = 0;
        _param->sigmaColor = 70;
        _param->sigmaSpace = 70;
    }
    
    dialog = new QDialog();
    QLabel *descriptionLabel = new QLabel("This is a bilateral filter. \nAdjust the parameters below. \nFIXME");
    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));
    QPushButton *okButton = new QPushButton("OK");
    QPushButton *cancelButton = new QPushButton("Cancel");

    QObject::connect(okButton, &QPushButton::clicked, dialog, &QDialog::accept);
    QObject::connect(cancelButton, &QPushButton::clicked, dialog, &QDialog::close);

    QGridLayout *layout = new QGridLayout();
    layout->addWidget(descriptionLabel, 0, 0, 1, 2);
    layout->addWidget(dLabel, 1, 0);
    layout->addWidget(dEdit, 1, 1);
    layout->addWidget(sigmaColorLabel, 2, 0);
    layout->addWidget(sigmaColorEdit, 2, 1);
    layout->addWidget(sigmaSpaceLabel, 3, 0);
    layout->addWidget(sigmaSpaceEdit, 3, 1);
    
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    // Add spacers to push the buttons to the right
    buttonLayout->addStretch();
    buttonLayout->addWidget(okButton);
    buttonLayout->addSpacing(10);
    buttonLayout->addWidget(cancelButton);

    layout->addLayout(buttonLayout, 4, 0, 1, 2);
    
    dialog->setLayout(layout);
}

BilateralFilter::~BilateralFilter() {
    delete _param;
    delete dialog;
    delete dEdit;
    delete sigmaColorEdit;
    delete sigmaSpaceEdit;
}

const char *BilateralFilter::getConfiguration(void) {
    static char buf[1024];
    sprintf((char *)buf, "Bilateral filter, d : %d, sigmaColor : %.2f, sigmaSpace : %.2f", _param->d, _param->sigmaColor, _param->sigmaSpace);
    return buf;
}

bool BilateralFilter::getNextFrame(uint32_t *fn, ADMImage *image) {
    // Assert that the frame number is within the valid range
    //ADM_assert(*fn < _info.nb_frames);

    // Get the next frame from the previous filter
    //ADM_assert(previousFilter->getNextFrame(fn, image));
    
    if(false==previousFilter->getNextFrame(fn,image))
    {
        return false;
    }

    // Convert the image data to a cv::Mat object
    cv::Mat src(image->_height, image->_width, CV_8UC3, image->GetWritePtr(PLANAR_Y), image->GetPitch(PLANAR_Y));

    // Create a destination cv::Mat object for the filtered image
    cv::Mat dst;

    // Apply the bilateral filter to the source image
    cv::bilateralFilter(src, dst, _param->d, _param->sigmaColor, _param->sigmaSpace);

    // Copy the filtered image back into the image object
    memcpy(image->GetWritePtr(PLANAR_Y), dst.data, image->GetPitch(PLANAR_Y) * image->_height);

    return true;
}

bool BilateralFilter::getCoupledConf(CONFcouple **couples) {
    return ADM_paramSave(couples, bf_param, _param);
}

void BilateralFilter::setCoupledConf(CONFcouple *couples) {
    ADM_paramLoad(couples, bf_param, _param);
}

bool BilateralFilter::configure(void) {
    // Show the dialog
    int result = dialog->exec();

    // Check if the user clicked OK
    if (result == QDialog::Accepted) {
        // Update the filter parameters based on the values entered by the user
        _param->d = dEdit->text().toInt();
        _param->sigmaColor = sigmaColorEdit->text().toDouble();
        _param->sigmaSpace = sigmaSpaceEdit->text().toDouble();
    }

    return true;
}
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 -lQt5Core -lQt5Gui -lADM_coreVideoFilter6 -lopencv_core -lopencv_imgproc
#LIBS = -L/opt/qt/gcc_64/lib -L/usr/lib -lQt5Core -lQt5Gui -lADM_coreVideoFilter6 /path/to/your/static/opencv_core.a /path/to/your/static/opencv_imgproc.a

all: bilateralFilter.so

bilateralFilter.so: bilateralFilter.o
	$(CXX) -shared -o $@ $^ $(LIBS)

%.o: %.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

clean:
	rm -f *.o bilateralFilter.so
Теперь он конпеляется и даже запускается.
make clean
make
cp bilateralFilter.so /usr/lib/ADM_plugins6/videoFilters/
После чего просто открыл Avidemux, новый плагин появился в UI.

Похоже, мануал устарел.

damix9 ★★★
() автор топика
Ответ на: комментарий от damix9
configure(void) 

в c++ void не обязателен для функции без параметров

configure() 

и еще:

typedef struct bilateralFilterParam {
    uint32_t d;
    double sigmaColor;
    double sigmaSpace;
} bilateralFilterParam;

а структуру проще декларировать без typedef

struct bilateralFilterParam {
    uint32_t d;
    double sigmaColor;
    double sigmaSpace;
};
alysnix ★★★
()
Ответ на: комментарий от alysnix

Спасибо, я давно не повторял C++ и никогда его серьезно не изучал, для меня это «Си, только с классами». А этот код мне по большей части писала нейросеть.

а структуру проще декларировать без typedef

А отличий нет?

Может какие еще будут замечания?

У меня еще если добавить мой фильтр к видео, а затем его удалить, крэшится с

 [HandleAction] 23:49:23-697  ************ VIDEO_FILTERS **************
active : 0x5633bf41e830
 [displayFamily] 23:49:23-704  Video filter Family :0, nb 15
0 active filters
Paint event
Paint event
 [displayFamily] 23:49:26-429  Video filter Family :7, nb 4
 [add] 23:49:28-690  Tag : 701->family=7, index=1
 [ADM_vf_addFilterFromTag] 23:49:28-690  Creating video filter using tag 701 
[VideoFilterBridge] Creating bridge from 0 s to 4154504685 s
 [convertLinearTimeToSeg] 23:49:28-690  Frame time=0, taking first segment 
 [seektoTime] 23:49:28-690  Seeking to a keyframe at 0 ms
 [seektoTime] 23:49:28-690  Seeking to frame 0 at 0 ms
 [DecodePictureUpToIntra] 23:49:28-690  Decoding up to intra frame 0, ref: 0
[edCache] Flush
 [goToTimeVideo] 23:49:28-694  Seek done, in reference, gone to 0 with segment start at 0
1 active filters
0 Bilateral
Active item :0x5633bf9e9e10
 [remove] 23:50:41-783  Deleting item 0
 [ADM_vf_removeFilterAtIndex] 23:50:41-783  Deleting video filter at index 0
Недопустимая инструкция (стек памяти сброшен на диск)
Ну я не знаю, правильно ли собственно getNextFrame(uint32_t *fn, ADMImage *image) написан. Если начать сохранять видео, процессор долбится в соточку, все потоки; память заметно не течет; а видео обрабатывается больше нескольких минут, я дольше ждать не стал. Это норма или нет? 
И правильно ли вообще сглаживать видео, применяя алгоритм, предназначенный для сглаживания картинок тупо к каждому кадру?
cast  IIIypuk

damix9 ★★★
() автор топика
Ответ на: комментарий от damix9

я чисто по с++. что вы там программируете - не понимаю досконально. фильтры какие-то и обработка изображений.

насколько я понял, можете обойти реальную обработку фильтром, просто закомментив в кусок в BilateralFilter::getNextFrame(uint32_t *fn, ADMImage *image) :

    // Convert the image data to a cv::Mat object
    cv::Mat src(image->_height, image->_width, CV_8UC3, image->GetWritePtr(PLANAR_Y), image->GetPitch(PLANAR_Y));

    // Create a destination cv::Mat object for the filtered image
    cv::Mat dst;

    // Apply the bilateral filter to the source image
    cv::bilateralFilter(src, dst, _param->d, _param->sigmaColor, _param->sigmaSpace);

    // Copy the filtered image back into the image object
    memcpy(image->GetWritePtr(PLANAR_Y), dst.data, image->GetPitch(PLANAR_Y) * image->_height);

если его закомментить то кадр не будет обрабатываться, но вся кухня будет работать. если получится файл спасти, значит все правильно и дело просто в работе с кадром фильтра. может там сложная математика и потому долго.

alysnix ★★★
()
Ответ на: комментарий от alysnix

Нашел причину крэша. В деструкторе не надо удалять виджеты.

BilateralFilter::~BilateralFilter() {
    delete dialog;

    dialog = NULL;
    dEdit = NULL;
    sigmaColorEdit = NULL;
    sigmaSpaceEdit = NULL;
}

Еще закомментил

    cv::bilateralFilter(src, dst, _param->d, _param->sigmaColor, _param->sigmaSpace);
    memcpy(image->GetWritePtr(PLANAR_Y), dst.data, image->GetPitch(PLANAR_Y) * image->_height);
и программа стала сохранять файл за конечное время, просто без редактирования. Стало быть в этих строчках где-то зацикливание при обработке одного и того же кадра.

Ну и опытным путем выяснил, что в configure если юзер отменил диалог надо возвращать false.

Но как бы сама интеграция с видеоредактором получилась, теперь осталось отладить getNextFrame, т.е. собственно обработку изображения, но это я уже другую тему создам, если надо будет.

damix9 ★★★
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.