blob: f06197c77bdc84e0a0939c7bc727e130c0740ebe [file] [log] [blame]
/*
* Copyright (C) 2020 Savoir-faire Linux Inc.
*
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FRAMEFILTER_H
#define FRAMEFILTER_H
#include <map>
#include <string>
#include <vector>
#include "mediaStream.h"
#include <memory>
extern "C" {
struct AVFilterContext;
struct AVFilterGraph;
struct AVFilterInOut;
}
namespace jami {
/**
* @brief Provides access to libavfilter.
*
* Can be used for filters with unlimited number of inputs.
* Multiple outputs are not supported. They add complexity for little gain.
*
* For information on how to write a filter graph description, see:
* https://ffmpeg.org/ffmpeg-filters.html
* http://trac.ffmpeg.org/wiki/FilteringGuide
*
* It is required to name each filter graph input. These names are used to feed the correct input.
* It is the same name that will be passed as second argument to feedInput(AVFrame*, std::string).
*
* Examples:
*
* - "[in1] scale=320:240"
* Scales the input to 320x240.
*
* - "[in1] scale=iw/4:ih/4 [mid]; [in2] [mid] overlay=main_w-overlay_w-10:main_h-overlay_h-10"
* in1 will be scaled to 1/16th its size and placed over in2 in the bottom right corner. When
* feeding frames to the filter, you need to specify whether the frame is destined for in1 or in2.
*/
class FrameFilter
{
public:
FrameFilter();
~FrameFilter();
/**
* @brief Initializes the filter graph with one or more inputs and one output. Returns a
* negative code on error.
*/
int initialize(const std::string& filterDesc, std::vector<MediaStream> msps);
/**
* @brief Returns a MediaStream object describing the input specified by @inputName.
*/
MediaStream getInputParams(const std::string& inputName) const;
/**
* @brief 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() const;
/**
* @brief Give the specified source filter an input frame.
*
* Caller is responsible for freeing the frame.
*
* NOTE Will fail if @inputName is not found in the graph.
*/
int feedInput(AVFrame* frame, const std::string& inputName);
int feedEOF(const std::string& inputName);
/**
* @brief 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();
/**
* @brief Frees resources used by FrameFilter.
*/
void clean();
/**
* @brief Flag to know whether or not the filter graph is initialized.
*/
bool initialized_ {false};
private:
/**
* @brief Initializes output of filter graph.
*/
int initOutputFilter(AVFilterInOut* out);
/**
* @brief Initializes an input of filter graph.
*/
int initInputFilter(AVFilterInOut* in, MediaStream msp);
/**
* @brief Reinitializes the filter graph.
*
* Reinitializes with @inputParams_, which should be updated beforehand.
*/
int reinitialize();
/**
* @brief Convenience method that prints @msg and returns err.
*
* NOTE @msg should not be null.
*/
int fail(std::string msg, int err) const;
/**
* @brief Filter graph pointer.
*/
AVFilterGraph* graph_{};
/**
* @brief Filter graph output.
*
* Corresponds to a buffersink/abuffersink filter.
*/
AVFilterContext* output_{};
/**
* @brief List of filter graph inputs.
*
* Each corresponds to a buffer/abuffer filter.
*/
std::vector<AVFilterContext*> inputs_;
/**
* @brief List of filter graph input parameters.
*
* Same order as @inputs_.
*/
std::vector<MediaStream> inputParams_;
/**
* @brief Filter graph string.
*/
std::string desc_ {};
};
}; // namespace jami
#endif // FRAMEFILTER_H