Commit 454cb171 authored by Philippe Gorley's avatar Philippe Gorley Committed by Sébastien Blin

filter: get output stream properties

Change-Id: I6f1ebfc9d967452fe7d7c7e72e32cf795ae2d85a
Reviewed-by: Sébastien Blin's avatarSebastien Blin <sebastien.blin@savoirfairelinux.com>
parent 6fdf09ce
......@@ -121,6 +121,41 @@ MediaFilter::initialize(const std::string& filterDesc, std::vector<MediaStream>
return 0;
}
MediaStream
MediaFilter::getOutputParams()
{
MediaStream output;
if (!output_ || !initialized_) {
fail("Filter not initialized", -1);
return output;
}
switch (av_buffersink_get_type(output_)) {
case AVMEDIA_TYPE_VIDEO:
output.name = "videoOutput";
output.format = av_buffersink_get_format(output_);
output.isVideo = true;
output.timeBase = av_buffersink_get_time_base(output_);
output.width = av_buffersink_get_w(output_);
output.height = av_buffersink_get_h(output_);
output.aspectRatio = av_buffersink_get_sample_aspect_ratio(output_);
output.frameRate = av_buffersink_get_frame_rate(output_);
break;
case AVMEDIA_TYPE_AUDIO:
output.name = "audioOutput";
output.format = av_buffersink_get_format(output_);
output.isVideo = false;
output.timeBase = av_buffersink_get_time_base(output_);
output.sampleRate = av_buffersink_get_sample_rate(output_);
output.nbChannels = av_buffersink_get_channels(output_);
break;
default:
output.format = -1;
break;
}
return output;
}
int
MediaFilter::feedInput(AVFrame* frame)
{
......
......@@ -78,6 +78,13 @@ class MediaFilter {
*/
int initialize(const std::string& filterDesc, std::vector<MediaStream> msps);
/**
* 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).
*/
MediaStream getOutputParams();
/**
* Give the filter graph an input frame. Caller is responsible for freeing the frame.
*
......@@ -97,8 +104,10 @@ class MediaFilter {
* Pull a frame from the filter graph. Caller owns the frame reference.
*
* Returns AVERROR(EAGAIN) if filter graph requires more input.
*
* NOTE Frame reference belongs to the caller
*/
AVFrame* readOutput(); // frame reference belongs to caller
AVFrame* readOutput();
private:
NON_COPYABLE(MediaFilter);
......
......@@ -41,11 +41,15 @@ private:
void testSimpleVideoFilter();
void testSimpleAudioFilter();
void testComplexVideoFilter();
void testSimpleFilterParams();
void testComplexFilterParams();
CPPUNIT_TEST_SUITE(MediaFilterTest);
CPPUNIT_TEST(testSimpleVideoFilter);
CPPUNIT_TEST(testSimpleAudioFilter);
CPPUNIT_TEST(testComplexVideoFilter);
CPPUNIT_TEST(testSimpleFilterParams);
CPPUNIT_TEST(testComplexFilterParams);
CPPUNIT_TEST_SUITE_END();
std::unique_ptr<MediaFilter> filter_;
......@@ -235,6 +239,64 @@ MediaFilterTest::testComplexVideoFilter()
CPPUNIT_ASSERT(frame_->width == width1 && frame_->height == height1);
}
void
MediaFilterTest::testSimpleFilterParams()
{
std::string filterSpec = "scale=200x100";
// constants
const constexpr int width = 320;
const constexpr int height = 240;
const constexpr AVPixelFormat format = AV_PIX_FMT_YUV420P;
// construct the filter parameters
rational<int> one = rational<int>(1);
auto params = MediaStream("vf", format, one, width, height, one, one);
// returned params should be invalid
CPPUNIT_ASSERT(filter_->getOutputParams().format < 0);
// prepare filter
CPPUNIT_ASSERT(filter_->initialize(filterSpec, params) >= 0);
// output params should now be valid
auto ms = filter_->getOutputParams();
CPPUNIT_ASSERT(ms.format >= 0 && ms.width > 0 && ms.height > 0);
}
void
MediaFilterTest::testComplexFilterParams()
{
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
const constexpr int width1 = 320;
const constexpr int height1 = 240;
const constexpr int width2 = 30;
const constexpr int height2 = 30;
const constexpr AVPixelFormat format = AV_PIX_FMT_YUV420P;
// construct the filter parameters
rational<int> one = rational<int>(1);
auto params1 = MediaStream("main", format, one, width1, height1, one, one);
auto params2 = MediaStream("top", format, one, width2, height2, one, one);
// returned params should be invalid
CPPUNIT_ASSERT(filter_->getOutputParams().format < 0);
// prepare filter
auto vec = std::vector<MediaStream>();
vec.push_back(params2); // order does not matter, as long as names match
vec.push_back(params1);
CPPUNIT_ASSERT(filter_->initialize(filterSpec, vec) >= 0);
// output params should now be valid
auto ms = filter_->getOutputParams();
CPPUNIT_ASSERT(ms.format >= 0 && ms.width == width1 && ms.height == height1);
}
}} // namespace ring::test
RING_TEST_RUNNER(ring::test::MediaFilterTest::name());
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