Ring Daemon 16.0.0
Loading...
Searching...
No Matches
media_encoder.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 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 <map>
34#include <memory>
35#include <string>
36#include <vector>
37
38extern "C" {
39struct AVCodecContext;
40struct AVFormatContext;
41struct AVDictionary;
42struct AVCodec;
43}
44
45namespace jami {
46
47struct MediaDescription;
48
49#ifdef RING_ACCEL
50namespace video {
51class HardwareAccel;
52}
53#endif
54
55class MediaEncoderException : public std::runtime_error
56{
57public:
59 : std::runtime_error(msg){}
60 MediaEncoderException(const std::string& msg)
61 : std::runtime_error(msg){}
62};
63
65{
66public:
69
70 void openOutput(const std::string& filename, const std::string& format = "");
71 void setMetadata(const std::string& title, const std::string& description);
72 void setOptions(const MediaStream& opts);
73 void setOptions(const MediaDescription& args);
74 int addStream(const SystemCodecInfo& codec);
75 void setIOContext(AVIOContext* ioctx) { ioCtx_ = ioctx; }
76 void resetStreams(int width, int height);
77
78 bool send(AVPacket& packet, int streamIdx = -1);
79
80#ifdef ENABLE_VIDEO
81 int encode(const std::shared_ptr<VideoFrame>& input, bool is_keyframe, int64_t frame_number);
82#endif // ENABLE_VIDEO
83
85
86 // frame should be ready to be sent to the encoder at this point
87 int encode(AVFrame* frame, int streamIdx);
88
89 int flush();
90 std::string print_sdp();
91
92 /* getWidth and getHeight return size of the encoded frame.
93 * Values have meaning only after openLiveOutput call.
94 */
95 int getWidth() const { return videoOpts_.width; };
96 int getHeight() const { return videoOpts_.height; };
97
100
101 const std::string& getAudioCodec() const { return audioCodec_; }
102 const std::string& getVideoCodec() const { return videoCodec_; }
103
106
107#ifdef RING_ACCEL
108 void enableAccel(bool enableAccel);
109#endif
110
111 static std::string testH265Accel();
112
113 unsigned getStreamCount() const;
114 MediaStream getStream(const std::string& name, int streamIdx = -1) const;
115
116private:
118 AVCodecContext* prepareEncoderContext(const AVCodec* outputCodec, bool is_video);
119 void forcePresetX2645(AVCodecContext* encoderCtx);
120 void extractProfileLevelID(const std::string& parameters, AVCodecContext* ctx);
121 int initStream(const std::string& codecName, AVBufferRef* framesCtx = {});
122 int initStream(const SystemCodecInfo& systemCodecInfo, AVBufferRef* framesCtx = {});
123 void openIOContext();
124 void startIO();
125 AVCodecContext* getCurrentVideoAVCtx();
126 AVCodecContext* getCurrentAudioAVCtx();
127 void stopEncoder();
128 AVCodecContext* initCodec(AVMediaType mediaType, AVCodecID avcodecId, uint64_t br);
129 void initH264(AVCodecContext* encoderCtx, uint64_t br);
130 void initH265(AVCodecContext* encoderCtx, uint64_t br);
131 void initVP8(AVCodecContext* encoderCtx, uint64_t br);
132 void initMPEG4(AVCodecContext* encoderCtx, uint64_t br);
133 void initH263(AVCodecContext* encoderCtx, uint64_t br);
134 void initOpus(AVCodecContext* encoderCtx);
135 bool isDynBitrateSupported(AVCodecID codecid);
136 bool isDynPacketLossSupported(AVCodecID codecid);
137 void initAccel(AVCodecContext* encoderCtx, uint64_t br);
138#ifdef ENABLE_VIDEO
139 int getHWFrame(const std::shared_ptr<VideoFrame>& input, std::shared_ptr<VideoFrame>& output);
140 std::shared_ptr<VideoFrame> getUnlinkedHWFrame(const VideoFrame& input);
141 std::shared_ptr<VideoFrame> getHWFrameFromSWFrame(const VideoFrame& input);
142 std::shared_ptr<VideoFrame> getScaledSWFrame(const VideoFrame& input);
143#endif
144
145 std::vector<AVCodecContext*> encoders_;
146 AVFormatContext* outputCtx_ = nullptr;
147 AVIOContext* ioCtx_ = nullptr;
148 int currentStreamIdx_ = -1;
149 unsigned sent_samples = 0;
150 bool initialized_ {false};
151 bool fileIO_ {false};
152 unsigned int currentVideoCodecID_ {0};
153 const AVCodec* outputCodec_ = nullptr;
154 std::mutex encMutex_;
155 bool linkableHW_ {false};
157 bool fecEnabled_ {false};
158
159#ifdef ENABLE_VIDEO
160 video::VideoScaler scaler_;
161 std::shared_ptr<VideoFrame> scaledFrame_;
162#endif // ENABLE_VIDEO
163
164 std::vector<uint8_t> scaledFrameBuffer_;
165 int scaledFrameBufferSize_ = 0;
166
167#ifdef RING_ACCEL
168 bool enableAccel_ {false};
169 std::unique_ptr<video::HardwareAccel> accel_;
170#endif
171
172protected:
177 std::string videoCodec_;
178 std::string audioCodec_;
179};
180
181} // 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 ring_signal.h:64
libjami::VideoFrame VideoFrame
Definition video_base.h:53
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30
MediaDescription Negotiated RTP media slot.