UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
h264_rtp.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, z. s. p. o.
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
42#include <cctype>
43#include <cstdint> // for uint32_t
44#include <cstdio> // for printf
45#include <cstdlib>
46#include <cstring>
47#include <memory>
48
49#include "compat/strings.h" // strdupa
50#include "debug.h"
51#include "host.h"
52#include "lib_common.h"
53#include "rtp/rtp.h"
54#include "rtsp/rtsp_utils.h" // for rtsp_types_t
55#include "transmit.h"
56#include "tv.h"
57#include "types.h" // for video_frame, H264, JPEG, MJPG
58#include "utils/color_out.h"
59#include "utils/sdp.h" // for sdp_print_supported_codecs
60#include "video_codec.h" // for get_codec_name
61#include "video_rxtx.hpp"
63
64#define MOD_NAME "[vrxtx/h264_rtp] "
65
66using std::shared_ptr;
67
68h264_rtp_video_rxtx::h264_rtp_video_rxtx(std::map<std::string, param_u> const &params,
69 int rtsp_port) :
71{
72 rtsp_params.rtsp_port = (unsigned) rtsp_port;
73 rtsp_params.parent = m_common.parent;;
74 rtsp_params.avType = static_cast<rtsp_types_t>(params.at("avType").l);
75 rtsp_params.rtp_port_video = params.at("rx_port").i; //server rtp port
76}
77
84void
86{
87 assert((rtsp_params.avType & rtsp_type_video) != 0);
88 if (rtsp_params.video_codec == H264) {
90 } else if (rtsp_params.video_codec == JPEG ||
91 rtsp_params.video_codec == MJPG) {
93 } else {
94 MSG(ERROR,
95 "codecs other than H.264 and JPEG currently not "
96 "supported, got %s\n",
97 get_codec_name(rtsp_params.video_codec));
98 return;
99 }
100
101 if ((rtsp_params.avType & rtsp_type_audio) != 0) {
102 if (!audio_params_set) {
103 MSG(INFO, "Waiting for audio specs...\n");
104 return;
105 }
106 }
108}
109
110void
111h264_rtp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame) noexcept
112{
113 if (m_rtsp_server == nullptr) {
114 rtsp_params.video_codec = tx_frame->color_spec;
115 configure_rtsp_server_video();
116 }
117 if (m_rtsp_server == nullptr) {
118 return;
119 }
120
121 tx_send_std(m_tx, tx_frame.get(), m_network_device);
122
123 if ((m_rxtx_mode & MODE_RECEIVER) == 0) { // send RTCP (receiver thread would otherwise do this
124 time_ns_t curr_time = get_time_in_ns();
125 uint32_t ts = (curr_time - m_common.start_time) / 100'000 * 9; // at 90000 Hz
126 rtp_update(m_network_device, curr_time);
127 rtp_send_ctrl(m_network_device, ts, nullptr, curr_time);
128
129 // receive RTCP
130 struct timeval timeout;
131 timeout.tv_sec = 0;
132 timeout.tv_usec = 0;
133 rtp_recv_r(m_network_device, &timeout, ts);
134 }
135}
136
141
147
148void
150 int audio_rx_port, int /* audio_tx_port */,
151 bool /* ipv6 */)
152{
153 rtsp_params.adesc = *desc;
154 rtsp_params.rtp_port_audio = audio_rx_port;
155 audio_params_set = true;
156
157 if ((rtsp_params.avType & rtsp_type_video) == 0U) {
159 }
160}
161
162static void rtps_server_usage(){
163 printf("\n[RTSP SERVER] usage:\n");
164 color_printf("\t" TBOLD("-x rtsp[:port=number]") "\n");
165 printf("\t\tdefault rtsp server port number: 8554\n\n");
166
168}
169
170static int get_rtsp_server_port(const char *config) {
171 if (strncmp(config, "port:", 5) != 0 &&
172 strncmp(config, "port=", 5) != 0) {
173 log_msg(LOG_LEVEL_ERROR, "\n[RTSP SERVER] ERROR - please, check usage.\n");
175 return -1;
176 }
177 if (strlen(config) == 5) {
178 log_msg(LOG_LEVEL_ERROR, "\n[RTSP SERVER] ERROR - please, enter a port number.\n");
180 return -1;
181 }
182 if (config[4] == ':') {
183 MSG(WARNING, "deprecated usage - use port=number, not port:number!\n");
184 }
185 int port = atoi(config + 5);
186 if (port < 0 || port > 65535 || !isdigit(config[5])) {
187 log_msg(LOG_LEVEL_ERROR, "\n[RTSP SERVER] ERROR - please, enter a valid port number.\n");
189 return -1;
190 }
191 return port;
192}
193
194static video_rxtx *create_video_rxtx_h264_std(std::map<std::string, param_u> const &params)
195{
196 int rtsp_port;
197 const char *rtsp_port_str = static_cast<const char *>(params.at("opts").ptr);
198 if (strlen(rtsp_port_str) == 0) {
199 rtsp_port = 0;
200 } else {
201 if (strcmp(rtsp_port_str, "help") == 0) {
203 return nullptr;
204 }
205 rtsp_port = get_rtsp_server_port(rtsp_port_str);
206 if (rtsp_port == -1) {
207 return nullptr;
208 }
209 }
210 return new h264_rtp_video_rxtx(params, rtsp_port);
211}
212
214 "RTP standard (using RTSP)",
216};
217
219
struct video_desc desc
const char * get_codec_name(codec_t codec)
void c_stop_server(rtsp_serv_t *server)
rtsp_serv_t * c_start_server(struct rtsp_server_parameters params)
void set_audio_spec(const struct audio_desc *desc, int audio_rx_port, int audio_tx_port, bool ipv6) override
Definition h264_rtp.cpp:149
void(* tx_send_std)(struct tx *tx_session, struct video_frame *frame, struct rtp *rtp_session)
Definition h264_rtp.hpp:73
virtual ~h264_rtp_video_rxtx()
Definition h264_rtp.cpp:137
h264_rtp_video_rxtx(std::map< std::string, param_u > const &, int)
Definition h264_rtp.cpp:68
virtual void send_frame(std::shared_ptr< video_frame >) noexcept override
Definition h264_rtp.cpp:111
std::atomic< bool > audio_params_set
Definition h264_rtp.hpp:71
rtsp_serv_t * m_rtsp_server
Definition h264_rtp.hpp:72
void configure_rtsp_server_video()
Definition h264_rtp.cpp:85
void join() override
Definition h264_rtp.cpp:142
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
static int get_rtsp_server_port(const char *config)
Definition h264_rtp.cpp:170
static void rtps_server_usage()
Definition h264_rtp.cpp:162
static const struct video_rxtx_info h264_video_rxtx_info
Definition h264_rtp.cpp:213
static video_rxtx * create_video_rxtx_h264_std(std::map< std::string, param_u > const &params)
Definition h264_rtp.cpp:194
#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
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
rtsp_types_t
Definition rtsp_utils.h:4
@ rtsp_type_video
Definition rtsp_utils.h:7
@ rtsp_type_audio
Definition rtsp_utils.h:6
void sdp_print_supported_codecs(void)
Definition sdp.c:652
struct module * parent
Definition host.h:171
virtual void join()
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)
long long time_ns_t
Definition tv.h:81
static time_ns_t get_time_in_ns()
Definition tv.h:101
@ JPEG
JPEG image, restart intervals may be used. Compatible with GPUJPEG.
Definition types.h:81
@ MJPG
JPEG image, without restart intervals.
Definition types.h:85
@ H264
H.264 frame.
Definition types.h:83
#define VIDEO_RXTX_ABI_VERSION