UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
h264_sdp.cpp
Go to the documentation of this file.
1
8/*
9 * Copyright (c) 2013-2014 Fundació i2CAT, Internet I Innovació Digital a Catalunya
10 * Copyright (c) 2013-2024 CESNET
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, is permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * 3. Neither the name of CESNET nor the names of its contributors may be
25 * used to endorse or promote products derived from this software without
26 * specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
30 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
38 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
39 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
43
44#include <cstdint> // for uint32_t
45#include <cstdlib> // for abort
46#include <cstring> // for strncpy
47#include <exception> // for exception
48#include <iostream>
49
50#include "audio/audio.h"
51#include "audio/types.h" // for audio_desc
52#include "debug.h"
53#include "host.h"
54#include "lib_common.h"
55#include "messaging.h" // for msg_change_compress_data, free_response
56#include "module.h"
57#include "rtp/rtp.h"
58#include "transmit.h"
59#include "tv.h"
60#include "ug_runtime_error.hpp"
61#include "utils/sdp.h"
62#include "video_codec.h" // for is_codec_opaque
63#include "video_rxtx.hpp"
64
65#define DEFAULT_SDP_COMPRESSION "lavc:codec=MJPEG:safe"
66#define MOD_NAME "[vrxtx/sdp] "
67
68using std::cout;
69using std::exception;
70using std::shared_ptr;
71using std::string;
72
73h264_sdp_video_rxtx::h264_sdp_video_rxtx(std::map<std::string, param_u> const &params)
75{
76 auto opts = params.at("opts").str;
77 LOG(LOG_LEVEL_WARNING) << "Warning: SDP support is experimental only. Things may be broken - feel free to report them but the support may be limited.\n";
79 m_saved_tx_port = params.at("tx_port").i;
80 if (int ret = sdp_set_options(opts)) {
81 throw ret == 1 ? 0 : 1;
82 }
83}
84
85void h264_sdp_video_rxtx::change_address_callback(void *udata, const char *address)
86{
87 auto *s = static_cast<h264_sdp_video_rxtx *>(udata);
88 if (s->m_saved_addr == address) {
89 return;
90 }
91 s->m_saved_addr = address;
92
93 constexpr enum module_class path_sender[] = { MODULE_CLASS_SENDER,
96 path_sender, address);
97}
98
100{
101 const int rc = ::sdp_add_video(
104 if (rc == -2) {
105 throw ug_runtime_error("[SDP] Unsupported video codec for SDP (allowed H.264 and JPEG)!\n");
106 }
107 if (rc != 0) {
108 abort();
109 }
110}
111
118void
119h264_sdp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame) noexcept
120{
121 if (!is_codec_opaque(tx_frame->color_spec)) {
122 if (m_sent_compress_change) {
123 return;
124 }
125 auto msg = (struct msg_change_compress_data *)
127 msg->what = CHANGE_COMPRESS;
128 strncpy(msg->config_string, DEFAULT_SDP_COMPRESSION, sizeof(msg->config_string) - 1);
129
130 const char *path = "sender.compress";
131 auto *resp = send_message(get_root_module(m_common.parent), path,
132 (struct message *) msg);
133 free_response(resp);
134 m_sent_compress_change = true;
135 return;
136 }
137 if (m_sdp_configured_codec == VIDEO_CODEC_NONE) {
138 try {
139 sdp_add_video(tx_frame->color_spec);
140 m_sdp_configured_codec = tx_frame->color_spec;
141 } catch (exception const &e) {
142 LOG(LOG_LEVEL_ERROR) << e.what();
143 exit_uv(1);
144 return;
145 }
146 }
147
148 if (m_sdp_configured_codec != tx_frame->color_spec) {
149 LOG(LOG_LEVEL_ERROR) << "[SDP] Video codec reconfiguration is not supported!\n";
150 return;
151 }
152
153 if (m_sdp_configured_codec == H264) {
154 tx_send_h264(m_tx, tx_frame.get(), m_network_device);
155 } else {
156 tx_send_jpeg(m_tx, tx_frame.get(), m_network_device);
157 }
158 if ((m_rxtx_mode & MODE_RECEIVER) ==
159 0) { // send RTCP (receiver thread would otherwise do this)
161 time_ns_t curr_time = get_time_in_ns();
162 rtp_update(m_network_device, curr_time);
163 rtp_send_ctrl(m_network_device, ts, nullptr, curr_time);
164
165 // receive RTCP
166 struct timeval timeout;
167 timeout.tv_sec = 0;
168 timeout.tv_usec = 0;
169 rtp_recv_r(m_network_device, &timeout, ts);
170 }
171}
172
173static void
174sdp_change_address_callback(void *udata, const char *address)
175{
176 const enum module_class path_sender[] = { MODULE_CLASS_AUDIO,
179 sdp_send_change_address_message((module *) udata, path_sender, address);
180}
181
182void
184 int /* audio_rx_port */, int audio_tx_port, bool ipv6)
185{
186 if (sdp_add_audio(ipv6, audio_tx_port,
187 desc->sample_rate,
188 desc->ch_count, desc->codec,
191 MSG(ERROR, "Cannot add audio to SDP!\n");
192 }
193}
194
195static video_rxtx *create_video_rxtx_h264_sdp(std::map<std::string, param_u> const &params)
196{
197 return new h264_sdp_video_rxtx(params);
198}
199
201 "RTP standard (SDP version)",
203};
204
206
struct video_desc desc
This file contains definition of some common audio types.
void sdp_send_change_address_message(struct module *root, const enum module_class *path, const char *address)
Definition audio.cpp:238
virtual void send_frame(std::shared_ptr< video_frame >) noexcept override
Definition h264_sdp.cpp:119
void sdp_add_video(codec_t codec)
Definition h264_sdp.cpp:99
h264_sdp_video_rxtx(std::map< std::string, param_u > const &)
Definition h264_sdp.cpp:73
std::string m_saved_addr
for dynamic address reconfiguration,
Definition h264_sdp.hpp:70
void set_audio_spec(const struct audio_desc *desc, int audio_rx_port, int audio_tx_port, bool ipv6) override
Definition h264_sdp.cpp:183
static void change_address_callback(void *udata, const char *address)
Definition h264_sdp.cpp:85
struct rtp * m_network_device
Definition rtp.hpp:71
std::string m_requested_receiver
Definition rtp.hpp:75
static void new_message(struct module *m)
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
module_class
Definition module.h:81
struct module * get_root_module(struct module *node)
Definition module.c:203
@ MODULE_CLASS_NONE
Definition module.h:82
@ MODULE_CLASS_AUDIO
Definition module.h:90
@ MODULE_CLASS_SENDER
Definition module.h:87
static const struct video_rxtx_info h264_sdp_video_rxtx_info
Definition h264_sdp.cpp:200
static void sdp_change_address_callback(void *udata, const char *address)
Definition h264_sdp.cpp:174
#define DEFAULT_SDP_COMPRESSION
Definition h264_sdp.cpp:65
static video_rxtx * create_video_rxtx_h264_sdp(std::map< std::string, param_u > const &params)
Definition h264_sdp.cpp:195
void exit_uv(int status)
Definition host.cpp:625
#define MODE_RECEIVER
Definition host.h:103
@ LIBRARY_CLASS_VIDEO_RXTX
Definition lib_common.h:84
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
struct response * send_message(struct module *root, const char *const_path, struct message *msg)
Sends message without waiting for response.
void free_response(struct response *r)
@ CHANGE_COMPRESS
Definition messaging.h:129
void rtp_update(struct rtp *session, time_ns_t curr_time)
Definition rtp.c:3456
void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback, time_ns_t curr_time)
Definition rtp.c:3409
bool rtp_recv_r(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
Receive RTP packets and dispatch them.
Definition rtp.c:2338
bool rtp_is_ipv6(struct rtp *session)
Definition rtp.c:4022
int sdp_add_audio(bool ipv6, int port, int sample_rate, int channels, audio_codec_t codec, address_callback_t addr_callback, void *addr_callback_udata)
Definition sdp.c:277
int sdp_set_options(const char *opts)
Definition sdp.c:585
int sdp_add_video(bool ipv6, int port, codec_t codec, address_callback_t addr_callback, void *addr_callback_udata)
Definition sdp.c:335
struct module * parent
Definition host.h:171
Definition sdp.c:108
struct common_opts m_common
uint32_t ts
Definition tfrc.c:101
void tx_send_jpeg(struct tx *tx, struct video_frame *frame, struct rtp *rtp_session)
void tx_send_h264(struct tx *tx, struct video_frame *frame, struct rtp *rtp_session)
uint32_t get_std_video_local_mediatime(void)
Definition tv.c:204
long long time_ns_t
Definition tv.h:81
static time_ns_t get_time_in_ns()
Definition tv.h:101
codec_t
Definition types.h:65
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ H264
H.264 frame.
Definition types.h:83
bool is_codec_opaque(codec_t codec)
#define VIDEO_RXTX_ABI_VERSION