| /* |
| * Copyright (C) 2020-2021 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 |