Ring Daemon
Loading...
Searching...
No Matches
media_stream.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#include "libav_deps.h"
20#include "logger.h"
21#include "rational.h"
22#include "audio/audio_format.h"
23
24#include <string>
25
26namespace jami {
27
29{
30 std::string name {};
31 int format {-1};
32 bool isVideo {false};
35 int width {0};
36 int height {0};
37 int bitrate {0};
39 int sampleRate {0};
40 int nbChannels {0};
41 int frameSize {0};
42
44
45 MediaStream(const std::string& streamName, int fmt, rational<int> tb, int w, int h, int br, rational<int> fr)
47 , format(fmt)
48 , isVideo(true)
49 , timeBase(tb)
50 , width(w)
51 , height(h)
52 , bitrate(br)
53 , frameRate(fr)
54 {}
55
56 MediaStream(const std::string& streamName, int fmt, rational<int> tb, int sr, int channels, int size)
58 , format(fmt)
59 , isVideo(false)
60 , timeBase(tb)
61 , sampleRate(sr)
62 , nbChannels(channels)
63 , frameSize(size)
64 {}
65
66 MediaStream(const std::string& streamName, AudioFormat fmt)
67 : MediaStream(streamName, fmt, 0)
68 {}
69
72 , format(fmt.sampleFormat)
73 , isVideo(false)
74 , timeBase(1, static_cast<int>(fmt.sample_rate))
76 , sampleRate(static_cast<int>(fmt.sample_rate))
77 , nbChannels(static_cast<int>(fmt.nb_channels))
78 , frameSize(static_cast<int>(fmt.sample_rate) / 50) // standard frame size for our encoder is 20 ms
79 {}
80
81 MediaStream(const std::string& streamName, AVCodecContext* c)
82 : MediaStream(streamName, c, 0)
83 {}
84
88 {
89 if (c) {
90 timeBase = c->time_base;
91 switch (c->codec_type) {
93 format = c->pix_fmt;
94 isVideo = true;
95 width = c->width;
96 height = c->height;
97 bitrate = static_cast<int>(c->bit_rate);
98 frameRate = c->framerate;
99 break;
101 format = c->sample_fmt;
102 isVideo = false;
103 sampleRate = c->sample_rate;
104 nbChannels = c->ch_layout.nb_channels;
105 frameSize = c->frame_size;
106 break;
107 default:
108 break;
109 }
110 } else {
111 JAMI_WARN() << "Attempting to get stream info from null codec context";
112 }
113 }
114
115 MediaStream(const MediaStream& other) = default;
116
117 bool isValid() const
118 {
119 if (format < 0)
120 return false;
121 if (isVideo)
122 return width > 0 && height > 0;
123 else
124 return sampleRate > 0 && nbChannels > 0;
125 }
126
128 {
129 // update all info possible (AVFrame has no fps or bitrate data)
130 format = f->format;
131 if (isVideo) {
132 width = f->width;
133 height = f->height;
134 } else {
135 sampleRate = f->sample_rate;
136 nbChannels = f->ch_layout.nb_channels;
137 timeBase = rational<int>(1, f->sample_rate);
138 if (!frameSize)
139 frameSize = f->nb_samples;
140 }
141 }
142
143 friend bool operator==(const MediaStream& ms1, const MediaStream& ms2)
144 {
145 return ms1.bitrate == ms2.bitrate and ms1.firstTimestamp == ms2.firstTimestamp and ms1.format == ms2.format
146 and ms1.frameRate == ms2.frameRate and ms1.frameSize == ms2.frameSize and ms1.height == ms2.height
147 and ms1.isVideo == ms2.isVideo and ms1.name == ms2.name and ms1.nbChannels == ms2.nbChannels
148 and ms1.sampleRate == ms2.sampleRate and ms1.timeBase == ms2.timeBase and ms1.width == ms2.width;
149 }
150};
151
152inline std::ostream&
153operator<<(std::ostream& os, const MediaStream& ms)
154{
155 if (ms.isVideo) {
156 const auto* formatName = av_get_pix_fmt_name(static_cast<AVPixelFormat>(ms.format));
157 os << (ms.name.empty() ? "(null)" : ms.name) << ": " << (formatName ? formatName : "(unknown format)")
158 << " video, " << ms.width << "x" << ms.height << ", " << ms.frameRate << " fps (" << ms.timeBase << ")";
159 if (ms.bitrate > 0)
160 os << ", " << ms.bitrate << " kb/s";
161 } else {
162 os << (ms.name.empty() ? "(null)" : ms.name) << ": "
163 << av_get_sample_fmt_name(static_cast<AVSampleFormat>(ms.format)) << " audio, " << ms.nbChannels
164 << " channel(s), " << ms.sampleRate << " Hz (" << ms.timeBase << "), " << ms.frameSize
165 << " samples per frame";
166 }
167 if (ms.firstTimestamp > 0)
168 os << ", start: " << ms.firstTimestamp;
169 return os;
170}
171
172}; // namespace jami
Naive implementation of the boost::rational interface, described here: https://www....
Definition rational.h:39
#define JAMI_WARN(...)
Definition logger.h:229
void emitSignal(Args... args)
Definition jami_signal.h:64
static std::ostream & operator<<(std::ostream &os, const Account &acc)
Definition account.h:512
Structure to hold sample rate and channel number associated with audio data.
MediaStream(const std::string &streamName, AudioFormat fmt)
void update(AVFrame *f)
friend bool operator==(const MediaStream &ms1, const MediaStream &ms2)
MediaStream(const std::string &streamName, AVCodecContext *c)
MediaStream(const std::string &streamName, AudioFormat fmt, int64_t startTimestamp)
MediaStream(const MediaStream &other)=default
MediaStream(const std::string &streamName, AVCodecContext *c, int64_t startTimestamp)
bool isValid() const
MediaStream(const std::string &streamName, int fmt, rational< int > tb, int sr, int channels, int size)
rational< int > frameRate
std::string name
MediaStream(const std::string &streamName, int fmt, rational< int > tb, int w, int h, int br, rational< int > fr)
rational< int > timeBase