Ring Daemon 16.0.0
Loading...
Searching...
No Matches
media_stream.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#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,
46 int fmt,
48 int w,
49 int h,
50 int br,
53 , format(fmt)
54 , isVideo(true)
55 , timeBase(tb)
56 , width(w)
57 , height(h)
58 , bitrate(br)
59 , frameRate(fr)
60 {}
61
63 const std::string& streamName, int fmt, rational<int> tb, int sr, int channels, int size)
65 , format(fmt)
66 , isVideo(false)
67 , timeBase(tb)
68 , sampleRate(sr)
69 , nbChannels(channels)
70 , frameSize(size)
71 {}
72
73 MediaStream(const std::string& streamName, AudioFormat fmt)
74 : MediaStream(streamName, fmt, 0)
75 {}
76
79 , format(fmt.sampleFormat)
80 , isVideo(false)
81 , timeBase(1, fmt.sample_rate)
83 , sampleRate(fmt.sample_rate)
84 , nbChannels(fmt.nb_channels)
85 , frameSize(fmt.sample_rate / 50) // standard frame size for our encoder is 20 ms
86 {}
87
88 MediaStream(const std::string& streamName, AVCodecContext* c)
89 : MediaStream(streamName, c, 0)
90 {}
91
95 {
96 if (c) {
97 timeBase = c->time_base;
98 switch (c->codec_type) {
100 format = c->pix_fmt;
101 isVideo = true;
102 width = c->width;
103 height = c->height;
104 bitrate = c->bit_rate;
105 frameRate = c->framerate;
106 break;
108 format = c->sample_fmt;
109 isVideo = false;
110 sampleRate = c->sample_rate;
111 nbChannels = c->ch_layout.nb_channels;
112 frameSize = c->frame_size;
113 break;
114 default:
115 break;
116 }
117 } else {
118 JAMI_WARN() << "Attempting to get stream info from null codec context";
119 }
120 }
121
122 MediaStream(const MediaStream& other) = default;
123
124 bool isValid() const
125 {
126 if (format < 0)
127 return false;
128 if (isVideo)
129 return width > 0 && height > 0;
130 else
131 return sampleRate > 0 && nbChannels > 0;
132 }
133
135 {
136 // update all info possible (AVFrame has no fps or bitrate data)
137 format = f->format;
138 if (isVideo) {
139 width = f->width;
140 height = f->height;
141 } else {
142 sampleRate = f->sample_rate;
143 nbChannels = f->ch_layout.nb_channels;
144 timeBase = rational<int>(1, f->sample_rate);
145 if (!frameSize)
146 frameSize = f->nb_samples;
147 }
148 }
149
150 friend bool operator==(const MediaStream& ms1, const MediaStream& ms2)
151 {
152 return ms1.bitrate == ms2.bitrate and ms1.firstTimestamp == ms2.firstTimestamp
153 and ms1.format == ms2.format and ms1.frameRate == ms2.frameRate
154 and ms1.frameSize == ms2.frameSize and ms1.height == ms2.height
155 and ms1.isVideo == ms2.isVideo and ms1.name == ms2.name
156 and ms1.nbChannels == ms2.nbChannels and ms1.sampleRate == ms2.sampleRate
157 and ms1.timeBase == ms2.timeBase and ms1.width == ms2.width;
158 }
159};
160
161inline std::ostream&
162operator<<(std::ostream& os, const MediaStream& ms)
163{
164 if (ms.isVideo) {
165 auto formatName = av_get_pix_fmt_name(static_cast<AVPixelFormat>(ms.format));
166 os << (ms.name.empty() ? "(null)" : ms.name) << ": "
167 << (formatName ? formatName : "(unknown format)") << " video, " << ms.width << "x"
168 << ms.height << ", " << ms.frameRate << " fps (" << ms.timeBase << ")";
169 if (ms.bitrate > 0)
170 os << ", " << ms.bitrate << " kb/s";
171 } else {
172 os << (ms.name.empty() ? "(null)" : ms.name) << ": "
173 << av_get_sample_fmt_name(static_cast<AVSampleFormat>(ms.format)) << " audio, "
174 << ms.nbChannels << " channel(s), " << ms.sampleRate << " Hz (" << ms.timeBase << "), "
175 << ms.frameSize << " samples per frame";
176 }
177 if (ms.firstTimestamp > 0)
178 os << ", start: " << ms.firstTimestamp;
179 return os;
180}
181
182}; // namespace jami
Naive implementation of the boost::rational interface, described here: http://www....
Definition rational.h:38
#define JAMI_WARN(...)
Definition logger.h:217
void emitSignal(Args... args)
Definition ring_signal.h:64
static std::ostream & operator<<(std::ostream &os, const Account &acc)
Definition account.h:530
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