Commit 60305d92 authored by Philippe Gorley's avatar Philippe Gorley

filter: simplify usage and get input params

Adds a way to get input parameters.
Simplifies usage of simple filters.
Adds const where useful.

Change-Id: I768d2f3e4e46e791e10530a1c3010607fecc42da
parent d7fee9ca
...@@ -125,7 +125,22 @@ MediaFilter::initialize(const std::string& filterDesc, std::vector<MediaStream> ...@@ -125,7 +125,22 @@ MediaFilter::initialize(const std::string& filterDesc, std::vector<MediaStream>
} }
MediaStream MediaStream
MediaFilter::getOutputParams() MediaFilter::getInputParams() const
{
return getInputParams("default");
}
MediaStream
MediaFilter::getInputParams(const std::string& inputName) const
{
for (auto ms : inputParams_)
if (ms.name == inputName)
return ms;
return {};
}
MediaStream
MediaFilter::getOutputParams() const
{ {
MediaStream output; MediaStream output;
if (!output_ || !initialized_) { if (!output_ || !initialized_) {
...@@ -174,7 +189,7 @@ MediaFilter::feedInput(AVFrame* frame, std::string inputName) ...@@ -174,7 +189,7 @@ MediaFilter::feedInput(AVFrame* frame, std::string inputName)
for (size_t i = 0; i < inputs_.size(); ++i) { for (size_t i = 0; i < inputs_.size(); ++i) {
auto filterCtx = inputs_[i]; auto filterCtx = inputs_[i];
if (inputNames_[i] != inputName) if (inputParams_[i].name != inputName)
continue; continue;
int flags = AV_BUFFERSRC_FLAG_PUSH | AV_BUFFERSRC_FLAG_KEEP_REF; int flags = AV_BUFFERSRC_FLAG_PUSH | AV_BUFFERSRC_FLAG_KEEP_REF;
...@@ -213,6 +228,19 @@ MediaFilter::readOutput() ...@@ -213,6 +228,19 @@ MediaFilter::readOutput()
return nullptr; return nullptr;
} }
AVFrame*
MediaFilter::apply(AVFrame* frame)
{
if (inputs_.size() != 1) {
RING_ERR() << "Cannot use apply(AVFrame*) shortcut with a complex filter";
return nullptr;
}
if (feedInput(frame) < 0)
return nullptr;
return readOutput();
}
int int
MediaFilter::initOutputFilter(AVFilterInOut* out) MediaFilter::initOutputFilter(AVFilterInOut* out)
{ {
...@@ -291,14 +319,15 @@ MediaFilter::initInputFilter(AVFilterInOut* in, MediaStream msp, bool simple) ...@@ -291,14 +319,15 @@ MediaFilter::initInputFilter(AVFilterInOut* in, MediaStream msp, bool simple)
inputs_.push_back(buffersrcCtx); inputs_.push_back(buffersrcCtx);
if (simple) if (simple)
inputNames_.push_back("default"); msp.name = "default";
else else
inputNames_.push_back(in->name); msp.name = in->name;
inputParams_.push_back(msp);
return ret; return ret;
} }
int int
MediaFilter::fail(std::string msg, int err) MediaFilter::fail(std::string msg, int err) const
{ {
if (!msg.empty()) if (!msg.empty())
RING_ERR() << msg << ": " << libav_utils::getError(err); RING_ERR() << msg << ": " << libav_utils::getError(err);
......
...@@ -78,12 +78,24 @@ class MediaFilter { ...@@ -78,12 +78,24 @@ class MediaFilter {
*/ */
int initialize(const std::string& filterDesc, std::vector<MediaStream> msps); int initialize(const std::string& filterDesc, std::vector<MediaStream> msps);
/**
* Returns a MediaStream object describing the input.
*
* NOTE This is a shortcut for simple filters and will fail when called on a complex filter.
*/
MediaStream getInputParams() const;
/**
* Returns a MediaStream object describing the input specified by @inputName.
*/
MediaStream getInputParams(const std::string& inputName) const;
/** /**
* Returns a MediaStream struct describing the frames that will be output. * Returns a MediaStream struct describing the frames that will be output.
* *
* When called in an invalid state, the returned format will be invalid (less than 0). * When called in an invalid state, the returned format will be invalid (less than 0).
*/ */
MediaStream getOutputParams(); MediaStream getOutputParams() const;
/** /**
* Give the filter graph an input frame. Caller is responsible for freeing the frame. * Give the filter graph an input frame. Caller is responsible for freeing the frame.
...@@ -109,6 +121,16 @@ class MediaFilter { ...@@ -109,6 +121,16 @@ class MediaFilter {
*/ */
AVFrame* readOutput(); AVFrame* readOutput();
/**
* Passes a frame through a simple filter (1 input, 1 output).
*
* This is a shortcut for feedInput(AVFrame*)+readOutput().
*
* NOTE Returns nullptr if the filter graph has multiple inputs/outputs.
* NOTE Caller is responsible for freeing the input and output frames.
*/
AVFrame* apply(AVFrame* frame);
private: private:
NON_COPYABLE(MediaFilter); NON_COPYABLE(MediaFilter);
...@@ -127,7 +149,7 @@ class MediaFilter { ...@@ -127,7 +149,7 @@ class MediaFilter {
* *
* NOTE @msg should not be null. * NOTE @msg should not be null.
*/ */
int fail(std::string msg, int err); int fail(std::string msg, int err) const;
/** /**
* Frees resources used by MediaFilter. * Frees resources used by MediaFilter.
...@@ -150,9 +172,9 @@ class MediaFilter { ...@@ -150,9 +172,9 @@ class MediaFilter {
std::vector<AVFilterContext*> inputs_; std::vector<AVFilterContext*> inputs_;
/** /**
* List of filter graph input names. Same order as @inputs_. * List of filter graph input parameters. Same order as @inputs_.
*/ */
std::vector<std::string> inputNames_; std::vector<MediaStream> inputParams_;
/** /**
* Filter graph string. * Filter graph string.
......
...@@ -140,8 +140,7 @@ MediaFilterTest::testSimpleVideoFilter() ...@@ -140,8 +140,7 @@ MediaFilterTest::testSimpleVideoFilter()
CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0); CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0);
// apply filter // apply filter
CPPUNIT_ASSERT(filter_->feedInput(frame_) >= 0); frame_ = filter_->apply(frame_);
frame_ = filter_->readOutput();
CPPUNIT_ASSERT(frame_); CPPUNIT_ASSERT(frame_);
// check if the filter worked // check if the filter worked
...@@ -178,8 +177,7 @@ MediaFilterTest::testSimpleAudioFilter() ...@@ -178,8 +177,7 @@ MediaFilterTest::testSimpleAudioFilter()
CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0); CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0);
// apply filter // apply filter
CPPUNIT_ASSERT(filter_->feedInput(frame_) >= 0); frame_ = filter_->apply(frame_);
frame_ = filter_->readOutput();
CPPUNIT_ASSERT(frame_); CPPUNIT_ASSERT(frame_);
// check if the filter worked // check if the filter worked
...@@ -259,17 +257,19 @@ MediaFilterTest::testSimpleFilterParams() ...@@ -259,17 +257,19 @@ MediaFilterTest::testSimpleFilterParams()
// prepare filter // prepare filter
CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0); CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0);
// check input params
auto msin = filter_->getInputParams();
CPPUNIT_ASSERT(msin.format == format && msin.width == width && msin.height == height);
// output params should now be valid // output params should now be valid
auto ms = filter_->getOutputParams(); auto msout = filter_->getOutputParams();
CPPUNIT_ASSERT(ms.format >= 0 && ms.width > 0 && ms.height > 0); CPPUNIT_ASSERT(msout.format >= 0 && msout.width > 0 && msout.height > 0);
} }
void void
MediaFilterTest::testComplexFilterParams() MediaFilterTest::testComplexFilterParams()
{ {
std::string filterSpec = "[main] [top] overlay=main_w-overlay_w-10:main_h-overlay_h-10"; std::string filterSpec = "[main] [top] overlay=main_w-overlay_w-10:main_h-overlay_h-10";
std::string main = "main";
std::string top = "top";
// constants // constants
const constexpr int width1 = 320; const constexpr int width1 = 320;
...@@ -292,6 +292,12 @@ MediaFilterTest::testComplexFilterParams() ...@@ -292,6 +292,12 @@ MediaFilterTest::testComplexFilterParams()
vec.push_back(params1); vec.push_back(params1);
CPPUNIT_ASSERT(filter_->initialize(filterSpec, vec) >= 0); CPPUNIT_ASSERT(filter_->initialize(filterSpec, vec) >= 0);
// check input params
auto main = filter_->getInputParams("main");
CPPUNIT_ASSERT(main.format == format && main.width == width1 && main.height == height1);
auto top = filter_->getInputParams("top");
CPPUNIT_ASSERT(top.format == format && top.width == width2 && top.height == height2);
// output params should now be valid // output params should now be valid
auto ms = filter_->getOutputParams(); auto ms = filter_->getOutputParams();
CPPUNIT_ASSERT(ms.format >= 0 && ms.width == width1 && ms.height == height1); CPPUNIT_ASSERT(ms.format >= 0 && ms.width == width1 && ms.height == height1);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment