Ring Daemon
Loading...
Searching...
No Matches
media_encoder.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#ifdef ENABLE_VIDEO
24#include "video/video_base.h"
25#include "video/video_scaler.h"
26#endif
27
28#include "noncopyable.h"
29#include "media_buffer.h"
30#include "media_codec.h"
31#include "media_stream.h"
32
33#include <memory>
34#include <string>
35#include <vector>
36
37extern "C" {
38struct AVCodecContext;
39struct AVFormatContext;
40struct AVDictionary;
41struct AVCodec;
42}
43
44namespace jami {
45
46struct MediaDescription;
47
48#ifdef ENABLE_HWACCEL
49namespace video {
50class HardwareAccel;
51}
52#endif
53
54class MediaEncoderException : public std::runtime_error
55{
56public:
58 : std::runtime_error(msg)
59 {}
60 MediaEncoderException(const std::string& msg)
61 : std::runtime_error(msg)
62 {}
63};
64
66{
67public:
70
71 void openOutput(const std::string& filename, const std::string& format = "");
72 void setMetadata(const std::string& title, const std::string& description);
73 void setOptions(const MediaStream& opts);
74 void setOptions(const MediaDescription& args);
75 int addStream(const SystemCodecInfo& codec);
76 void setIOContext(AVIOContext* ioctx) { ioCtx_ = ioctx; }
77 void resetStreams(int width, int height);
78
79 bool send(AVPacket& packet, int streamIdx = -1);
80
81#ifdef ENABLE_VIDEO
82 int encode(const std::shared_ptr<VideoFrame>& input, bool is_keyframe, int64_t frame_number);
83#endif // ENABLE_VIDEO
84
86
87 // frame should be ready to be sent to the encoder at this point
88 int encode(AVFrame* frame, int streamIdx);
89
90 int flush();
91 std::string print_sdp();
92
93 /* getWidth and getHeight return size of the encoded frame.
94 * Values have meaning only after openLiveOutput call.
95 */
96 int getWidth() const { return videoOpts_.width; };
97 int getHeight() const { return videoOpts_.height; };
98
101
102 const std::string& getAudioCodec() const { return audioCodec_; }
103 const std::string& getVideoCodec() const { return videoCodec_; }
104
107
108#ifdef ENABLE_HWACCEL
109 void enableAccel(bool enableAccel);
110#endif
111
112 static std::string testH265Accel();
113
114 unsigned getStreamCount() const;
115 MediaStream getStream(const std::string& name, int streamIdx = -1) const;
116
118
119private:
121 AVCodecContext* prepareEncoderContext(const AVCodec* outputCodec, bool is_video);
122 void forcePresetX2645(AVCodecContext* encoderCtx);
123 void extractProfileLevelID(const std::string& parameters, AVCodecContext* ctx);
124 int initStream(const std::string& codecName, AVBufferRef* framesCtx = {});
125 int initStream(const SystemCodecInfo& systemCodecInfo, AVBufferRef* framesCtx = {});
126 void openIOContext();
127 void startIO();
128 AVCodecContext* getCurrentVideoAVCtx();
129 AVCodecContext* getCurrentAudioAVCtx();
130 void stopEncoder();
131 AVCodecContext* initCodec(AVMediaType mediaType, AVCodecID avcodecId, uint64_t br);
132 void initH264(AVCodecContext* encoderCtx, uint64_t br);
133 void initH265(AVCodecContext* encoderCtx, uint64_t br);
134 void initVP8(AVCodecContext* encoderCtx, uint64_t br);
135 void initMPEG4(AVCodecContext* encoderCtx, uint64_t br);
136 void initH263(AVCodecContext* encoderCtx, uint64_t br);
137 void initOpus(AVCodecContext* encoderCtx);
138 bool isDynBitrateSupported(AVCodecID codecid);
139 bool isDynPacketLossSupported(AVCodecID codecid);
140 void initAccel(AVCodecContext* encoderCtx, uint64_t br);
141#ifdef ENABLE_VIDEO
142 int getHWFrame(const std::shared_ptr<VideoFrame>& input, std::shared_ptr<VideoFrame>& output);
143 std::shared_ptr<VideoFrame> getUnlinkedHWFrame(const VideoFrame& input);
144 std::shared_ptr<VideoFrame> getHWFrameFromSWFrame(const VideoFrame& input);
145 std::shared_ptr<VideoFrame> getScaledSWFrame(const VideoFrame& input);
146#endif
147
148 std::vector<AVCodecContext*> encoders_;
149 AVFormatContext* outputCtx_ = nullptr;
150 AVIOContext* ioCtx_ = nullptr;
151 int currentStreamIdx_ = -1;
152 unsigned sent_samples = 0;
153 bool initialized_ {false};
154 bool fileIO_ {false};
155 const AVCodec* outputCodec_ = nullptr;
156 std::mutex encMutex_;
157 bool linkableHW_ {false};
159 bool fecEnabled_ {false};
160
161#ifdef ENABLE_VIDEO
162 video::VideoScaler scaler_;
163 std::shared_ptr<VideoFrame> scaledFrame_;
164#endif // ENABLE_VIDEO
165
166 std::vector<uint8_t> scaledFrameBuffer_;
167 int scaledFrameBufferSize_ = 0;
168
169#ifdef ENABLE_HWACCEL
170 bool enableAccel_ {false};
171 std::unique_ptr<video::HardwareAccel> accel_;
172#endif
173
174protected:
179 std::string videoCodec_;
180 std::string audioCodec_;
181};
182
183} // namespace jami
MediaEncoderException(const char *msg)
MediaEncoderException(const std::string &msg)
std::string videoCodec_
unsigned getStreamCount() const
MediaStream audioOpts_
void setInitSeqVal(uint16_t seqVal)
int getWidth() const
int encodeAudio(AudioFrame &frame)
void readConfig(AVCodecContext *encoderCtx)
void resetStreams(int width, int height)
int addStream(const SystemCodecInfo &codec)
const std::string & getAudioCodec() const
static std::string testH265Accel()
MediaStream getStream(const std::string &name, int streamIdx=-1) const
int encode(AVFrame *frame, int streamIdx)
AVDictionary * options_
int setPacketLoss(uint64_t pl)
void setMetadata(const std::string &title, const std::string &description)
int getHeight() const
MediaStream videoOpts_
std::string audioCodec_
const std::string & getVideoCodec() const
void openOutput(const std::string &filename, const std::string &format="")
std::string print_sdp()
void setIOContext(AVIOContext *ioctx)
int setBitrate(uint64_t br)
void setOptions(const MediaStream &opts)
bool send(AVPacket &packet, int streamIdx=-1)
void emitSignal(Args... args)
Definition jami_signal.h:64
libjami::VideoFrame VideoFrame
Definition video_base.h:49
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30
MediaDescription Negotiated RTP media slot.